dt-sql-parser 4.5.0-beta.3 → 4.5.1-beta.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/FlinkSqlLexer.d.ts +397 -399
- package/dist/lib/flink/FlinkSqlLexer.js +2489 -2504
- package/dist/lib/flink/FlinkSqlParser.d.ts +617 -726
- package/dist/lib/flink/FlinkSqlParser.js +3605 -4908
- package/dist/lib/flink/FlinkSqlParserListener.d.ts +33 -90
- package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +21 -57
- package/dist/lib/generic/GenericSqlLexer.d.ts +143 -0
- package/dist/lib/generic/GenericSqlLexer.js +603 -0
- package/dist/lib/generic/GenericSqlListener.d.ts +1174 -0
- package/dist/lib/generic/GenericSqlListener.js +11 -0
- package/dist/lib/generic/GenericSqlParser.d.ts +1341 -0
- package/dist/lib/generic/GenericSqlParser.js +8041 -0
- package/dist/lib/generic/GenericSqlVisitor.d.ts +737 -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 +185 -145
- package/dist/lib/spark/SparkSqlParser.js +5463 -5152
- package/dist/lib/spark/SparkSqlParserListener.d.ts +33 -0
- package/dist/lib/spark/SparkSqlParserVisitor.d.ts +21 -0
- package/dist/parser/common/basicSQL.d.ts +5 -17
- package/dist/parser/common/basicSQL.js +3 -74
- package/dist/parser/common/entityCollector.js +14 -2
- package/dist/parser/flink/index.js +5 -2
- package/dist/parser/generic/genericEntityCollector.d.ts +33 -0
- package/dist/parser/generic/genericEntityCollector.js +124 -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 +109 -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
|
@@ -131,8 +131,10 @@ import { TableNameCreateContext } from "./SparkSqlParser.js";
|
|
|
131
131
|
import { TableNameContext } from "./SparkSqlParser.js";
|
|
132
132
|
import { ViewNameCreateContext } from "./SparkSqlParser.js";
|
|
133
133
|
import { ViewNameContext } from "./SparkSqlParser.js";
|
|
134
|
+
import { EmptyColumnContext } from "./SparkSqlParser.js";
|
|
134
135
|
import { ColumnNameContext } from "./SparkSqlParser.js";
|
|
135
136
|
import { ColumnNamePathContext } from "./SparkSqlParser.js";
|
|
137
|
+
import { ColumnNamePathAllowEmptyContext } from "./SparkSqlParser.js";
|
|
136
138
|
import { ColumnNameSeqContext } from "./SparkSqlParser.js";
|
|
137
139
|
import { ColumnNameCreateContext } from "./SparkSqlParser.js";
|
|
138
140
|
import { IdentifierReferenceContext } from "./SparkSqlParser.js";
|
|
@@ -206,6 +208,7 @@ import { TableAliasContext } from "./SparkSqlParser.js";
|
|
|
206
208
|
import { RowFormatContext } from "./SparkSqlParser.js";
|
|
207
209
|
import { MultipartIdentifierListContext } from "./SparkSqlParser.js";
|
|
208
210
|
import { MultipartIdentifierContext } from "./SparkSqlParser.js";
|
|
211
|
+
import { MultipartIdentifierAllowEmptyContext } from "./SparkSqlParser.js";
|
|
209
212
|
import { MultipartIdentifierPropertyListContext } from "./SparkSqlParser.js";
|
|
210
213
|
import { MultipartIdentifierPropertyContext } from "./SparkSqlParser.js";
|
|
211
214
|
import { TableIdentifierContext } from "./SparkSqlParser.js";
|
|
@@ -1796,6 +1799,16 @@ export declare class SparkSqlParserListener implements ParseTreeListener {
|
|
|
1796
1799
|
* @param ctx the parse tree
|
|
1797
1800
|
*/
|
|
1798
1801
|
exitViewName?: (ctx: ViewNameContext) => void;
|
|
1802
|
+
/**
|
|
1803
|
+
* Enter a parse tree produced by `SparkSqlParser.emptyColumn`.
|
|
1804
|
+
* @param ctx the parse tree
|
|
1805
|
+
*/
|
|
1806
|
+
enterEmptyColumn?: (ctx: EmptyColumnContext) => void;
|
|
1807
|
+
/**
|
|
1808
|
+
* Exit a parse tree produced by `SparkSqlParser.emptyColumn`.
|
|
1809
|
+
* @param ctx the parse tree
|
|
1810
|
+
*/
|
|
1811
|
+
exitEmptyColumn?: (ctx: EmptyColumnContext) => void;
|
|
1799
1812
|
/**
|
|
1800
1813
|
* Enter a parse tree produced by `SparkSqlParser.columnName`.
|
|
1801
1814
|
* @param ctx the parse tree
|
|
@@ -1816,6 +1829,16 @@ export declare class SparkSqlParserListener implements ParseTreeListener {
|
|
|
1816
1829
|
* @param ctx the parse tree
|
|
1817
1830
|
*/
|
|
1818
1831
|
exitColumnNamePath?: (ctx: ColumnNamePathContext) => void;
|
|
1832
|
+
/**
|
|
1833
|
+
* Enter a parse tree produced by `SparkSqlParser.columnNamePathAllowEmpty`.
|
|
1834
|
+
* @param ctx the parse tree
|
|
1835
|
+
*/
|
|
1836
|
+
enterColumnNamePathAllowEmpty?: (ctx: ColumnNamePathAllowEmptyContext) => void;
|
|
1837
|
+
/**
|
|
1838
|
+
* Exit a parse tree produced by `SparkSqlParser.columnNamePathAllowEmpty`.
|
|
1839
|
+
* @param ctx the parse tree
|
|
1840
|
+
*/
|
|
1841
|
+
exitColumnNamePathAllowEmpty?: (ctx: ColumnNamePathAllowEmptyContext) => void;
|
|
1819
1842
|
/**
|
|
1820
1843
|
* Enter a parse tree produced by `SparkSqlParser.columnNameSeq`.
|
|
1821
1844
|
* @param ctx the parse tree
|
|
@@ -2556,6 +2579,16 @@ export declare class SparkSqlParserListener implements ParseTreeListener {
|
|
|
2556
2579
|
* @param ctx the parse tree
|
|
2557
2580
|
*/
|
|
2558
2581
|
exitMultipartIdentifier?: (ctx: MultipartIdentifierContext) => void;
|
|
2582
|
+
/**
|
|
2583
|
+
* Enter a parse tree produced by `SparkSqlParser.multipartIdentifierAllowEmpty`.
|
|
2584
|
+
* @param ctx the parse tree
|
|
2585
|
+
*/
|
|
2586
|
+
enterMultipartIdentifierAllowEmpty?: (ctx: MultipartIdentifierAllowEmptyContext) => void;
|
|
2587
|
+
/**
|
|
2588
|
+
* Exit a parse tree produced by `SparkSqlParser.multipartIdentifierAllowEmpty`.
|
|
2589
|
+
* @param ctx the parse tree
|
|
2590
|
+
*/
|
|
2591
|
+
exitMultipartIdentifierAllowEmpty?: (ctx: MultipartIdentifierAllowEmptyContext) => void;
|
|
2559
2592
|
/**
|
|
2560
2593
|
* Enter a parse tree produced by `SparkSqlParser.multipartIdentifierPropertyList`.
|
|
2561
2594
|
* @param ctx the parse tree
|
|
@@ -131,8 +131,10 @@ import { TableNameCreateContext } from "./SparkSqlParser.js";
|
|
|
131
131
|
import { TableNameContext } from "./SparkSqlParser.js";
|
|
132
132
|
import { ViewNameCreateContext } from "./SparkSqlParser.js";
|
|
133
133
|
import { ViewNameContext } from "./SparkSqlParser.js";
|
|
134
|
+
import { EmptyColumnContext } from "./SparkSqlParser.js";
|
|
134
135
|
import { ColumnNameContext } from "./SparkSqlParser.js";
|
|
135
136
|
import { ColumnNamePathContext } from "./SparkSqlParser.js";
|
|
137
|
+
import { ColumnNamePathAllowEmptyContext } from "./SparkSqlParser.js";
|
|
136
138
|
import { ColumnNameSeqContext } from "./SparkSqlParser.js";
|
|
137
139
|
import { ColumnNameCreateContext } from "./SparkSqlParser.js";
|
|
138
140
|
import { IdentifierReferenceContext } from "./SparkSqlParser.js";
|
|
@@ -206,6 +208,7 @@ import { TableAliasContext } from "./SparkSqlParser.js";
|
|
|
206
208
|
import { RowFormatContext } from "./SparkSqlParser.js";
|
|
207
209
|
import { MultipartIdentifierListContext } from "./SparkSqlParser.js";
|
|
208
210
|
import { MultipartIdentifierContext } from "./SparkSqlParser.js";
|
|
211
|
+
import { MultipartIdentifierAllowEmptyContext } from "./SparkSqlParser.js";
|
|
209
212
|
import { MultipartIdentifierPropertyListContext } from "./SparkSqlParser.js";
|
|
210
213
|
import { MultipartIdentifierPropertyContext } from "./SparkSqlParser.js";
|
|
211
214
|
import { TableIdentifierContext } from "./SparkSqlParser.js";
|
|
@@ -1175,6 +1178,12 @@ export declare class SparkSqlParserVisitor<Result> extends AbstractParseTreeVisi
|
|
|
1175
1178
|
* @return the visitor result
|
|
1176
1179
|
*/
|
|
1177
1180
|
visitViewName?: (ctx: ViewNameContext) => Result;
|
|
1181
|
+
/**
|
|
1182
|
+
* Visit a parse tree produced by `SparkSqlParser.emptyColumn`.
|
|
1183
|
+
* @param ctx the parse tree
|
|
1184
|
+
* @return the visitor result
|
|
1185
|
+
*/
|
|
1186
|
+
visitEmptyColumn?: (ctx: EmptyColumnContext) => Result;
|
|
1178
1187
|
/**
|
|
1179
1188
|
* Visit a parse tree produced by `SparkSqlParser.columnName`.
|
|
1180
1189
|
* @param ctx the parse tree
|
|
@@ -1187,6 +1196,12 @@ export declare class SparkSqlParserVisitor<Result> extends AbstractParseTreeVisi
|
|
|
1187
1196
|
* @return the visitor result
|
|
1188
1197
|
*/
|
|
1189
1198
|
visitColumnNamePath?: (ctx: ColumnNamePathContext) => Result;
|
|
1199
|
+
/**
|
|
1200
|
+
* Visit a parse tree produced by `SparkSqlParser.columnNamePathAllowEmpty`.
|
|
1201
|
+
* @param ctx the parse tree
|
|
1202
|
+
* @return the visitor result
|
|
1203
|
+
*/
|
|
1204
|
+
visitColumnNamePathAllowEmpty?: (ctx: ColumnNamePathAllowEmptyContext) => Result;
|
|
1190
1205
|
/**
|
|
1191
1206
|
* Visit a parse tree produced by `SparkSqlParser.columnNameSeq`.
|
|
1192
1207
|
* @param ctx the parse tree
|
|
@@ -1630,6 +1645,12 @@ export declare class SparkSqlParserVisitor<Result> extends AbstractParseTreeVisi
|
|
|
1630
1645
|
* @return the visitor result
|
|
1631
1646
|
*/
|
|
1632
1647
|
visitMultipartIdentifier?: (ctx: MultipartIdentifierContext) => Result;
|
|
1648
|
+
/**
|
|
1649
|
+
* Visit a parse tree produced by `SparkSqlParser.multipartIdentifierAllowEmpty`.
|
|
1650
|
+
* @param ctx the parse tree
|
|
1651
|
+
* @return the visitor result
|
|
1652
|
+
*/
|
|
1653
|
+
visitMultipartIdentifierAllowEmpty?: (ctx: MultipartIdentifierAllowEmptyContext) => Result;
|
|
1633
1654
|
/**
|
|
1634
1655
|
* Visit a parse tree produced by `SparkSqlParser.multipartIdentifierPropertyList`.
|
|
1635
1656
|
* @param ctx the parse tree
|
|
@@ -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.
|
|
@@ -95,22 +95,10 @@ export declare abstract class BasicSQL<L extends Lexer = Lexer, PRC extends Pars
|
|
|
95
95
|
private parseWithCache;
|
|
96
96
|
/**
|
|
97
97
|
* Validate input string and return syntax errors if exists.
|
|
98
|
-
* When input contains multiple statements separated by semicolons
|
|
99
|
-
* and the initial parse doesn't capture all errors, each statement
|
|
100
|
-
* is validated independently to collect all errors.
|
|
101
98
|
* @param input source string
|
|
102
99
|
* @returns syntax errors
|
|
103
100
|
*/
|
|
104
101
|
validate(input: string): ParseError[];
|
|
105
|
-
/**
|
|
106
|
-
* Validate each statement fragment independently and collect all errors.
|
|
107
|
-
*/
|
|
108
|
-
private validateStatements;
|
|
109
|
-
/**
|
|
110
|
-
* Split input into individual statement strings by semicolons.
|
|
111
|
-
* Handles semicolons inside quoted strings correctly.
|
|
112
|
-
*/
|
|
113
|
-
private splitStatements;
|
|
114
102
|
/**
|
|
115
103
|
* Get the input string that has been parsed.
|
|
116
104
|
*/
|
|
@@ -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.
|
|
@@ -104,84 +104,13 @@ export class BasicSQL {
|
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
106
|
* Validate input string and return syntax errors if exists.
|
|
107
|
-
* When input contains multiple statements separated by semicolons
|
|
108
|
-
* and the initial parse doesn't capture all errors, each statement
|
|
109
|
-
* is validated independently to collect all errors.
|
|
110
107
|
* @param input source string
|
|
111
108
|
* @returns syntax errors
|
|
112
109
|
*/
|
|
113
110
|
validate(input) {
|
|
114
111
|
this.parseWithCache(input);
|
|
115
|
-
if (this._parseErrors.length > 0) {
|
|
116
|
-
const statements = this.splitStatements(input);
|
|
117
|
-
if (statements.length > 1) {
|
|
118
|
-
const splitErrors = this.validateStatements(statements);
|
|
119
|
-
if (splitErrors.length > this._parseErrors.length) {
|
|
120
|
-
this._parseErrors = splitErrors;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
112
|
return this._parseErrors;
|
|
125
113
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Validate each statement fragment independently and collect all errors.
|
|
128
|
-
*/
|
|
129
|
-
validateStatements(statements) {
|
|
130
|
-
const allErrors = [];
|
|
131
|
-
let lineOffset = 0;
|
|
132
|
-
for (const statement of statements) {
|
|
133
|
-
if (!statement.text.trim()) {
|
|
134
|
-
const newlines = (statement.text.match(/\n/g) || []).length;
|
|
135
|
-
lineOffset += newlines;
|
|
136
|
-
continue;
|
|
137
|
-
}
|
|
138
|
-
const parser = this.createParser(statement.text);
|
|
139
|
-
const errors = [];
|
|
140
|
-
parser.removeErrorListeners();
|
|
141
|
-
parser.addErrorListener(this.createErrorListener((error) => {
|
|
142
|
-
errors.push({
|
|
143
|
-
startLine: error.startLine + lineOffset,
|
|
144
|
-
endLine: error.endLine + lineOffset,
|
|
145
|
-
startColumn: error.startColumn,
|
|
146
|
-
endColumn: error.endColumn,
|
|
147
|
-
message: error.message,
|
|
148
|
-
});
|
|
149
|
-
}));
|
|
150
|
-
parser.errorHandler = new ErrorStrategy();
|
|
151
|
-
parser.program();
|
|
152
|
-
allErrors.push(...errors);
|
|
153
|
-
const newlines = (statement.text.match(/\n/g) || []).length;
|
|
154
|
-
lineOffset += newlines;
|
|
155
|
-
}
|
|
156
|
-
return allErrors;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Split input into individual statement strings by semicolons.
|
|
160
|
-
* Handles semicolons inside quoted strings correctly.
|
|
161
|
-
*/
|
|
162
|
-
splitStatements(input) {
|
|
163
|
-
const statements = [];
|
|
164
|
-
let inSingleQuote = false;
|
|
165
|
-
let inDoubleQuote = false;
|
|
166
|
-
let lastSplit = 0;
|
|
167
|
-
for (let i = 0; i < input.length; i++) {
|
|
168
|
-
const ch = input[i];
|
|
169
|
-
if (ch === "'" && !inDoubleQuote) {
|
|
170
|
-
inSingleQuote = !inSingleQuote;
|
|
171
|
-
}
|
|
172
|
-
else if (ch === '"' && !inSingleQuote) {
|
|
173
|
-
inDoubleQuote = !inDoubleQuote;
|
|
174
|
-
}
|
|
175
|
-
else if (ch === ';' && !inSingleQuote && !inDoubleQuote) {
|
|
176
|
-
statements.push({ text: input.slice(lastSplit, i + 1), start: lastSplit });
|
|
177
|
-
lastSplit = i + 1;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
if (lastSplit < input.length) {
|
|
181
|
-
statements.push({ text: input.slice(lastSplit), start: lastSplit });
|
|
182
|
-
}
|
|
183
|
-
return statements;
|
|
184
|
-
}
|
|
185
114
|
/**
|
|
186
115
|
* Get the input string that has been parsed.
|
|
187
116
|
*/
|
|
@@ -431,7 +360,7 @@ export class BasicSQL {
|
|
|
431
360
|
const core = new CodeCompletionCore(sqlParserIns);
|
|
432
361
|
core.preferredRules = this.preferredRules;
|
|
433
362
|
// core.showRuleStack = true;
|
|
434
|
-
//
|
|
363
|
+
// core.showResult = true;
|
|
435
364
|
const candidates = core.collectCandidates(caretTokenIndex, parseTree);
|
|
436
365
|
const originalSuggestions = this.processCandidates(candidates, allTokens, caretTokenIndex);
|
|
437
366
|
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,33 @@
|
|
|
1
|
+
import type { GenericSqlListener } from '../../lib/generic/GenericSqlListener';
|
|
2
|
+
import { AlterTableContext, ColumnRefContext, ColumnRefCreateContext, CreateTableContext, DeleteContext, DropTableContext, InsertContext, QuerySpecificationContext, QueryStatementContext, SelectAllElementContext, SelectEmptyElementContext, SelectExpressionElementContext, SelectStarElementContext, 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
|
+
exitColumnRefCreate(ctx: ColumnRefCreateContext): void;
|
|
10
|
+
exitQuerySpecification(ctx: QuerySpecificationContext): void;
|
|
11
|
+
exitSelectExpressionElement(ctx: SelectExpressionElementContext): void;
|
|
12
|
+
exitSelectStarElement(ctx: SelectStarElementContext): void;
|
|
13
|
+
exitSelectAllElement(ctx: SelectAllElementContext): void;
|
|
14
|
+
exitSelectEmptyElement(ctx: SelectEmptyElementContext): void;
|
|
15
|
+
private isSimpleColumnReference;
|
|
16
|
+
/** ===== Statement begin */
|
|
17
|
+
enterSingleStatement(ctx: SingleStatementContext): void;
|
|
18
|
+
exitSingleStatement(ctx: SingleStatementContext): void;
|
|
19
|
+
enterCreateTable(ctx: CreateTableContext): void;
|
|
20
|
+
exitCreateTable(ctx: CreateTableContext): void;
|
|
21
|
+
enterQueryStatement(ctx: QueryStatementContext): void;
|
|
22
|
+
exitQueryStatement(ctx: QueryStatementContext): void;
|
|
23
|
+
enterInsert(ctx: InsertContext): void;
|
|
24
|
+
exitInsert(ctx: InsertContext): void;
|
|
25
|
+
enterUpdate(ctx: UpdateContext): void;
|
|
26
|
+
exitUpdate(ctx: UpdateContext): void;
|
|
27
|
+
enterDelete(ctx: DeleteContext): void;
|
|
28
|
+
exitDelete(ctx: DeleteContext): void;
|
|
29
|
+
enterAlterTable(ctx: AlterTableContext): void;
|
|
30
|
+
exitAlterTable(ctx: AlterTableContext): void;
|
|
31
|
+
enterDropTable(ctx: DropTableContext): void;
|
|
32
|
+
exitDropTable(ctx: DropTableContext): void;
|
|
33
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { ColumnDefinitionContext, CreateTableStatementContext, SelectExpressionElementContext, } 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
|
+
exitColumnRefCreate(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
|
+
exitSelectExpressionElement(ctx) {
|
|
38
|
+
const isSimpleColumn = this.isSimpleColumnReference(ctx);
|
|
39
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [
|
|
40
|
+
{
|
|
41
|
+
attrName: AttrName.alias,
|
|
42
|
+
endContextList: [SelectExpressionElementContext.name],
|
|
43
|
+
},
|
|
44
|
+
], {
|
|
45
|
+
declareType: isSimpleColumn
|
|
46
|
+
? ColumnDeclareType.LITERAL
|
|
47
|
+
: ColumnDeclareType.EXPRESSION,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
exitSelectStarElement(ctx) {
|
|
51
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
52
|
+
declareType: ColumnDeclareType.ALL,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
exitSelectAllElement(ctx) {
|
|
56
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
57
|
+
declareType: ColumnDeclareType.ALL,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
exitSelectEmptyElement(ctx) {
|
|
61
|
+
this.pushEntity(ctx, EntityContextType.COLUMN, [], {
|
|
62
|
+
declareType: ColumnDeclareType.LITERAL,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
isSimpleColumnReference(ctx) {
|
|
66
|
+
const text = ctx.getText();
|
|
67
|
+
// Simple column reference: no parentheses, no operators, no spaces
|
|
68
|
+
return (!text.includes('(') &&
|
|
69
|
+
!text.includes(' ') &&
|
|
70
|
+
!text.includes('+') &&
|
|
71
|
+
!text.includes('-') &&
|
|
72
|
+
!text.includes('*') &&
|
|
73
|
+
!text.includes('/'));
|
|
74
|
+
}
|
|
75
|
+
/** ===== Statement begin */
|
|
76
|
+
enterSingleStatement(ctx) {
|
|
77
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
78
|
+
}
|
|
79
|
+
exitSingleStatement(ctx) {
|
|
80
|
+
this.popStmt();
|
|
81
|
+
}
|
|
82
|
+
enterCreateTable(ctx) {
|
|
83
|
+
this.pushStmt(ctx, StmtContextType.CREATE_TABLE_STMT);
|
|
84
|
+
}
|
|
85
|
+
exitCreateTable(ctx) {
|
|
86
|
+
this.popStmt();
|
|
87
|
+
}
|
|
88
|
+
enterQueryStatement(ctx) {
|
|
89
|
+
this.pushStmt(ctx, StmtContextType.SELECT_STMT);
|
|
90
|
+
}
|
|
91
|
+
exitQueryStatement(ctx) {
|
|
92
|
+
this.popStmt();
|
|
93
|
+
}
|
|
94
|
+
enterInsert(ctx) {
|
|
95
|
+
this.pushStmt(ctx, StmtContextType.INSERT_STMT);
|
|
96
|
+
}
|
|
97
|
+
exitInsert(ctx) {
|
|
98
|
+
this.popStmt();
|
|
99
|
+
}
|
|
100
|
+
enterUpdate(ctx) {
|
|
101
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
102
|
+
}
|
|
103
|
+
exitUpdate(ctx) {
|
|
104
|
+
this.popStmt();
|
|
105
|
+
}
|
|
106
|
+
enterDelete(ctx) {
|
|
107
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
108
|
+
}
|
|
109
|
+
exitDelete(ctx) {
|
|
110
|
+
this.popStmt();
|
|
111
|
+
}
|
|
112
|
+
enterAlterTable(ctx) {
|
|
113
|
+
this.pushStmt(ctx, StmtContextType.ALTER_TABLE_STMT);
|
|
114
|
+
}
|
|
115
|
+
exitAlterTable(ctx) {
|
|
116
|
+
this.popStmt();
|
|
117
|
+
}
|
|
118
|
+
enterDropTable(ctx) {
|
|
119
|
+
this.pushStmt(ctx, StmtContextType.COMMON_STMT);
|
|
120
|
+
}
|
|
121
|
+
exitDropTable(ctx) {
|
|
122
|
+
this.popStmt();
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -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
|
+
}
|