30
30
import java .io .Reader ;
31
31
import java .sql .SQLException ;
32
32
import java .util .ArrayList ;
33
- import java .util .Arrays ;
34
33
import java .util .Collection ;
35
- import java .util .Collections ;
36
34
import java .util .List ;
37
- import java .util .Objects ;
38
35
import java .util .Properties ;
39
36
import org .apache .calcite .jdbc .CalcitePrepare ;
40
37
import org .apache .calcite .jdbc .CalciteSchema ;
41
38
import org .apache .calcite .rel .RelRoot ;
42
- import org .apache .calcite .rel .type .RelDataType ;
43
- import org .apache .calcite .rel .type .RelDataTypeFactory ;
44
- import org .apache .calcite .rel .type .RelDataTypeImpl ;
45
- import org .apache .calcite .rel .type .RelDataTypeSystem ;
46
- import org .apache .calcite .rel .type .RelProtoDataType ;
47
39
import org .apache .calcite .schema .Function ;
48
40
import org .apache .calcite .schema .SchemaPlus ;
49
41
import org .apache .calcite .schema .Table ;
50
42
import org .apache .calcite .schema .impl .ViewTable ;
51
43
import org .apache .calcite .server .DdlExecutor ;
52
44
import org .apache .calcite .server .ServerDdlExecutor ;
53
- import org .apache .calcite .sql .SqlCall ;
54
- import org .apache .calcite .sql .SqlIdentifier ;
55
45
import org .apache .calcite .sql .SqlKind ;
56
46
import org .apache .calcite .sql .SqlNode ;
57
- import org .apache .calcite .sql .SqlNodeList ;
58
- import org .apache .calcite .sql .SqlSelect ;
59
47
import org .apache .calcite .sql .ddl .SqlCreateMaterializedView ;
60
48
import org .apache .calcite .sql .ddl .SqlCreateView ;
61
49
import org .apache .calcite .sql .ddl .SqlDropObject ;
62
50
import org .apache .calcite .sql .dialect .CalciteSqlDialect ;
63
- import org .apache .calcite .sql .fun .SqlStdOperatorTable ;
64
51
import org .apache .calcite .sql .parser .SqlAbstractParserImpl ;
65
52
import org .apache .calcite .sql .parser .SqlParserImplFactory ;
66
53
import org .apache .calcite .sql .parser .SqlParserPos ;
67
54
import org .apache .calcite .sql .parser .ddl .SqlDdlParserImpl ;
68
- import org .apache .calcite .sql .type .SqlTypeFactoryImpl ;
69
55
import org .apache .calcite .sql .validate .SqlConformanceEnum ;
70
56
import org .apache .calcite .util .Pair ;
71
- import org .apache .calcite .util .Util ;
72
57
73
58
74
59
public final class HoptimatorDdlExecutor extends ServerDdlExecutor {
@@ -107,7 +92,7 @@ public void execute(SqlCreateView create, CalcitePrepare.Context context) {
107
92
throw new DdlException (create , e .getMessage (), e );
108
93
}
109
94
110
- final Pair <CalciteSchema , String > pair = schema (context , true , create .name );
95
+ final Pair <CalciteSchema , String > pair = HoptimatorDdlUtils . schema (context , true , create .name );
111
96
if (pair .left == null ) {
112
97
throw new DdlException (create , "Schema for " + create .name + " not found." );
113
98
}
@@ -126,15 +111,13 @@ public void execute(SqlCreateView create, CalcitePrepare.Context context) {
126
111
}
127
112
}
128
113
129
- final SqlNode q = renameColumns (create .columnList , create .query );
114
+ final SqlNode q = HoptimatorDdlUtils . renameColumns (create .columnList , create .query );
130
115
final String sql = q .toSqlString (CalciteSqlDialect .DEFAULT ).getSql ();
131
116
List <String > schemaPath = pair .left .path (null );
132
117
String viewName = pair .right ;
133
118
List <String > viewPath = new ArrayList <>(schemaPath );
134
119
viewPath .add (viewName );
135
- CalcitePrepare .AnalyzeViewResult analyzed = HoptimatorDriver .analyzeView (connection , sql );
136
- RelProtoDataType protoType = RelDataTypeImpl .proto (analyzed .rowType );
137
- ViewTable viewTable = new ViewTable (Object .class , protoType , sql , schemaPath , viewPath );
120
+ ViewTable viewTable = HoptimatorDdlUtils .viewTable (context , sql , new HoptimatorDriver .Prepare (connection ), schemaPath , viewPath );
138
121
View view = new View (viewPath , sql );
139
122
logger .info ("Validated sql statement. The view is named {} and has path {}" ,
140
123
viewName , viewPath );
@@ -177,7 +160,7 @@ public void execute(SqlCreateMaterializedView create, CalcitePrepare.Context con
177
160
throw new DdlException (create , e .getMessage (), e );
178
161
}
179
162
180
- final Pair <CalciteSchema , String > pair = schema (context , true , create .name );
163
+ final Pair <CalciteSchema , String > pair = HoptimatorDdlUtils . schema (context , true , create .name );
181
164
if (pair .left == null ) {
182
165
throw new DdlException (create , "Schema for " + create .name + " not found." );
183
166
}
@@ -201,7 +184,7 @@ public void execute(SqlCreateMaterializedView create, CalcitePrepare.Context con
201
184
}
202
185
}
203
186
204
- final SqlNode q = renameColumns (create .columnList , create .query );
187
+ final SqlNode q = HoptimatorDdlUtils . renameColumns (create .columnList , create .query );
205
188
final String sql = q .toSqlString (CalciteSqlDialect .DEFAULT ).getSql ();
206
189
final List <String > schemaPath = pair .left .path (null );
207
190
@@ -212,21 +195,13 @@ public void execute(SqlCreateMaterializedView create, CalcitePrepare.Context con
212
195
List <String > viewPath = new ArrayList <>(schemaPath );
213
196
viewPath .add (viewName );
214
197
215
- Table currentViewTable = schemaPlus . getTable ( viewName ) ;
198
+ Pair < SchemaPlus , Table > schemaSnapshot = null ;
216
199
try {
217
200
if (!(pair .left .schema instanceof Database )) {
218
201
throw new DdlException (create , schemaName + " is not a physical database." );
219
202
}
220
203
String database = ((Database ) pair .left .schema ).databaseName ();
221
204
222
- // Table does not exist. Create it.
223
- RelDataTypeFactory typeFactory = new SqlTypeFactoryImpl (RelDataTypeSystem .DEFAULT );
224
- CalcitePrepare .AnalyzeViewResult analyzed = HoptimatorDriver .analyzeView (connection , sql );
225
- RelProtoDataType protoType = RelDataTypeImpl .proto (analyzed .rowType );
226
- ViewTable viewTable = new ViewTable (Object .class , protoType , sql , schemaPath , viewPath );
227
- MaterializedViewTable materializedViewTable = new MaterializedViewTable (viewTable );
228
- RelDataType viewRowType = materializedViewTable .getRowType (typeFactory );
229
-
230
205
logger .info ("Validated sql statement. The view is named {} and has path {}" ,
231
206
viewName , viewPath );
232
207
@@ -241,26 +216,11 @@ public void execute(SqlCreateMaterializedView create, CalcitePrepare.Context con
241
216
logger .info ("Pipeline name for view {} is {}" , viewName , pipelineName );
242
217
Properties connectionProperties = connection .connectionProperties ();
243
218
connectionProperties .setProperty (DeploymentService .PIPELINE_OPTION , pipelineName );
244
- List <String > sinkPath = new ArrayList <>(schemaPath );
245
- sinkPath .add (sinkName );
246
- Table sink = schemaPlus .getTable (sinkName );
247
-
248
- final RelDataType rowType ;
249
- if (sink != null ) {
250
- // For "partial views", the sink may already exist. Use the existing row type.
251
- rowType = sink .getRowType (typeFactory );
252
- } else {
253
- // For normal views, we create the sink based on the view row type.
254
- rowType = viewRowType ;
255
- }
256
219
257
220
// Plan a pipeline to materialize the view.
258
221
RelRoot root = new HoptimatorDriver .Prepare (connection ).convert (context , sql ).root ;
259
222
PipelineRel .Implementor plan = DeploymentService .plan (root , connection .materializations (), connectionProperties );
260
- plan .setSink (database , sinkPath , rowType , Collections .emptyMap ());
261
-
262
- // Need to add the view table to the connection so that the ConnectorService can find it when resolving options.
263
- schemaPlus .add (viewName , materializedViewTable );
223
+ schemaSnapshot = HoptimatorDdlUtils .snapshotAndSetSinkSchema (context , new HoptimatorDriver .Prepare (connection ), plan , sql , pair );
264
224
logger .info ("Added view {} to schema {}" , viewName , schemaPlus .getName ());
265
225
Pipeline pipeline = plan .pipeline (viewName , connection );
266
226
MaterializedView hook = new MaterializedView (database , viewPath , sql , pipeline .job ().sql (), pipeline );
@@ -282,10 +242,12 @@ public void execute(SqlCreateMaterializedView create, CalcitePrepare.Context con
282
242
if (deployers != null ) {
283
243
DeploymentService .restore (deployers );
284
244
}
285
- if (currentViewTable == null ) {
286
- schemaPlus .removeTable (viewName );
287
- } else {
288
- schemaPlus .add (viewName , currentViewTable );
245
+ if (schemaSnapshot != null ) {
246
+ if (schemaSnapshot .right == null ) {
247
+ schemaSnapshot .left .removeTable (viewName );
248
+ } else {
249
+ schemaPlus .add (viewName , schemaSnapshot .right );
250
+ }
289
251
}
290
252
throw new DdlException (create , e .getMessage (), e );
291
253
}
@@ -304,7 +266,7 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
304
266
return ;
305
267
}
306
268
307
- final Pair <CalciteSchema , String > pair = schema (context , false , drop .name );
269
+ final Pair <CalciteSchema , String > pair = HoptimatorDdlUtils . schema (context , false , drop .name );
308
270
String viewName = pair .right ;
309
271
310
272
SchemaPlus schemaPlus = pair .left .plus ();
@@ -344,41 +306,6 @@ public void execute(SqlDropObject drop, CalcitePrepare.Context context) {
344
306
schemaPlus .removeTable (viewName );
345
307
}
346
308
347
- // N.B. copy-pasted from Apache Calcite
348
-
349
- /** Returns the schema in which to create an object. */
350
- static Pair <CalciteSchema , String > schema (CalcitePrepare .Context context , boolean mutable , SqlIdentifier id ) {
351
- final String name ;
352
- final List <String > path ;
353
- if (id .isSimple ()) {
354
- path = context .getDefaultSchemaPath ();
355
- name = id .getSimple ();
356
- } else {
357
- path = Util .skipLast (id .names );
358
- name = Util .last (id .names );
359
- }
360
- CalciteSchema schema = mutable ? context .getMutableRootSchema () : context .getRootSchema ();
361
- for (String p : path ) {
362
- schema = Objects .requireNonNull (schema ).getSubSchema (p , true );
363
- }
364
- return Pair .of (schema , name );
365
- }
366
-
367
- // N.B. copy-pasted from Apache Calcite
368
-
369
- /** Wraps a query to rename its columns. Used by CREATE VIEW and CREATE
370
- * MATERIALIZED VIEW. */
371
- static SqlNode renameColumns (SqlNodeList columnList , SqlNode query ) {
372
- if (columnList == null ) {
373
- return query ;
374
- }
375
- final SqlParserPos p = query .getParserPosition ();
376
- final SqlNodeList selectList = SqlNodeList .SINGLETON_STAR ;
377
- final SqlCall from = SqlStdOperatorTable .AS .createCall (p ,
378
- Arrays .asList (query , new SqlIdentifier ("_" , p ), columnList ));
379
- return new SqlSelect (p , null , selectList , from , null , null , null , null , null , null , null , null , null );
380
- }
381
-
382
309
/** Unchecked exception related to a DDL statement. */
383
310
static public class DdlException extends RuntimeException {
384
311
0 commit comments