11package io .substrait .isthmus ;
22
33import com .google .common .annotations .VisibleForTesting ;
4- import io .substrait .isthmus .sql . SubstraitSqlToCalcite ;
4+ import io .substrait .isthmus .expression . DdlRelBuilder ;
55import io .substrait .isthmus .sql .SubstraitSqlValidator ;
66import io .substrait .plan .ImmutablePlan .Builder ;
77import io .substrait .plan .Plan ;
88import io .substrait .plan .Plan .Version ;
99import io .substrait .plan .PlanProtoConverter ;
10+ import java .util .ArrayList ;
1011import java .util .List ;
1112import org .apache .calcite .plan .hep .HepPlanner ;
1213import org .apache .calcite .plan .hep .HepProgram ;
@@ -109,6 +110,49 @@ List<RelRoot> sqlToRelNode(String sql, Prepare.CatalogReader catalogReader)
109110 return roots ;
110111 }
111112
113+ protected void sqlToPlanRoots (
114+ String sql , SqlValidator validator , Prepare .CatalogReader catalogReader , Builder builder )
115+ throws SqlParseException {
116+
117+ SqlParser parser = SqlParser .create (sql , parserConfig );
118+ SqlNodeList parsedList = parser .parseStmtList ();
119+ if (parsedList .isEmpty ()) {
120+ return ;
121+ }
122+
123+ SqlToRelConverter converter = createSqlToRelConverter (validator , catalogReader );
124+ DdlRelBuilder ddlRelBuilder =
125+ new DdlRelBuilder (
126+ converter , SqlToSubstrait ::getBestExpRelRoot , EXTENSION_COLLECTION , featureBoard );
127+
128+ List <SqlNode > nonDdlNodes = new ArrayList <>();
129+
130+ for (SqlNode sqlNode : parsedList ) {
131+ final io .substrait .plan .Plan .Root ddlRoot = sqlNode .accept (ddlRelBuilder );
132+ if (ddlRoot != null ) {
133+ builder .addRoots (ddlRoot );
134+ } else {
135+ nonDdlNodes .add (sqlNode );
136+ }
137+ }
138+
139+ if (!nonDdlNodes .isEmpty ()) {
140+ SqlNodeList dmlNodes = new SqlNodeList (nonDdlNodes , parsedList .getParserPosition ());
141+
142+ List <RelRoot > relRoots = sqlNodesToRelNode (dmlNodes , converter );
143+ relRoots .stream ()
144+ .map (root -> SubstraitRelVisitor .convert (root , EXTENSION_COLLECTION , featureBoard ))
145+ .forEach (builder ::addRoots );
146+ }
147+ }
148+
149+ private List <RelRoot > sqlNodesToRelNode (
150+ final SqlNodeList parsedList , final SqlToRelConverter converter ) {
151+ return parsedList .stream ()
152+ .map (parsed -> getBestExpRelRoot (converter , parsed ))
153+ .collect (java .util .stream .Collectors .toList ());
154+ }
155+
112156 protected SqlToRelConverter createSqlToRelConverter (
113157 SqlValidator validator , Prepare .CatalogReader catalogReader ) {
114158 SqlToRelConverter converter =
@@ -122,7 +166,7 @@ protected SqlToRelConverter createSqlToRelConverter(
122166 return converter ;
123167 }
124168
125- protected RelRoot getBestExpRelRoot (SqlToRelConverter converter , SqlNode parsed ) {
169+ protected static RelRoot getBestExpRelRoot (SqlToRelConverter converter , SqlNode parsed ) {
126170 RelRoot root = converter .convertQuery (parsed , true , true );
127171 {
128172 // RelBuilder seems to implicitly use the rule below,
0 commit comments