dt-sql-parser 4.4.2 → 4.5.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -3
- package/dist/lib/SQLParserBase.d.ts +13 -1
- package/dist/lib/SQLParserBase.js +40 -5
- package/dist/lib/flink/FlinkSqlLexer.d.ts +397 -399
- package/dist/lib/flink/FlinkSqlLexer.js +2489 -2504
- package/dist/lib/flink/FlinkSqlParser.d.ts +726 -728
- package/dist/lib/flink/FlinkSqlParser.js +4727 -5330
- package/dist/lib/flink/FlinkSqlParserListener.d.ts +132 -90
- package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +84 -57
- package/dist/lib/hive/HiveSqlParser.d.ts +338 -239
- package/dist/lib/hive/HiveSqlParser.js +6466 -5794
- package/dist/lib/hive/HiveSqlParserListener.d.ts +88 -0
- package/dist/lib/hive/HiveSqlParserVisitor.d.ts +56 -0
- package/dist/lib/impala/ImpalaSqlParser.d.ts +236 -125
- package/dist/lib/impala/ImpalaSqlParser.js +4257 -3483
- package/dist/lib/impala/ImpalaSqlParserListener.d.ts +109 -14
- package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +69 -8
- package/dist/lib/mysql/MySqlParser.d.ts +403 -306
- package/dist/lib/mysql/MySqlParser.js +10694 -10030
- package/dist/lib/mysql/MySqlParserListener.d.ts +121 -18
- package/dist/lib/mysql/MySqlParserVisitor.d.ts +75 -10
- package/dist/lib/postgresql/PostgreSqlParser.d.ts +256 -173
- package/dist/lib/postgresql/PostgreSqlParser.js +14934 -11710
- package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +97 -5
- package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +61 -3
- package/dist/lib/spark/SparkSqlParser.d.ts +314 -149
- package/dist/lib/spark/SparkSqlParser.js +6185 -5227
- package/dist/lib/spark/SparkSqlParserListener.d.ts +180 -5
- package/dist/lib/spark/SparkSqlParserVisitor.d.ts +113 -3
- package/dist/lib/trino/TrinoSqlListener.d.ts +90 -37
- package/dist/lib/trino/TrinoSqlParser.d.ts +219 -165
- package/dist/lib/trino/TrinoSqlParser.js +4942 -4615
- package/dist/lib/trino/TrinoSqlVisitor.d.ts +55 -21
- package/dist/parser/common/basicSQL.d.ts +5 -5
- package/dist/parser/common/basicSQL.js +4 -2
- package/dist/parser/common/entityCollector.d.ts +91 -4
- package/dist/parser/common/entityCollector.js +227 -11
- package/dist/parser/common/textAndWord.d.ts +9 -1
- package/dist/parser/common/textAndWord.js +2 -0
- package/dist/parser/common/types.d.ts +2 -0
- package/dist/parser/common/types.js +2 -0
- package/dist/parser/flink/flinkEntityCollector.d.ts +10 -2
- package/dist/parser/flink/flinkEntityCollector.js +76 -14
- package/dist/parser/flink/index.js +5 -2
- package/dist/parser/hive/hiveEntityCollector.d.ts +13 -1
- package/dist/parser/hive/hiveEntityCollector.js +85 -12
- package/dist/parser/impala/impalaEntityCollector.d.ts +7 -1
- package/dist/parser/impala/impalaEntityCollector.js +63 -12
- package/dist/parser/impala/index.js +2 -1
- package/dist/parser/mysql/index.js +3 -1
- package/dist/parser/mysql/mysqlEntityCollector.d.ts +10 -1
- package/dist/parser/mysql/mysqlEntityCollector.js +65 -12
- package/dist/parser/mysql/mysqlErrorListener.js +2 -0
- package/dist/parser/postgresql/postgreEntityCollector.d.ts +12 -1
- package/dist/parser/postgresql/postgreEntityCollector.js +99 -22
- package/dist/parser/spark/index.js +3 -1
- package/dist/parser/spark/sparkEntityCollector.d.ts +13 -1
- package/dist/parser/spark/sparkEntityCollector.js +88 -12
- package/dist/parser/trino/trinoEntityCollector.d.ts +7 -1
- package/dist/parser/trino/trinoEntityCollector.js +53 -12
- package/package.json +1 -1
|
@@ -30,16 +30,19 @@ export var StmtContextType;
|
|
|
30
30
|
StmtContextType["ALTER_TABLE_STMT"] = "alterTableStmt";
|
|
31
31
|
})(StmtContextType || (StmtContextType = {}));
|
|
32
32
|
export function toStmtContext(ctx, type, input, rootStmt, parentStmt, isContainCaret) {
|
|
33
|
+
var _a;
|
|
33
34
|
const text = ctxToText(ctx, input);
|
|
34
35
|
if (!text)
|
|
35
36
|
return null;
|
|
36
|
-
const { text:
|
|
37
|
+
const { text: stmtText } = text, position = __rest(text, ["text"]);
|
|
37
38
|
return {
|
|
38
39
|
stmtContextType: type,
|
|
39
40
|
position,
|
|
40
41
|
rootStmt: rootStmt !== null && rootStmt !== void 0 ? rootStmt : null,
|
|
41
42
|
parentStmt: parentStmt !== null && parentStmt !== void 0 ? parentStmt : null,
|
|
42
43
|
isContainCaret,
|
|
44
|
+
text: stmtText,
|
|
45
|
+
scopeDepth: type === StmtContextType.COMMON_STMT ? 0 : ((_a = parentStmt === null || parentStmt === void 0 ? void 0 : parentStmt.scopeDepth) !== null && _a !== void 0 ? _a : 0) + 1,
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
/**
|
|
@@ -54,22 +57,56 @@ export var AttrName;
|
|
|
54
57
|
AttrName["colType"] = "_colType";
|
|
55
58
|
AttrName["alias"] = "_alias";
|
|
56
59
|
})(AttrName || (AttrName = {}));
|
|
60
|
+
/**
|
|
61
|
+
* Types of column declarations
|
|
62
|
+
*/
|
|
63
|
+
export var ColumnDeclareType;
|
|
64
|
+
(function (ColumnDeclareType) {
|
|
65
|
+
/** Literal column name */
|
|
66
|
+
ColumnDeclareType[ColumnDeclareType["LITERAL"] = 0] = "LITERAL";
|
|
67
|
+
/** Using asterisk syntax (tableName.*) */
|
|
68
|
+
ColumnDeclareType[ColumnDeclareType["ALL"] = 1] = "ALL";
|
|
69
|
+
/** Complex expressions like subqueries, case statements, function calls */
|
|
70
|
+
ColumnDeclareType[ColumnDeclareType["EXPRESSION"] = 2] = "EXPRESSION";
|
|
71
|
+
})(ColumnDeclareType || (ColumnDeclareType = {}));
|
|
72
|
+
/**
|
|
73
|
+
* Types of table declarations
|
|
74
|
+
*/
|
|
75
|
+
export var TableDeclareType;
|
|
76
|
+
(function (TableDeclareType) {
|
|
77
|
+
/** Regular table reference */
|
|
78
|
+
TableDeclareType[TableDeclareType["LITERAL"] = 0] = "LITERAL";
|
|
79
|
+
/** Table defined by expression (e.g., subquery) */
|
|
80
|
+
TableDeclareType[TableDeclareType["EXPRESSION"] = 1] = "EXPRESSION";
|
|
81
|
+
})(TableDeclareType || (TableDeclareType = {}));
|
|
57
82
|
export function isCommonEntityContext(entity) {
|
|
58
83
|
if (!entity)
|
|
59
84
|
return false;
|
|
60
|
-
return
|
|
85
|
+
return !isFuncEntityContext(entity) && !isColumnEntityContext(entity);
|
|
61
86
|
}
|
|
62
87
|
export function isFuncEntityContext(entity) {
|
|
63
88
|
if (!entity)
|
|
64
89
|
return false;
|
|
65
|
-
return
|
|
90
|
+
return [EntityContextType.FUNCTION, EntityContextType.FUNCTION_CREATE].includes(entity.entityContextType);
|
|
66
91
|
}
|
|
67
92
|
export function isColumnEntityContext(entity) {
|
|
68
93
|
if (!entity)
|
|
69
94
|
return false;
|
|
70
|
-
return
|
|
95
|
+
return [EntityContextType.COLUMN, EntityContextType.COLUMN_CREATE].includes(entity.entityContextType);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Check if ctx is a child node of a specific rule type
|
|
99
|
+
*/
|
|
100
|
+
export function isChildContextOf(ctx, parentRuleIndex) {
|
|
101
|
+
let parentCtx = ctx.parent;
|
|
102
|
+
while (parentCtx) {
|
|
103
|
+
if (parentCtx.ruleIndex === parentRuleIndex)
|
|
104
|
+
return true;
|
|
105
|
+
parentCtx = parentCtx.parent;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
71
108
|
}
|
|
72
|
-
export function toEntityContext(ctx, type, input, belongStmt, attrInfo) {
|
|
109
|
+
export function toEntityContext(ctx, type, input, belongStmt, attrInfo, metaInfo) {
|
|
73
110
|
var _a, _b;
|
|
74
111
|
const word = ctxToText(ctx, input);
|
|
75
112
|
if (!word)
|
|
@@ -81,6 +118,7 @@ export function toEntityContext(ctx, type, input, belongStmt, attrInfo) {
|
|
|
81
118
|
text,
|
|
82
119
|
position,
|
|
83
120
|
belongStmt,
|
|
121
|
+
declareType: metaInfo === null || metaInfo === void 0 ? void 0 : metaInfo.declareType,
|
|
84
122
|
[AttrName.comment]: null,
|
|
85
123
|
};
|
|
86
124
|
switch (entityInfo.entityContextType) {
|
|
@@ -168,6 +206,24 @@ function findAttributeChildren(ctx, keyName) {
|
|
|
168
206
|
}
|
|
169
207
|
return attrVal;
|
|
170
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* Check if an entity is contained within the range entity's context
|
|
211
|
+
* @param entity - The entity to check if it's contained
|
|
212
|
+
* @param rangeEntity - The entity that defines the containing range
|
|
213
|
+
* @returns true if entity is contained within rangeEntity's range
|
|
214
|
+
*/
|
|
215
|
+
function isEntityInScope(entity, rangeEntity) {
|
|
216
|
+
const entityStart = entity.position.startTokenIndex;
|
|
217
|
+
const entityStop = entity.position.endTokenIndex;
|
|
218
|
+
const rangeStart = rangeEntity.position.startTokenIndex;
|
|
219
|
+
const rangeStop = rangeEntity.position.endTokenIndex;
|
|
220
|
+
return (entityStart != null &&
|
|
221
|
+
entityStop != null &&
|
|
222
|
+
rangeStart != null &&
|
|
223
|
+
rangeStop != null &&
|
|
224
|
+
rangeStart <= entityStart &&
|
|
225
|
+
rangeStop >= entityStop);
|
|
226
|
+
}
|
|
171
227
|
/**
|
|
172
228
|
* @todo: Handle alias, includes column alias, table alias, query as alias and so on.
|
|
173
229
|
* @todo: [may be need] Combine the entities in each clause.
|
|
@@ -181,6 +237,8 @@ export class EntityCollector {
|
|
|
181
237
|
this._stmtStack = new SimpleStack();
|
|
182
238
|
this._entityStack = new SimpleStack();
|
|
183
239
|
this._rootStmt = null;
|
|
240
|
+
this._caretStmtScopeDepth = 0;
|
|
241
|
+
this._caretStmt = null;
|
|
184
242
|
}
|
|
185
243
|
visitTerminal() { }
|
|
186
244
|
visitErrorNode() { }
|
|
@@ -198,6 +256,78 @@ export class EntityCollector {
|
|
|
198
256
|
this._entityStack.clear();
|
|
199
257
|
this._rootStmt = null;
|
|
200
258
|
}
|
|
259
|
+
exitProgram() {
|
|
260
|
+
const entities = Array.from(this._entitiesSet);
|
|
261
|
+
if (this._caretTokenIndex !== -1) {
|
|
262
|
+
this.attachAccessibleToEntities(entities);
|
|
263
|
+
}
|
|
264
|
+
this._entityStack.clear();
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Adds accessibility markers to entities
|
|
268
|
+
* @param entities The list of entities to process
|
|
269
|
+
*/
|
|
270
|
+
attachAccessibleToEntities(entities) {
|
|
271
|
+
var _a;
|
|
272
|
+
if (!entities.length) {
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
for (const entity of entities) {
|
|
276
|
+
if (entity.isAccessible !== undefined) {
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
const entityScopeDepth = (_a = entity.belongStmt.scopeDepth) !== null && _a !== void 0 ? _a : 0;
|
|
280
|
+
if (entity.entityContextType === EntityContextType.TABLE) {
|
|
281
|
+
entity.isAccessible =
|
|
282
|
+
!!entity.belongStmt.isContainCaret &&
|
|
283
|
+
entityScopeDepth === this._caretStmtScopeDepth;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
entity.isAccessible = null;
|
|
287
|
+
}
|
|
288
|
+
// Recursively process related entities
|
|
289
|
+
if (entity.relatedEntities) {
|
|
290
|
+
this.attachAccessibleToEntities(entity.relatedEntities);
|
|
291
|
+
}
|
|
292
|
+
// Process columns of the table
|
|
293
|
+
if (entity.columns) {
|
|
294
|
+
const columnEntities = entity.columns || [];
|
|
295
|
+
this.attachAccessibleToEntities(columnEntities);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Attach query result to column if the column is derived from expression.
|
|
301
|
+
*/
|
|
302
|
+
attachQueryResultToColumn(column, queryResults) {
|
|
303
|
+
const relatedEntities = queryResults.filter((queryResult) => isEntityInScope(queryResult, column));
|
|
304
|
+
column.relatedEntities = relatedEntities;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Attach related columns to query result
|
|
308
|
+
*/
|
|
309
|
+
attachColumnsToQueryResult(queryResult, columns) {
|
|
310
|
+
const relatedColumns = columns.filter((column) => column.belongStmt === queryResult.belongStmt);
|
|
311
|
+
queryResult.columns = relatedColumns;
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Attach query result to table if the table is derived from expression.
|
|
315
|
+
*/
|
|
316
|
+
attachQueryResultToTable(table, queryResults) {
|
|
317
|
+
const relatedQueryResults = queryResults.filter((queryResult) => isEntityInScope(queryResult, table));
|
|
318
|
+
table.relatedEntities = relatedQueryResults;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Gets query result entities inside a statement
|
|
322
|
+
* @param stmt The statement to search within
|
|
323
|
+
* @returns Array of query result entity contexts
|
|
324
|
+
*/
|
|
325
|
+
getQueryResultEntitiesInsideStmt(stmt) {
|
|
326
|
+
return this.getEntities()
|
|
327
|
+
.filter((entity) => entity.entityContextType === EntityContextType.QUERY_RESULT &&
|
|
328
|
+
entity.belongStmt.parentStmt === stmt)
|
|
329
|
+
.filter(isCommonEntityContext);
|
|
330
|
+
}
|
|
201
331
|
/**
|
|
202
332
|
* The antlr4 will ignore hidden tokens, if we type whitespace at the end of a statement,
|
|
203
333
|
* the whitespace token will not as stop token, so we consider the whitespace token as a part of the nonhidden token in front of it
|
|
@@ -223,6 +353,9 @@ export class EntityCollector {
|
|
|
223
353
|
!!ctx.stop &&
|
|
224
354
|
ctx.start.tokenIndex <= this._caretTokenIndex &&
|
|
225
355
|
ctx.stop.tokenIndex >= this.getPrevNonHiddenTokenIndex(this._caretTokenIndex);
|
|
356
|
+
if (isContainCaret && type !== StmtContextType.COMMON_STMT) {
|
|
357
|
+
this._caretStmtScopeDepth++;
|
|
358
|
+
}
|
|
226
359
|
}
|
|
227
360
|
const stmtContext = toStmtContext(ctx, type, this._input, this._rootStmt, this._stmtStack.peek(), isContainCaret);
|
|
228
361
|
if (stmtContext) {
|
|
@@ -236,16 +369,24 @@ export class EntityCollector {
|
|
|
236
369
|
}
|
|
237
370
|
popStmt() {
|
|
238
371
|
const stmtContext = this._stmtStack.pop();
|
|
239
|
-
if (stmtContext
|
|
240
|
-
|
|
372
|
+
if (stmtContext) {
|
|
373
|
+
if (stmtContext.stmtContextType === StmtContextType.COMMON_STMT) {
|
|
374
|
+
this._rootStmt = this._stmtStack.peek();
|
|
375
|
+
}
|
|
241
376
|
if (!this._entityStack.isEmpty()) {
|
|
242
377
|
this.combineEntitiesAndAdd(stmtContext);
|
|
243
378
|
}
|
|
379
|
+
// If the current statement contains the caret and its scope depth equals the caret statement's scope depth
|
|
380
|
+
// then set it as the nearest statement containing the caret
|
|
381
|
+
if (stmtContext.isContainCaret &&
|
|
382
|
+
stmtContext.scopeDepth === this._caretStmtScopeDepth) {
|
|
383
|
+
this._caretStmt = stmtContext;
|
|
384
|
+
}
|
|
244
385
|
}
|
|
245
386
|
return stmtContext;
|
|
246
387
|
}
|
|
247
|
-
pushEntity(ctx, type, attrInfo) {
|
|
248
|
-
const entityContext = toEntityContext(ctx, type, this._input, this._stmtStack.peek(), attrInfo);
|
|
388
|
+
pushEntity(ctx, type, attrInfo, metaInfo) {
|
|
389
|
+
const entityContext = toEntityContext(ctx, type, this._input, this._stmtStack.peek(), attrInfo, metaInfo);
|
|
249
390
|
if (entityContext) {
|
|
250
391
|
if (this._stmtStack.isEmpty()) {
|
|
251
392
|
this._entitiesSet.add(entityContext);
|
|
@@ -283,13 +424,88 @@ export class EntityCollector {
|
|
|
283
424
|
stmtContext.stmtContextType === StmtContextType.CREATE_TABLE_STMT) {
|
|
284
425
|
return this.combineCreateTableOrViewStmtEntities(stmtContext, entitiesInsideStmt);
|
|
285
426
|
}
|
|
286
|
-
|
|
427
|
+
else if (stmtContext.stmtContextType === StmtContextType.SELECT_STMT) {
|
|
428
|
+
const tableSourceEntities = this.combineFromTableSource(stmtContext, entitiesInsideStmt);
|
|
429
|
+
const queryResultEntities = this.combineQueryResultStmtEntities(stmtContext, entitiesInsideStmt);
|
|
430
|
+
const otherEntities = entitiesInsideStmt.filter((entity) => ![
|
|
431
|
+
EntityContextType.QUERY_RESULT,
|
|
432
|
+
EntityContextType.TABLE,
|
|
433
|
+
EntityContextType.COLUMN,
|
|
434
|
+
].includes(entity.entityContextType));
|
|
435
|
+
return Array.from(new Set([...tableSourceEntities, ...queryResultEntities, ...otherEntities]));
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
// Do not collect column and queryResult entities if they are not inside a select statement
|
|
439
|
+
// Exception: empty column entities (text === '') should be kept
|
|
440
|
+
return entitiesInsideStmt.filter((entity) => {
|
|
441
|
+
// Keep non-COLUMN and non-QUERY_RESULT entities
|
|
442
|
+
if (entity.entityContextType !== EntityContextType.COLUMN &&
|
|
443
|
+
entity.entityContextType !== EntityContextType.QUERY_RESULT) {
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
// Also keep empty QUERY_RESULT entities (text === '')
|
|
447
|
+
if (entity.entityContextType === EntityContextType.QUERY_RESULT &&
|
|
448
|
+
entity.text === '') {
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
return false;
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
combineQueryResultStmtEntities(stmtContext, entitiesInsideStmt) {
|
|
456
|
+
if (!stmtContext || !(entitiesInsideStmt === null || entitiesInsideStmt === void 0 ? void 0 : entitiesInsideStmt.length)) {
|
|
457
|
+
return [];
|
|
458
|
+
}
|
|
459
|
+
const columnEntities = [];
|
|
460
|
+
const relatedTableEntities = [];
|
|
461
|
+
const finalEntities = [];
|
|
462
|
+
const queryResultEntitiesInsideStmt = this.getQueryResultEntitiesInsideStmt(stmtContext);
|
|
463
|
+
// Categorize and process entities
|
|
464
|
+
entitiesInsideStmt.forEach((entity) => {
|
|
465
|
+
if (entity.belongStmt !== stmtContext)
|
|
466
|
+
return;
|
|
467
|
+
if (entity.entityContextType === EntityContextType.QUERY_RESULT &&
|
|
468
|
+
isCommonEntityContext(entity)) {
|
|
469
|
+
finalEntities.push(entity);
|
|
470
|
+
}
|
|
471
|
+
else if (entity.entityContextType === EntityContextType.COLUMN &&
|
|
472
|
+
isColumnEntityContext(entity)) {
|
|
473
|
+
if (entity.declareType === ColumnDeclareType.EXPRESSION) {
|
|
474
|
+
this.attachQueryResultToColumn(entity, queryResultEntitiesInsideStmt);
|
|
475
|
+
}
|
|
476
|
+
columnEntities.push(entity);
|
|
477
|
+
}
|
|
478
|
+
else if (entity.entityContextType === EntityContextType.TABLE &&
|
|
479
|
+
isCommonEntityContext(entity)) {
|
|
480
|
+
relatedTableEntities.push(entity);
|
|
481
|
+
}
|
|
482
|
+
});
|
|
483
|
+
// combine collected entities to query result entity
|
|
484
|
+
finalEntities.forEach((queryResultEntity) => {
|
|
485
|
+
this.attachColumnsToQueryResult(queryResultEntity, columnEntities);
|
|
486
|
+
queryResultEntity.relatedEntities = relatedTableEntities;
|
|
487
|
+
});
|
|
488
|
+
return finalEntities;
|
|
489
|
+
}
|
|
490
|
+
combineFromTableSource(stmtContext, entitiesInsideStmt) {
|
|
491
|
+
const finalEntities = [];
|
|
492
|
+
const queryResultEntitiesInsideStmt = this.getQueryResultEntitiesInsideStmt(stmtContext);
|
|
493
|
+
const tableEntities = (entitiesInsideStmt.filter((entity) => entity.entityContextType === EntityContextType.TABLE));
|
|
494
|
+
tableEntities.forEach((table) => {
|
|
495
|
+
// If it's an EXPRESSION type (subquery), need to associate with QUERY_RESULT entities
|
|
496
|
+
if (table.declareType === TableDeclareType.EXPRESSION) {
|
|
497
|
+
this.attachQueryResultToTable(table, queryResultEntitiesInsideStmt);
|
|
498
|
+
}
|
|
499
|
+
finalEntities.push(table);
|
|
500
|
+
});
|
|
501
|
+
return finalEntities;
|
|
287
502
|
}
|
|
288
503
|
combineCreateTableOrViewStmtEntities(stmtContext, entitiesInsideStmt) {
|
|
289
504
|
const columns = [];
|
|
290
505
|
const relatedEntities = [];
|
|
506
|
+
const queryResultEntitiesInsideStmt = this.getQueryResultEntitiesInsideStmt(stmtContext);
|
|
291
507
|
let mainEntity = null;
|
|
292
|
-
const finalEntities = entitiesInsideStmt.reduce((result, entity) => {
|
|
508
|
+
const finalEntities = [...entitiesInsideStmt, ...queryResultEntitiesInsideStmt].reduce((result, entity) => {
|
|
293
509
|
if (entity.belongStmt !== stmtContext) {
|
|
294
510
|
if (entity.entityContextType !== EntityContextType.COLUMN &&
|
|
295
511
|
entity.entityContextType !== EntityContextType.COLUMN_CREATE) {
|
|
@@ -10,8 +10,12 @@ export interface WordPosition {
|
|
|
10
10
|
readonly startColumn: number;
|
|
11
11
|
/** end at ..n + 1 */
|
|
12
12
|
readonly endColumn: number;
|
|
13
|
+
/** start at 0 */
|
|
14
|
+
readonly startTokenIndex: number;
|
|
15
|
+
/** end at ..n-1 */
|
|
16
|
+
readonly endTokenIndex: number;
|
|
13
17
|
}
|
|
14
|
-
export interface WordRange extends WordPosition {
|
|
18
|
+
export interface WordRange extends Omit<WordPosition, 'startTokenIndex' | 'endTokenIndex'> {
|
|
15
19
|
/** content of word */
|
|
16
20
|
readonly text: string;
|
|
17
21
|
}
|
|
@@ -28,6 +32,10 @@ export interface TextPosition {
|
|
|
28
32
|
readonly startColumn: number;
|
|
29
33
|
/** end at ..n + 1 */
|
|
30
34
|
readonly endColumn: number;
|
|
35
|
+
/** start at 0 */
|
|
36
|
+
readonly startTokenIndex: number;
|
|
37
|
+
/** end at ..n-1 */
|
|
38
|
+
readonly endTokenIndex: number;
|
|
31
39
|
}
|
|
32
40
|
export interface TextSlice extends TextPosition {
|
|
33
41
|
readonly text: string;
|
|
@@ -34,6 +34,8 @@ export function ctxToText(ctx, input) {
|
|
|
34
34
|
endIndex,
|
|
35
35
|
startColumn: ctx.start.column + 1,
|
|
36
36
|
endColumn: ctx.stop.column + 1 + ((_b = (_a = ctx.stop.text) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0),
|
|
37
|
+
startTokenIndex: ctx.start.tokenIndex,
|
|
38
|
+
endTokenIndex: ctx.stop.tokenIndex,
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
41
|
/**
|
|
@@ -42,6 +42,8 @@ export declare enum EntityContextType {
|
|
|
42
42
|
COLUMN = "column",
|
|
43
43
|
/** column name that will be created */
|
|
44
44
|
COLUMN_CREATE = "columnCreate",
|
|
45
|
+
/** query result */
|
|
46
|
+
QUERY_RESULT = "queryResult",
|
|
45
47
|
/** table property key when creating table*/
|
|
46
48
|
TABLE_PROPERTY_KEY = "tablePropertyKey",
|
|
47
49
|
/** table property value when creating table*/
|
|
@@ -31,6 +31,8 @@ export var EntityContextType;
|
|
|
31
31
|
EntityContextType["COLUMN"] = "column";
|
|
32
32
|
/** column name that will be created */
|
|
33
33
|
EntityContextType["COLUMN_CREATE"] = "columnCreate";
|
|
34
|
+
/** query result */
|
|
35
|
+
EntityContextType["QUERY_RESULT"] = "queryResult";
|
|
34
36
|
/** table property key when creating table*/
|
|
35
37
|
EntityContextType["TABLE_PROPERTY_KEY"] = "tablePropertyKey";
|
|
36
38
|
/** table property value when creating table*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CatalogPathContext, CatalogPathCreateContext, ColumnNameCreateContext, CreateCatalogContext, CreateDatabaseContext, CreateFunctionContext, CreateTableContext, CreateViewContext, DatabasePathContext, DatabasePathCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryStatementContext, SqlStatementContext, TablePathContext, TablePathCreateContext, ViewPathContext, ViewPathCreateContext } from '../../lib/flink/FlinkSqlParser';
|
|
1
|
+
import { AtomExpressionTableContext, AtomFunctionTableContext, CatalogPathContext, CatalogPathCreateContext, ColumnNameCreateContext, CreateCatalogContext, CreateDatabaseContext, CreateFunctionContext, CreateTableContext, CreateViewContext, DatabasePathContext, DatabasePathCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryStatementContext, SelectExpressionColumnNameContext, SelectListContext, SelectLiteralColumnNameContext, SelectWindowItemColumnNameContext, SqlStatementContext, TableAllColumnsContext, TablePathContext, TablePathCreateContext, ViewPathContext, ViewPathCreateContext } from '../../lib/flink/FlinkSqlParser';
|
|
2
2
|
import { FlinkSqlParserListener } from '../../lib/flink/FlinkSqlParserListener';
|
|
3
3
|
import { EntityCollector } from '../common/entityCollector';
|
|
4
4
|
export declare class FlinkEntityCollector extends EntityCollector implements FlinkSqlParserListener {
|
|
@@ -8,11 +8,19 @@ export declare class FlinkEntityCollector extends EntityCollector implements Fli
|
|
|
8
8
|
exitDatabasePathCreate(ctx: DatabasePathCreateContext): void;
|
|
9
9
|
exitDatabasePath(ctx: DatabasePathContext): void;
|
|
10
10
|
exitTablePath(ctx: TablePathContext): void;
|
|
11
|
+
exitAtomFunctionTable(ctx: AtomFunctionTableContext): void;
|
|
12
|
+
exitAtomExpressionTable(ctx: AtomExpressionTableContext): void;
|
|
11
13
|
exitTablePathCreate(ctx: TablePathCreateContext): void;
|
|
12
14
|
exitViewPath(ctx: ViewPathContext): void;
|
|
13
15
|
exitViewPathCreate(ctx: ViewPathCreateContext): void;
|
|
14
|
-
exitColumnNameCreate(ctx: ColumnNameCreateContext): void;
|
|
15
16
|
exitFunctionNameCreate(ctx: FunctionNameCreateContext): void;
|
|
17
|
+
exitSelectList(ctx: SelectListContext): void;
|
|
18
|
+
/** Column entity rules */
|
|
19
|
+
exitColumnNameCreate(ctx: ColumnNameCreateContext): void;
|
|
20
|
+
exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
|
|
21
|
+
exitSelectExpressionColumnName(ctx: SelectExpressionColumnNameContext): void;
|
|
22
|
+
exitSelectWindowItemColumnName(ctx: SelectWindowItemColumnNameContext): void;
|
|
23
|
+
exitTableAllColumns(ctx: TableAllColumnsContext): void;
|
|
16
24
|
/** ===== Statement begin */
|
|
17
25
|
enterSqlStatement(ctx: SqlStatementContext): void;
|
|
18
26
|
exitSqlStatement(ctx: SqlStatementContext): void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CreateDatabaseContext, CreateTableContext, CreateViewContext, PhysicalColumnDefinitionContext, TableReferenceContext, } from '../../lib/flink/FlinkSqlParser';
|
|
2
|
-
import { AttrName, EntityCollector, StmtContextType } from '../common/entityCollector';
|
|
1
|
+
import { ColumnProjectItemContext, CreateDatabaseContext, CreateTableContext, CreateViewContext, OverWindowItemContext, PhysicalColumnDefinitionContext, TableReferenceContext, } from '../../lib/flink/FlinkSqlParser';
|
|
2
|
+
import { AttrName, ColumnDeclareType, EntityCollector, StmtContextType, TableDeclareType, } from '../common/entityCollector';
|
|
3
3
|
import { EntityContextType } from '../common/types';
|
|
4
4
|
export class FlinkEntityCollector extends EntityCollector {
|
|
5
5
|
/** ====== Entity Begin */
|
|
@@ -21,16 +21,34 @@ export class FlinkEntityCollector extends EntityCollector {
|
|
|
21
21
|
this.pushEntity(ctx, EntityContextType.DATABASE);
|
|
22
22
|
}
|
|
23
23
|
exitTablePath(ctx) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
this.pushEntity(ctx, EntityContextType.TABLE, [
|
|
25
|
+
{
|
|
26
|
+
attrName: AttrName.alias,
|
|
27
|
+
endContextList: [TableReferenceContext.name],
|
|
28
|
+
},
|
|
29
|
+
], {
|
|
30
|
+
declareType: TableDeclareType.LITERAL,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exitAtomFunctionTable(ctx) {
|
|
34
|
+
this.pushEntity(ctx, EntityContextType.TABLE, [
|
|
35
|
+
{
|
|
36
|
+
attrName: AttrName.alias,
|
|
37
|
+
endContextList: [TableReferenceContext.name],
|
|
38
|
+
},
|
|
39
|
+
], {
|
|
40
|
+
declareType: TableDeclareType.EXPRESSION,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
exitAtomExpressionTable(ctx) {
|
|
44
|
+
this.pushEntity(ctx, EntityContextType.TABLE, [
|
|
45
|
+
{
|
|
46
|
+
attrName: AttrName.alias,
|
|
47
|
+
endContextList: [TableReferenceContext.name],
|
|
48
|
+
},
|
|
49
|
+
], {
|
|
50
|
+
declareType: TableDeclareType.EXPRESSION,
|
|
51
|
+
});
|
|
34
52
|
}
|
|
35
53
|
exitTablePathCreate(ctx) {
|
|
36
54
|
this.pushEntity(ctx, EntityContextType.TABLE_CREATE, [
|
|
@@ -51,6 +69,13 @@ export class FlinkEntityCollector extends EntityCollector {
|
|
|
51
69
|
},
|
|
52
70
|
]);
|
|
53
71
|
}
|
|
72
|
+
exitFunctionNameCreate(ctx) {
|
|
73
|
+
this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
|
|
74
|
+
}
|
|
75
|
+
exitSelectList(ctx) {
|
|
76
|
+
this.pushEntity(ctx, EntityContextType.QUERY_RESULT);
|
|
77
|
+
}
|
|
78
|
+
/** Column entity rules */
|
|
54
79
|
exitColumnNameCreate(ctx) {
|
|
55
80
|
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE, [
|
|
56
81
|
{
|
|
@@ -63,8 +88,45 @@ export class FlinkEntityCollector extends EntityCollector {
|
|
|
63
88
|
},
|
|
64
89
|
]);
|
|
65
90
|
}
|
|
66
|
-
|
|
67
|
-
this.pushEntity(ctx, EntityContextType.
|
|
91
|
+
exitSelectLiteralColumnName(ctx) {
|
|
92
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
93
|
+
{
|
|
94
|
+
attrName: AttrName.alias,
|
|
95
|
+
endContextList: [ColumnProjectItemContext.name],
|
|
96
|
+
},
|
|
97
|
+
], {
|
|
98
|
+
declareType: ColumnDeclareType.LITERAL,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
exitSelectExpressionColumnName(ctx) {
|
|
102
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
103
|
+
{
|
|
104
|
+
attrName: AttrName.alias,
|
|
105
|
+
endContextList: [ColumnProjectItemContext.name],
|
|
106
|
+
},
|
|
107
|
+
], {
|
|
108
|
+
declareType: ColumnDeclareType.EXPRESSION,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
exitSelectWindowItemColumnName(ctx) {
|
|
112
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
113
|
+
{
|
|
114
|
+
attrName: AttrName.alias,
|
|
115
|
+
endContextList: [ColumnProjectItemContext.name, OverWindowItemContext.name],
|
|
116
|
+
},
|
|
117
|
+
], {
|
|
118
|
+
declareType: ColumnDeclareType.EXPRESSION,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
exitTableAllColumns(ctx) {
|
|
122
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
123
|
+
{
|
|
124
|
+
attrName: AttrName.alias,
|
|
125
|
+
endContextList: [ColumnProjectItemContext.name],
|
|
126
|
+
},
|
|
127
|
+
], {
|
|
128
|
+
declareType: ColumnDeclareType.ALL,
|
|
129
|
+
});
|
|
68
130
|
}
|
|
69
131
|
/** ===== Statement begin */
|
|
70
132
|
enterSqlStatement(ctx) {
|
|
@@ -36,6 +36,7 @@ export class FlinkSQL extends BasicSQL {
|
|
|
36
36
|
FlinkSqlParser.RULE_functionNameCreate, // functionName that will be created
|
|
37
37
|
FlinkSqlParser.RULE_columnName,
|
|
38
38
|
FlinkSqlParser.RULE_columnNamePath,
|
|
39
|
+
FlinkSqlParser.RULE_columnNamePathAllowEmpty,
|
|
39
40
|
FlinkSqlParser.RULE_columnNameCreate,
|
|
40
41
|
FlinkSqlParser.RULE_tablePropertyKey,
|
|
41
42
|
FlinkSqlParser.RULE_tablePropertyValue,
|
|
@@ -116,13 +117,15 @@ export class FlinkSQL extends BasicSQL {
|
|
|
116
117
|
syntaxContextType = EntityContextType.COLUMN_CREATE;
|
|
117
118
|
break;
|
|
118
119
|
}
|
|
119
|
-
case FlinkSqlParser.RULE_columnNamePath:
|
|
120
|
+
case FlinkSqlParser.RULE_columnNamePath:
|
|
121
|
+
case FlinkSqlParser.RULE_columnNamePathAllowEmpty: {
|
|
120
122
|
if (candidateRule.ruleList.includes(FlinkSqlParser.RULE_selectClause) ||
|
|
121
123
|
candidateRule.ruleList.includes(FlinkSqlParser.RULE_whereClause) ||
|
|
122
124
|
candidateRule.ruleList.includes(FlinkSqlParser.RULE_groupByClause) ||
|
|
123
125
|
candidateRule.ruleList.includes(FlinkSqlParser.RULE_limitClause) ||
|
|
124
126
|
candidateRule.ruleList.includes(FlinkSqlParser.RULE_whenClause) ||
|
|
125
|
-
candidateRule.ruleList.includes(FlinkSqlParser.RULE_havingClause)
|
|
127
|
+
candidateRule.ruleList.includes(FlinkSqlParser.RULE_havingClause) ||
|
|
128
|
+
candidateRule.ruleList.includes(FlinkSqlParser.RULE_joinCondition)) {
|
|
126
129
|
syntaxContextType = EntityContextType.COLUMN;
|
|
127
130
|
}
|
|
128
131
|
break;
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
import { HiveSqlParserListener } from '../../lib';
|
|
2
|
-
import { ColumnNameCreateContext, CreateDatabaseStatementContext, CreateFunctionStatementContext, CreateMaterializedViewStatementContext, CreateTableStatementContext, CreateViewStatementContext, DbSchemaNameContext, DbSchemaNameCreateContext, FromInsertStmtContext, FromSelectStmtContext, FunctionNameCreateContext, InsertStmtContext, SelectStatementContext, StatementContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext } from '../../lib/hive/HiveSqlParser';
|
|
2
|
+
import { AtomPartitionedTableFunctionContext, AtomValuesClauseContext, ColumnNameCreateContext, CreateDatabaseStatementContext, CreateFunctionStatementContext, CreateMaterializedViewStatementContext, CreateTableStatementContext, CreateViewStatementContext, DbSchemaNameContext, DbSchemaNameCreateContext, FromInsertStmtContext, FromSelectStmtContext, FunctionNameCreateContext, InsertStmtContext, QueryStatementExpressionContext, SelectExpressionColumnNameContext, SelectListContext, SelectLiteralColumnNameContext, SelectStatementContext, StatementContext, TableAllColumnsContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext } from '../../lib/hive/HiveSqlParser';
|
|
3
3
|
import { EntityCollector } from '../common/entityCollector';
|
|
4
4
|
export declare class HiveEntityCollector extends EntityCollector implements HiveSqlParserListener {
|
|
5
5
|
/** ====== Entity Begin */
|
|
6
6
|
exitTableNameCreate(ctx: TableNameCreateContext): void;
|
|
7
|
+
/** Table Entity Rules */
|
|
7
8
|
exitTableName(ctx: TableNameContext): void;
|
|
9
|
+
/** Virtual Table Entity Rules */
|
|
10
|
+
exitAtomValuesClause(ctx: AtomValuesClauseContext): void;
|
|
11
|
+
/** SubQuery Table Entity Rules */
|
|
12
|
+
exitQueryStatementExpression(ctx: QueryStatementExpressionContext): void;
|
|
13
|
+
/** Partitioned Table Entity Rules */
|
|
14
|
+
exitAtomPartitionedTableFunction(ctx: AtomPartitionedTableFunctionContext): void;
|
|
15
|
+
/** Column Entity Rules */
|
|
8
16
|
exitColumnNameCreate(ctx: ColumnNameCreateContext): void;
|
|
17
|
+
exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
|
|
18
|
+
exitSelectExpressionColumnName(ctx: SelectExpressionColumnNameContext): void;
|
|
19
|
+
exitTableAllColumns(ctx: TableAllColumnsContext): void;
|
|
9
20
|
exitViewNameCreate(ctx: ViewNameCreateContext): void;
|
|
21
|
+
exitSelectList(ctx: SelectListContext): void;
|
|
10
22
|
exitViewName(ctx: ViewNameContext): void;
|
|
11
23
|
exitDbSchemaNameCreate(ctx: DbSchemaNameCreateContext): void;
|
|
12
24
|
exitDbSchemaName(ctx: DbSchemaNameContext): void;
|