dt-sql-parser 4.5.0-beta.3 → 4.5.0
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 +2 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/lib/SQLParserBase.d.ts +13 -1
- package/dist/lib/SQLParserBase.js +40 -5
- package/dist/lib/flink/FlinkSqlParser.d.ts +229 -186
- package/dist/lib/flink/FlinkSqlParser.js +3508 -3156
- package/dist/lib/flink/FlinkSqlParserListener.d.ts +33 -0
- package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +21 -0
- package/dist/lib/generic/GenericSqlLexer.d.ts +143 -0
- package/dist/lib/generic/GenericSqlLexer.js +603 -0
- package/dist/lib/generic/GenericSqlListener.d.ts +1089 -0
- package/dist/lib/generic/GenericSqlListener.js +11 -0
- package/dist/lib/generic/GenericSqlParser.d.ts +1272 -0
- package/dist/lib/generic/GenericSqlParser.js +7641 -0
- package/dist/lib/generic/GenericSqlVisitor.d.ts +684 -0
- package/dist/lib/generic/GenericSqlVisitor.js +12 -0
- package/dist/lib/hive/HiveSqlParser.d.ts +274 -228
- package/dist/lib/hive/HiveSqlParser.js +6304 -5912
- package/dist/lib/hive/HiveSqlParserListener.d.ts +33 -0
- package/dist/lib/hive/HiveSqlParserVisitor.d.ts +21 -0
- package/dist/lib/impala/ImpalaSqlParser.d.ts +145 -103
- package/dist/lib/impala/ImpalaSqlParser.js +3687 -3320
- package/dist/lib/impala/ImpalaSqlParserListener.d.ts +33 -0
- package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +21 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +2 -0
- package/dist/lib/mysql/MySqlParser.d.ts +161 -94
- package/dist/lib/mysql/MySqlParser.js +9959 -9499
- package/dist/lib/mysql/MySqlParserListener.d.ts +79 -5
- package/dist/lib/mysql/MySqlParserVisitor.d.ts +49 -3
- package/dist/lib/postgresql/PostgreSqlParser.d.ts +108 -71
- package/dist/lib/postgresql/PostgreSqlParser.js +13330 -10388
- package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +48 -0
- package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +30 -0
- package/dist/lib/spark/SparkSqlParser.d.ts +186 -146
- package/dist/lib/spark/SparkSqlParser.js +5368 -5095
- package/dist/lib/spark/SparkSqlParserListener.d.ts +33 -0
- package/dist/lib/spark/SparkSqlParserVisitor.d.ts +21 -0
- package/dist/lib/trino/TrinoSqlLexer.d.ts +297 -296
- package/dist/lib/trino/TrinoSqlLexer.js +1451 -1445
- package/dist/lib/trino/TrinoSqlListener.d.ts +13 -0
- package/dist/lib/trino/TrinoSqlParser.d.ts +308 -297
- package/dist/lib/trino/TrinoSqlParser.js +2381 -2300
- package/dist/lib/trino/TrinoSqlVisitor.d.ts +8 -0
- package/dist/parser/common/basicSQL.d.ts +5 -5
- package/dist/parser/common/basicSQL.js +3 -3
- package/dist/parser/common/entityCollector.js +14 -2
- package/dist/parser/flink/index.js +5 -2
- package/dist/parser/generic/genericEntityCollector.d.ts +30 -0
- package/dist/parser/generic/genericEntityCollector.js +116 -0
- package/dist/parser/generic/genericErrorListener.d.ts +6 -0
- package/dist/parser/generic/genericErrorListener.js +56 -0
- package/dist/parser/generic/genericSemanticContextCollector.d.ts +9 -0
- package/dist/parser/generic/genericSemanticContextCollector.js +14 -0
- package/dist/parser/generic/genericSplitListener.d.ts +6 -0
- package/dist/parser/generic/genericSplitListener.js +6 -0
- package/dist/parser/generic/index.d.ts +33 -0
- package/dist/parser/generic/index.js +94 -0
- package/dist/parser/index.d.ts +1 -0
- package/dist/parser/index.js +1 -0
- package/dist/parser/mysql/index.js +3 -1
- package/dist/parser/mysql/mysqlEntityCollector.d.ts +2 -1
- package/dist/parser/mysql/mysqlEntityCollector.js +13 -3
- package/dist/parser/mysql/mysqlErrorListener.js +2 -0
- package/dist/parser/postgresql/postgreEntityCollector.d.ts +3 -1
- package/dist/parser/postgresql/postgreEntityCollector.js +13 -0
- package/dist/parser/spark/index.js +3 -1
- package/package.json +1 -1
|
@@ -223,6 +223,7 @@ import { NullLiteralContext } from "./TrinoSqlParser.js";
|
|
|
223
223
|
import { RowConstructorContext } from "./TrinoSqlParser.js";
|
|
224
224
|
import { SubscriptContext } from "./TrinoSqlParser.js";
|
|
225
225
|
import { JsonExistsContext } from "./TrinoSqlParser.js";
|
|
226
|
+
import { CoalesceContext } from "./TrinoSqlParser.js";
|
|
226
227
|
import { CurrentPathContext } from "./TrinoSqlParser.js";
|
|
227
228
|
import { SubqueryExpressionContext } from "./TrinoSqlParser.js";
|
|
228
229
|
import { BinaryLiteralContext } from "./TrinoSqlParser.js";
|
|
@@ -1888,6 +1889,13 @@ export declare class TrinoSqlVisitor<Result> extends AbstractParseTreeVisitor<Re
|
|
|
1888
1889
|
* @return the visitor result
|
|
1889
1890
|
*/
|
|
1890
1891
|
visitJsonExists?: (ctx: JsonExistsContext) => Result;
|
|
1892
|
+
/**
|
|
1893
|
+
* Visit a parse tree produced by the `coalesce`
|
|
1894
|
+
* labeled alternative in `TrinoSqlParser.primaryExpression`.
|
|
1895
|
+
* @param ctx the parse tree
|
|
1896
|
+
* @return the visitor result
|
|
1897
|
+
*/
|
|
1898
|
+
visitCoalesce?: (ctx: CoalesceContext) => Result;
|
|
1891
1899
|
/**
|
|
1892
1900
|
* Visit a parse tree produced by the `currentPath`
|
|
1893
1901
|
* labeled alternative in `TrinoSqlParser.primaryExpression`.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { Lexer, Token, CommonTokenStream, CharStream, ParserRuleContext, ParseTreeListener, ANTLRErrorListener, Parser } from 'antlr4ng';
|
|
2
1
|
import { CandidatesCollection } from 'antlr4-c3';
|
|
2
|
+
import { ANTLRErrorListener, CharStream, CommonTokenStream, Lexer, Parser, ParserRuleContext, ParseTreeListener, Token } from 'antlr4ng';
|
|
3
3
|
import { SQLParserBase } from '../../lib/SQLParserBase';
|
|
4
|
-
import { TextSlice } from './textAndWord';
|
|
5
|
-
import { CaretPosition, LOCALE_TYPE, SemanticCollectOptions, Suggestions } from './types';
|
|
6
|
-
import { ParseError, ErrorListener } from './parseErrorListener';
|
|
7
|
-
import type { SplitListener } from './splitListener';
|
|
8
4
|
import type { EntityCollector } from './entityCollector';
|
|
9
5
|
import { EntityContext } from './entityCollector';
|
|
6
|
+
import { ErrorListener, ParseError } from './parseErrorListener';
|
|
10
7
|
import SemanticContextCollector from './semanticContextCollector';
|
|
8
|
+
import type { SplitListener } from './splitListener';
|
|
9
|
+
import { TextSlice } from './textAndWord';
|
|
10
|
+
import { CaretPosition, LOCALE_TYPE, SemanticCollectOptions, Suggestions } from './types';
|
|
11
11
|
export declare const SQL_SPLIT_SYMBOL_TEXT = ";";
|
|
12
12
|
/**
|
|
13
13
|
* Basic SQL class, every sql needs extends it.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { CharStreams, CommonTokenStream, ParseTreeWalker, PredictionMode, } from 'antlr4ng';
|
|
2
1
|
import { CodeCompletionCore } from 'antlr4-c3';
|
|
2
|
+
import { CharStreams, CommonTokenStream, ParseTreeWalker, PredictionMode, } from 'antlr4ng';
|
|
3
|
+
import { ErrorStrategy } from './errorStrategy';
|
|
3
4
|
import { findCaretTokenIndex } from './findCaretTokenIndex';
|
|
4
5
|
import { ctxToText, tokenToWord } from './textAndWord';
|
|
5
|
-
import { ErrorStrategy } from './errorStrategy';
|
|
6
6
|
export const SQL_SPLIT_SYMBOL_TEXT = ';';
|
|
7
7
|
/**
|
|
8
8
|
* Basic SQL class, every sql needs extends it.
|
|
@@ -431,7 +431,7 @@ export class BasicSQL {
|
|
|
431
431
|
const core = new CodeCompletionCore(sqlParserIns);
|
|
432
432
|
core.preferredRules = this.preferredRules;
|
|
433
433
|
// core.showRuleStack = true;
|
|
434
|
-
//
|
|
434
|
+
// core.showResult = true;
|
|
435
435
|
const candidates = core.collectCandidates(caretTokenIndex, parseTree);
|
|
436
436
|
const originalSuggestions = this.processCandidates(candidates, allTokens, caretTokenIndex);
|
|
437
437
|
const syntaxSuggestions = originalSuggestions.syntax.map((syntaxCtx) => {
|
|
@@ -436,8 +436,20 @@ export class EntityCollector {
|
|
|
436
436
|
}
|
|
437
437
|
else {
|
|
438
438
|
// Do not collect column and queryResult entities if they are not inside a select statement
|
|
439
|
-
|
|
440
|
-
|
|
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
|
+
});
|
|
441
453
|
}
|
|
442
454
|
}
|
|
443
455
|
combineQueryResultStmtEntities(stmtContext, entitiesInsideStmt) {
|
|
@@ -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;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { GenericSqlListener } from '../../lib/generic/GenericSqlListener';
|
|
2
|
+
import { AlterTableContext, ColumnDefinitionContext, ColumnRefContext, CreateTableContext, DeleteContext, DropTableContext, InsertContext, QuerySpecificationContext, QueryStatementContext, SelectItemContext, SingleStatementContext, TableNameContext, TableNameCreateContext, UpdateContext } from '../../lib/generic/GenericSqlParser';
|
|
3
|
+
import { EntityCollector } from '../common/entityCollector';
|
|
4
|
+
export declare class GenericEntityCollector extends EntityCollector implements GenericSqlListener {
|
|
5
|
+
/** ====== Entity Begin */
|
|
6
|
+
exitTableName(ctx: TableNameContext): void;
|
|
7
|
+
exitTableNameCreate(ctx: TableNameCreateContext): void;
|
|
8
|
+
exitColumnRef(ctx: ColumnRefContext): void;
|
|
9
|
+
exitColumnDefinition(ctx: ColumnDefinitionContext): void;
|
|
10
|
+
exitQuerySpecification(ctx: QuerySpecificationContext): void;
|
|
11
|
+
exitSelectItem(ctx: SelectItemContext): void;
|
|
12
|
+
private isSimpleColumnReference;
|
|
13
|
+
/** ===== Statement begin */
|
|
14
|
+
enterSingleStatement(ctx: SingleStatementContext): void;
|
|
15
|
+
exitSingleStatement(ctx: SingleStatementContext): void;
|
|
16
|
+
enterCreateTable(ctx: CreateTableContext): void;
|
|
17
|
+
exitCreateTable(ctx: CreateTableContext): void;
|
|
18
|
+
enterQueryStatement(ctx: QueryStatementContext): void;
|
|
19
|
+
exitQueryStatement(ctx: QueryStatementContext): void;
|
|
20
|
+
enterInsert(ctx: InsertContext): void;
|
|
21
|
+
exitInsert(ctx: InsertContext): void;
|
|
22
|
+
enterUpdate(ctx: UpdateContext): void;
|
|
23
|
+
exitUpdate(ctx: UpdateContext): void;
|
|
24
|
+
enterDelete(ctx: DeleteContext): void;
|
|
25
|
+
exitDelete(ctx: DeleteContext): void;
|
|
26
|
+
enterAlterTable(ctx: AlterTableContext): void;
|
|
27
|
+
exitAlterTable(ctx: AlterTableContext): void;
|
|
28
|
+
enterDropTable(ctx: DropTableContext): void;
|
|
29
|
+
exitDropTable(ctx: DropTableContext): void;
|
|
30
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { ColumnDefinitionContext, CreateTableStatementContext, SelectItemContext, } from '../../lib/generic/GenericSqlParser';
|
|
2
|
+
import { AttrName, ColumnDeclareType, EntityCollector, StmtContextType, TableDeclareType, } from '../common/entityCollector';
|
|
3
|
+
import { EntityContextType } from '../common/types';
|
|
4
|
+
export class GenericEntityCollector extends EntityCollector {
|
|
5
|
+
/** ====== Entity Begin */
|
|
6
|
+
exitTableName(ctx) {
|
|
7
|
+
this.pushEntity(ctx, EntityContextType.TABLE, [], {
|
|
8
|
+
declareType: TableDeclareType.LITERAL,
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
exitTableNameCreate(ctx) {
|
|
12
|
+
this.pushEntity(ctx, EntityContextType.TABLE_CREATE, [
|
|
13
|
+
{
|
|
14
|
+
attrName: AttrName.comment,
|
|
15
|
+
endContextList: [CreateTableStatementContext.name],
|
|
16
|
+
},
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
exitColumnRef(ctx) {
|
|
20
|
+
this.pushEntity(ctx, EntityContextType.COLUMN);
|
|
21
|
+
}
|
|
22
|
+
exitColumnDefinition(ctx) {
|
|
23
|
+
this.pushEntity(ctx, EntityContextType.COLUMN_CREATE, [
|
|
24
|
+
{
|
|
25
|
+
attrName: AttrName.colType,
|
|
26
|
+
endContextList: [ColumnDefinitionContext.name],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
attrName: AttrName.comment,
|
|
30
|
+
endContextList: [ColumnDefinitionContext.name],
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
exitQuerySpecification(ctx) {
|
|
35
|
+
this.pushEntity(ctx, EntityContextType.QUERY_RESULT);
|
|
36
|
+
}
|
|
37
|
+
exitSelectItem(ctx) {
|
|
38
|
+
if (ctx.ASTERISK()) {
|
|
39
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
40
|
+
declareType: ColumnDeclareType.ALL,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const isSimpleColumn = this.isSimpleColumnReference(ctx);
|
|
45
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
46
|
+
{
|
|
47
|
+
attrName: AttrName.alias,
|
|
48
|
+
endContextList: [SelectItemContext.name],
|
|
49
|
+
},
|
|
50
|
+
], {
|
|
51
|
+
declareType: isSimpleColumn
|
|
52
|
+
? ColumnDeclareType.LITERAL
|
|
53
|
+
: ColumnDeclareType.EXPRESSION,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
isSimpleColumnReference(ctx) {
|
|
58
|
+
const text = ctx.getText();
|
|
59
|
+
// Simple column reference: no parentheses, no operators, no spaces
|
|
60
|
+
return (!text.includes('(') &&
|
|
61
|
+
!text.includes(' ') &&
|
|
62
|
+
!text.includes('+') &&
|
|
63
|
+
!text.includes('-') &&
|
|
64
|
+
!text.includes('*') &&
|
|
65
|
+
!text.includes('/'));
|
|
66
|
+
}
|
|
67
|
+
/** ===== Statement begin */
|
|
68
|
+
enterSingleStatement(ctx) {
|
|
69
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
70
|
+
}
|
|
71
|
+
exitSingleStatement(ctx) {
|
|
72
|
+
this.popStmt();
|
|
73
|
+
}
|
|
74
|
+
enterCreateTable(ctx) {
|
|
75
|
+
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
|
76
|
+
}
|
|
77
|
+
exitCreateTable(ctx) {
|
|
78
|
+
this.popStmt();
|
|
79
|
+
}
|
|
80
|
+
enterQueryStatement(ctx) {
|
|
81
|
+
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
|
82
|
+
}
|
|
83
|
+
exitQueryStatement(ctx) {
|
|
84
|
+
this.popStmt();
|
|
85
|
+
}
|
|
86
|
+
enterInsert(ctx) {
|
|
87
|
+
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
|
88
|
+
}
|
|
89
|
+
exitInsert(ctx) {
|
|
90
|
+
this.popStmt();
|
|
91
|
+
}
|
|
92
|
+
enterUpdate(ctx) {
|
|
93
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
94
|
+
}
|
|
95
|
+
exitUpdate(ctx) {
|
|
96
|
+
this.popStmt();
|
|
97
|
+
}
|
|
98
|
+
enterDelete(ctx) {
|
|
99
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
100
|
+
}
|
|
101
|
+
exitDelete(ctx) {
|
|
102
|
+
this.popStmt();
|
|
103
|
+
}
|
|
104
|
+
enterAlterTable(ctx) {
|
|
105
|
+
this.pushStmt(ctx, StmtContextType.ALTER_TABLE_STMT);
|
|
106
|
+
}
|
|
107
|
+
exitAlterTable(ctx) {
|
|
108
|
+
this.popStmt();
|
|
109
|
+
}
|
|
110
|
+
enterDropTable(ctx) {
|
|
111
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
112
|
+
}
|
|
113
|
+
exitDropTable(ctx) {
|
|
114
|
+
this.popStmt();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { CodeCompletionCore } from 'antlr4-c3';
|
|
2
|
+
import { GenericSqlParser } from '../../lib/generic/GenericSqlParser';
|
|
3
|
+
import { ParseErrorListener } from '../common/parseErrorListener';
|
|
4
|
+
export class GenericErrorListener extends ParseErrorListener {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.objectNames = new Map([
|
|
8
|
+
[GenericSqlParser.RULE_tableName, 'table'],
|
|
9
|
+
[GenericSqlParser.RULE_tableNameCreate, 'table'],
|
|
10
|
+
[GenericSqlParser.RULE_columnRef, 'column'],
|
|
11
|
+
]);
|
|
12
|
+
}
|
|
13
|
+
getExpectedText(parser, token) {
|
|
14
|
+
var _a;
|
|
15
|
+
let expectedText = '';
|
|
16
|
+
const input = this.parserContext.getParsedInput();
|
|
17
|
+
let currentContext = (_a = parser.context) !== null && _a !== void 0 ? _a : undefined;
|
|
18
|
+
while (currentContext === null || currentContext === void 0 ? void 0 : currentContext.parent) {
|
|
19
|
+
currentContext = currentContext.parent;
|
|
20
|
+
}
|
|
21
|
+
const parserInfo = this.parserContext.getMinimumParserInfo(input, token.tokenIndex, currentContext);
|
|
22
|
+
if (!parserInfo)
|
|
23
|
+
return '';
|
|
24
|
+
const { parser: c3Parser, newTokenIndex, parseTree: c3Context } = parserInfo;
|
|
25
|
+
const core = new CodeCompletionCore(c3Parser);
|
|
26
|
+
core.preferredRules = this.preferredRules;
|
|
27
|
+
const candidates = core.collectCandidates(newTokenIndex, c3Context);
|
|
28
|
+
if (candidates.rules.size) {
|
|
29
|
+
const result = [];
|
|
30
|
+
for (const candidate of candidates.rules) {
|
|
31
|
+
const [ruleType] = candidate;
|
|
32
|
+
const name = this.objectNames.get(ruleType);
|
|
33
|
+
switch (ruleType) {
|
|
34
|
+
case GenericSqlParser.RULE_tableName:
|
|
35
|
+
case GenericSqlParser.RULE_columnRef: {
|
|
36
|
+
if (name && !result.includes(`{existing}${name}`)) {
|
|
37
|
+
result.push(`{existing}${name}`);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case GenericSqlParser.RULE_tableNameCreate: {
|
|
42
|
+
if (name && !result.includes(`{new}${name}`)) {
|
|
43
|
+
result.push(`{new}${name}`);
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
expectedText = result.join('{or}');
|
|
50
|
+
}
|
|
51
|
+
if (candidates.tokens.size) {
|
|
52
|
+
expectedText += expectedText ? '{orKeyword}' : '{keyword}';
|
|
53
|
+
}
|
|
54
|
+
return expectedText;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { GenericSqlListener } from '../../lib/generic/GenericSqlListener';
|
|
2
|
+
import { StatementsContext } from '../../lib/generic/GenericSqlParser';
|
|
3
|
+
import SemanticContextCollector from '../common/semanticContextCollector';
|
|
4
|
+
declare class GenericSemanticContextCollector extends SemanticContextCollector implements GenericSqlListener {
|
|
5
|
+
getWhiteSpaceRuleType(): number;
|
|
6
|
+
getStatementRuleType(): number;
|
|
7
|
+
enterStatements(ctx: StatementsContext): void;
|
|
8
|
+
}
|
|
9
|
+
export { GenericSemanticContextCollector };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GenericSqlParser } from '../../lib/generic/GenericSqlParser';
|
|
2
|
+
import SemanticContextCollector from '../common/semanticContextCollector';
|
|
3
|
+
class GenericSemanticContextCollector extends SemanticContextCollector {
|
|
4
|
+
getWhiteSpaceRuleType() {
|
|
5
|
+
return GenericSqlParser.WHITE_SPACE;
|
|
6
|
+
}
|
|
7
|
+
getStatementRuleType() {
|
|
8
|
+
return GenericSqlParser.RULE_statements;
|
|
9
|
+
}
|
|
10
|
+
enterStatements(ctx) {
|
|
11
|
+
this.visitStatement(ctx);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export { GenericSemanticContextCollector };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { SingleStatementContext } from '../../lib/generic/GenericSqlParser';
|
|
2
|
+
import { GenericSqlListener } from '../../lib/generic/GenericSqlListener';
|
|
3
|
+
import { SplitListener } from '../common/splitListener';
|
|
4
|
+
export declare class GenericSplitListener extends SplitListener<SingleStatementContext> implements GenericSqlListener {
|
|
5
|
+
exitSingleStatement(ctx: SingleStatementContext): void;
|
|
6
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { CandidatesCollection } from 'antlr4-c3';
|
|
2
|
+
import { CharStream, CommonTokenStream, Token } from 'antlr4ng';
|
|
3
|
+
import { GenericSqlLexer } from '../../lib/generic/GenericSqlLexer';
|
|
4
|
+
import { GenericSqlParser, ProgramContext } from '../../lib/generic/GenericSqlParser';
|
|
5
|
+
import { BasicSQL } from '../common/basicSQL';
|
|
6
|
+
import { Suggestions, CaretPosition, SemanticCollectOptions } from '../common/types';
|
|
7
|
+
import { ErrorListener, ParseError } from '../common/parseErrorListener';
|
|
8
|
+
import { GenericEntityCollector } from './genericEntityCollector';
|
|
9
|
+
import { GenericErrorListener } from './genericErrorListener';
|
|
10
|
+
import { GenericSplitListener } from './genericSplitListener';
|
|
11
|
+
import { GenericSemanticContextCollector } from './genericSemanticContextCollector';
|
|
12
|
+
export { GenericEntityCollector, GenericSplitListener };
|
|
13
|
+
export interface GenericSQLOptions {
|
|
14
|
+
/** Enable or disable diagnostics (parse error collection). Defaults to true. */
|
|
15
|
+
diagnostics?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare class GenericSQL extends BasicSQL<GenericSqlLexer, ProgramContext, GenericSqlParser> {
|
|
18
|
+
private _diagnostics;
|
|
19
|
+
constructor(options?: GenericSQLOptions);
|
|
20
|
+
protected createLexerFromCharStream(charStreams: CharStream): GenericSqlLexer;
|
|
21
|
+
validate(input: string): ParseError[];
|
|
22
|
+
protected createParserFromTokenStream(tokenStream: CommonTokenStream): GenericSqlParser;
|
|
23
|
+
/**
|
|
24
|
+
* The rules that keywords you don't want to be suggested.
|
|
25
|
+
*/
|
|
26
|
+
protected excludeKeywordRules: Set<number>;
|
|
27
|
+
protected preferredRules: Set<number>;
|
|
28
|
+
protected get splitListener(): GenericSplitListener;
|
|
29
|
+
protected createErrorListener(_errorListener: ErrorListener): GenericErrorListener;
|
|
30
|
+
protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number): GenericEntityCollector;
|
|
31
|
+
protected createSemanticContextCollector(input: string, caretPosition: CaretPosition, allTokens: Token[], options?: SemanticCollectOptions): GenericSemanticContextCollector;
|
|
32
|
+
protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
|
|
33
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { processTokenCandidates } from '../common/tokenUtils';
|
|
2
|
+
import { GenericSqlLexer } from '../../lib/generic/GenericSqlLexer';
|
|
3
|
+
import { GenericSqlParser } from '../../lib/generic/GenericSqlParser';
|
|
4
|
+
import { BasicSQL } from '../common/basicSQL';
|
|
5
|
+
import { EntityContextType, } from '../common/types';
|
|
6
|
+
import { GenericEntityCollector } from './genericEntityCollector';
|
|
7
|
+
import { GenericErrorListener } from './genericErrorListener';
|
|
8
|
+
import { GenericSplitListener } from './genericSplitListener';
|
|
9
|
+
import { GenericSemanticContextCollector } from './genericSemanticContextCollector';
|
|
10
|
+
export { GenericEntityCollector, GenericSplitListener };
|
|
11
|
+
export class GenericSQL extends BasicSQL {
|
|
12
|
+
constructor(options) {
|
|
13
|
+
super();
|
|
14
|
+
/**
|
|
15
|
+
* The rules that keywords you don't want to be suggested.
|
|
16
|
+
*/
|
|
17
|
+
this.excludeKeywordRules = new Set([GenericSqlParser.RULE_nonReserved]);
|
|
18
|
+
this.preferredRules = new Set([
|
|
19
|
+
GenericSqlParser.RULE_tableName,
|
|
20
|
+
GenericSqlParser.RULE_tableNameCreate,
|
|
21
|
+
GenericSqlParser.RULE_columnRef,
|
|
22
|
+
...this.excludeKeywordRules,
|
|
23
|
+
]);
|
|
24
|
+
this._diagnostics = (options === null || options === void 0 ? void 0 : options.diagnostics) !== false;
|
|
25
|
+
}
|
|
26
|
+
createLexerFromCharStream(charStreams) {
|
|
27
|
+
return new GenericSqlLexer(charStreams);
|
|
28
|
+
}
|
|
29
|
+
validate(input) {
|
|
30
|
+
if (!this._diagnostics) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
return super.validate(input);
|
|
34
|
+
}
|
|
35
|
+
createParserFromTokenStream(tokenStream) {
|
|
36
|
+
return new GenericSqlParser(tokenStream);
|
|
37
|
+
}
|
|
38
|
+
get splitListener() {
|
|
39
|
+
return new GenericSplitListener();
|
|
40
|
+
}
|
|
41
|
+
createErrorListener(_errorListener) {
|
|
42
|
+
const parserContext = this;
|
|
43
|
+
return new GenericErrorListener(_errorListener, parserContext, this.preferredRules);
|
|
44
|
+
}
|
|
45
|
+
createEntityCollector(input, allTokens, caretTokenIndex) {
|
|
46
|
+
return new GenericEntityCollector(input, allTokens, caretTokenIndex);
|
|
47
|
+
}
|
|
48
|
+
createSemanticContextCollector(input, caretPosition, allTokens, options) {
|
|
49
|
+
return new GenericSemanticContextCollector(input, caretPosition, allTokens, options);
|
|
50
|
+
}
|
|
51
|
+
processCandidates(candidates, allTokens, caretTokenIndex) {
|
|
52
|
+
const originalSyntaxSuggestions = [];
|
|
53
|
+
const keywords = [];
|
|
54
|
+
for (const candidate of candidates.rules) {
|
|
55
|
+
const [ruleType, candidateRule] = candidate;
|
|
56
|
+
const tokenRanges = allTokens.slice(candidateRule.startTokenIndex, caretTokenIndex + 1);
|
|
57
|
+
let syntaxContextType = void 0;
|
|
58
|
+
switch (ruleType) {
|
|
59
|
+
case GenericSqlParser.RULE_tableName: {
|
|
60
|
+
syntaxContextType = EntityContextType.TABLE;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case GenericSqlParser.RULE_tableNameCreate: {
|
|
64
|
+
syntaxContextType = EntityContextType.TABLE_CREATE;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
case GenericSqlParser.RULE_columnRef: {
|
|
68
|
+
syntaxContextType = EntityContextType.COLUMN;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
default:
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
if (syntaxContextType &&
|
|
75
|
+
!originalSyntaxSuggestions.some((syn) => {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
return syn.syntaxContextType === syntaxContextType &&
|
|
78
|
+
((_a = syn.wordRanges.map((wordRange) => wordRange.text)) === null || _a === void 0 ? void 0 : _a.join(',')) ===
|
|
79
|
+
((_b = tokenRanges.map((tokenRange) => tokenRange.text)) === null || _b === void 0 ? void 0 : _b.join(','));
|
|
80
|
+
})) {
|
|
81
|
+
originalSyntaxSuggestions.push({
|
|
82
|
+
syntaxContextType,
|
|
83
|
+
wordRanges: tokenRanges,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const processedKeywords = processTokenCandidates(this._parser, candidates.tokens);
|
|
88
|
+
keywords.push(...processedKeywords);
|
|
89
|
+
return {
|
|
90
|
+
syntax: originalSyntaxSuggestions,
|
|
91
|
+
keywords,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
package/dist/parser/index.d.ts
CHANGED
package/dist/parser/index.js
CHANGED
|
@@ -25,6 +25,7 @@ export class MySQL extends BasicSQL {
|
|
|
25
25
|
MySqlParser.RULE_functionName,
|
|
26
26
|
MySqlParser.RULE_functionNameCreate,
|
|
27
27
|
MySqlParser.RULE_columnName,
|
|
28
|
+
MySqlParser.RULE_columnNamePath,
|
|
28
29
|
MySqlParser.RULE_columnNameCreate,
|
|
29
30
|
...this.excludeKeywordRules,
|
|
30
31
|
]);
|
|
@@ -88,7 +89,8 @@ export class MySQL extends BasicSQL {
|
|
|
88
89
|
syntaxContextType = EntityContextType.FUNCTION_CREATE;
|
|
89
90
|
break;
|
|
90
91
|
}
|
|
91
|
-
case MySqlParser.RULE_columnName:
|
|
92
|
+
case MySqlParser.RULE_columnName:
|
|
93
|
+
case MySqlParser.RULE_columnNamePath: {
|
|
92
94
|
syntaxContextType = EntityContextType.COLUMN;
|
|
93
95
|
break;
|
|
94
96
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnCreateTableContext, ColumnNameCreateContext, CopyCreateTableContext, CreateDatabaseContext, CreateFunctionContext, CreateFunctionLoadableContext, CreateViewContext, DatabaseNameContext, DatabaseNameCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryCreateTableContext, SelectExpressionElementContext, SelectStatementContext, SingleStatementContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext, TableAllColumnsContext,
|
|
1
|
+
import { ColumnCreateTableContext, ColumnNameCreateContext, CopyCreateTableContext, CreateDatabaseContext, CreateFunctionContext, CreateFunctionLoadableContext, CreateViewContext, DatabaseNameContext, DatabaseNameCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryCreateTableContext, SelectElementsContext, SelectExpressionElementContext, SelectLiteralColumnNameContext, SelectStatementContext, SingleStatementContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext, TableAllColumnsContext, AtomSubQueryTableSourceContext, PureAllColumnsContext, SelectElement_dot_emptyContext } from '../../lib/mysql/MySqlParser';
|
|
2
2
|
import type { MySqlParserListener } from '../../lib/mysql/MySqlParserListener';
|
|
3
3
|
import { EntityCollector } from '../common/entityCollector';
|
|
4
4
|
export declare class MySqlEntityCollector extends EntityCollector implements MySqlParserListener {
|
|
@@ -18,6 +18,7 @@ export declare class MySqlEntityCollector extends EntityCollector implements MyS
|
|
|
18
18
|
exitTableAllColumns(ctx: TableAllColumnsContext): void;
|
|
19
19
|
exitPureAllColumns(ctx: PureAllColumnsContext): void;
|
|
20
20
|
exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
|
|
21
|
+
exitSelectElement_dot_empty(ctx: SelectElement_dot_emptyContext): void;
|
|
21
22
|
exitSelectExpressionElement(ctx: SelectExpressionElementContext): void;
|
|
22
23
|
/** ===== Statement begin */
|
|
23
24
|
enterSingleStatement(ctx: SingleStatementContext): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ColumnCreateTableContext, CreateDefinitionContext, CreateFunctionContext,
|
|
1
|
+
import { ColumnCreateTableContext, CreateDefinitionContext, CreateFunctionContext, TableSourceItemContext, AtomTableItemContext, SubqueryTableItemContext, SelectElement_labelContext, SelectElement_exprContext, } from '../../lib/mysql/MySqlParser';
|
|
2
2
|
import { AttrName, ColumnDeclareType, EntityCollector, StmtContextType, TableDeclareType, } from '../common/entityCollector';
|
|
3
3
|
import { EntityContextType } from '../common/types';
|
|
4
4
|
export class MySqlEntityCollector extends EntityCollector {
|
|
@@ -79,20 +79,30 @@ export class MySqlEntityCollector extends EntityCollector {
|
|
|
79
79
|
});
|
|
80
80
|
}
|
|
81
81
|
exitSelectLiteralColumnName(ctx) {
|
|
82
|
+
// Handle empty column case (e.g., "select from")
|
|
83
|
+
// When emptyColumn matches, the context has no actual tokens
|
|
84
|
+
if (!ctx.start || !ctx.stop || ctx.start.start > ctx.stop.stop) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
82
87
|
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
83
88
|
{
|
|
84
89
|
attrName: AttrName.alias,
|
|
85
|
-
endContextList: [
|
|
90
|
+
endContextList: [SelectElement_labelContext.name],
|
|
86
91
|
},
|
|
87
92
|
], {
|
|
88
93
|
declareType: ColumnDeclareType.LITERAL,
|
|
89
94
|
});
|
|
90
95
|
}
|
|
96
|
+
exitSelectElement_dot_empty(ctx) {
|
|
97
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
98
|
+
declareType: ColumnDeclareType.LITERAL,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
91
101
|
exitSelectExpressionElement(ctx) {
|
|
92
102
|
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
93
103
|
{
|
|
94
104
|
attrName: AttrName.alias,
|
|
95
|
-
endContextList: [
|
|
105
|
+
endContextList: [SelectElement_exprContext.name],
|
|
96
106
|
},
|
|
97
107
|
], {
|
|
98
108
|
declareType: ColumnDeclareType.EXPRESSION,
|
|
@@ -14,6 +14,7 @@ export class MysqlErrorListener extends ParseErrorListener {
|
|
|
14
14
|
[MySqlParser.RULE_functionName, 'function'],
|
|
15
15
|
[MySqlParser.RULE_functionNameCreate, 'function'],
|
|
16
16
|
[MySqlParser.RULE_columnName, 'column'],
|
|
17
|
+
[MySqlParser.RULE_columnNamePath, 'column'],
|
|
17
18
|
[MySqlParser.RULE_columnNameCreate, 'column'],
|
|
18
19
|
]);
|
|
19
20
|
}
|
|
@@ -48,6 +49,7 @@ export class MysqlErrorListener extends ParseErrorListener {
|
|
|
48
49
|
case MySqlParser.RULE_tableName:
|
|
49
50
|
case MySqlParser.RULE_functionName:
|
|
50
51
|
case MySqlParser.RULE_viewName:
|
|
52
|
+
case MySqlParser.RULE_columnNamePath:
|
|
51
53
|
case MySqlParser.RULE_columnName: {
|
|
52
54
|
if (!result.includes(`{existing}${name}`)) {
|
|
53
55
|
result.push(`{existing}${name}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AlterTableStmtContext, type ColumnCreateTableContext, type ColumnNameCreateContext, type CreateDatabaseContext, type CreateForeignTableContext, type CreateFunctionStmtContext, type CreateMaterializedViewContext, type CreatePartitionForeignTableContext, type CreateViewContext, type DatabaseNameContext, type DatabaseNameCreateContext, type FunctionNameCreateContext, type InsertStatementContext, type ProcedureNameContext, type ProcedureNameCreateContext, type QueryCreateTableContext, SelectExpressionColumnNameContext, SelectLiteralColumnNameContext, type SelectStatementContext, type SingleStmtContext, TableAllColumnsContext, type TableNameContext, type TableNameCreateContext,
|
|
1
|
+
import { type AlterTableStmtContext, type ColumnCreateTableContext, type ColumnNameCreateContext, type CreateDatabaseContext, type CreateForeignTableContext, type CreateFunctionStmtContext, type CreateMaterializedViewContext, type CreatePartitionForeignTableContext, type CreateViewContext, type DatabaseNameContext, type DatabaseNameCreateContext, FuncTableContext, type FunctionNameCreateContext, type InsertStatementContext, type ProcedureNameContext, type ProcedureNameCreateContext, type QueryCreateTableContext, SelectExpressionColumnNameContext, SelectLiteralColumnNameContext, SelectNoParensContext, type SelectStatementContext, SelectWithParensContext, type SingleStmtContext, TableAllColumnsContext, type TableNameContext, type TableNameCreateContext, Target_dot_emptyContext, Target_emptyContext, TargetListContext, type ViewNameContext, type ViewNameCreateContext, XmlTableContext } from '../../lib/postgresql/PostgreSqlParser';
|
|
2
2
|
import type { PostgreSqlParserListener } from '../../lib/postgresql/PostgreSqlParserListener';
|
|
3
3
|
import { EntityCollector } from '../common/entityCollector';
|
|
4
4
|
export declare class PostgreSqlEntityCollector extends EntityCollector implements PostgreSqlParserListener {
|
|
@@ -16,6 +16,8 @@ export declare class PostgreSqlEntityCollector extends EntityCollector implement
|
|
|
16
16
|
exitColumnNameCreate(ctx: ColumnNameCreateContext): void;
|
|
17
17
|
exitTargetList(ctx: TargetListContext): void;
|
|
18
18
|
exitTableAllColumns(ctx: TableAllColumnsContext): void;
|
|
19
|
+
exitTarget_empty(ctx: Target_emptyContext): void;
|
|
20
|
+
exitTarget_dot_empty(ctx: Target_dot_emptyContext): void;
|
|
19
21
|
exitSelectExpressionColumnName(ctx: SelectExpressionColumnNameContext): void;
|
|
20
22
|
exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
|
|
21
23
|
exitProcedureName(ctx: ProcedureNameContext): void;
|
|
@@ -81,6 +81,7 @@ export class PostgreSqlEntityCollector extends EntityCollector {
|
|
|
81
81
|
]);
|
|
82
82
|
}
|
|
83
83
|
exitTargetList(ctx) {
|
|
84
|
+
// Only create QUERY_RESULT for targetList that is direct child of simpleSelect
|
|
84
85
|
if (!isChildContextOf(ctx, PostgreSqlParser.RULE_simpleSelect))
|
|
85
86
|
return;
|
|
86
87
|
this.pushEntity(ctx, EntityContextType.QUERY_RESULT);
|
|
@@ -92,6 +93,18 @@ export class PostgreSqlEntityCollector extends EntityCollector {
|
|
|
92
93
|
declareType: ColumnDeclareType.ALL,
|
|
93
94
|
});
|
|
94
95
|
}
|
|
96
|
+
exitTarget_empty(ctx) {
|
|
97
|
+
// Don't create entity for empty column here
|
|
98
|
+
// The targetList will create QUERY_RESULT entity
|
|
99
|
+
// Empty targetEl means the QUERY_RESULT has no columns
|
|
100
|
+
}
|
|
101
|
+
exitTarget_dot_empty(ctx) {
|
|
102
|
+
// Create COLUMN entity for incomplete column reference (e.g., "tb.|")
|
|
103
|
+
// This allows completion to suggest columns from table "tb"
|
|
104
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
105
|
+
declareType: ColumnDeclareType.LITERAL,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
95
108
|
exitSelectExpressionColumnName(ctx) {
|
|
96
109
|
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
97
110
|
{
|