dt-sql-parser 4.0.2 → 4.1.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.
Files changed (88) hide show
  1. package/README.md +6 -1
  2. package/dist/lib/flink/FlinkSqlLexer.js +1 -2
  3. package/dist/lib/flink/FlinkSqlParser.d.ts +175 -174
  4. package/dist/lib/flink/FlinkSqlParser.js +2315 -2388
  5. package/dist/lib/flink/FlinkSqlParserListener.d.ts +5 -16
  6. package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +3 -10
  7. package/dist/lib/hive/HiveSqlLexer.js +1 -2
  8. package/dist/lib/hive/HiveSqlParser.d.ts +3 -1
  9. package/dist/lib/hive/HiveSqlParser.js +8 -9
  10. package/dist/lib/impala/ImpalaSqlLexer.js +1 -2
  11. package/dist/lib/impala/ImpalaSqlParser.d.ts +123 -107
  12. package/dist/lib/impala/ImpalaSqlParser.js +3223 -3155
  13. package/dist/lib/impala/ImpalaSqlParserListener.d.ts +22 -0
  14. package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +14 -0
  15. package/dist/lib/mysql/MySqlLexer.js +1 -2
  16. package/dist/lib/mysql/MySqlParser.d.ts +469 -422
  17. package/dist/lib/mysql/MySqlParser.js +11460 -10509
  18. package/dist/lib/mysql/MySqlParserListener.d.ts +33 -11
  19. package/dist/lib/mysql/MySqlParserVisitor.d.ts +21 -7
  20. package/dist/lib/postgresql/PostgreSqlLexer.js +1 -2
  21. package/dist/lib/postgresql/PostgreSqlParser.d.ts +2025 -6265
  22. package/dist/lib/postgresql/PostgreSqlParser.js +60092 -88368
  23. package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +1688 -6083
  24. package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +712 -3511
  25. package/dist/lib/spark/SparkSqlLexer.js +1 -2
  26. package/dist/lib/spark/SparkSqlParser.d.ts +16 -13
  27. package/dist/lib/spark/SparkSqlParser.js +50 -51
  28. package/dist/lib/spark/SparkSqlParserListener.d.ts +10 -10
  29. package/dist/lib/spark/SparkSqlParserVisitor.d.ts +6 -6
  30. package/dist/lib/trino/TrinoSqlLexer.d.ts +323 -260
  31. package/dist/lib/trino/TrinoSqlLexer.js +1610 -1264
  32. package/dist/lib/trino/TrinoSqlListener.d.ts +1311 -200
  33. package/dist/lib/trino/TrinoSqlParser.d.ts +1908 -562
  34. package/dist/lib/trino/TrinoSqlParser.js +22629 -13412
  35. package/dist/lib/trino/TrinoSqlVisitor.d.ts +761 -69
  36. package/dist/locale/locale.d.ts +41 -0
  37. package/dist/locale/locale.js +43 -0
  38. package/dist/parser/common/basicSQL.d.ts +9 -4
  39. package/dist/parser/common/basicSQL.js +64 -21
  40. package/dist/parser/common/entityCollector.d.ts +60 -12
  41. package/dist/parser/common/entityCollector.js +141 -17
  42. package/dist/parser/common/parseErrorListener.d.ts +6 -3
  43. package/dist/parser/common/parseErrorListener.js +83 -2
  44. package/dist/parser/common/textAndWord.d.ts +6 -9
  45. package/dist/parser/common/textAndWord.js +9 -20
  46. package/dist/parser/common/transform.d.ts +8 -0
  47. package/dist/parser/common/transform.js +11 -0
  48. package/dist/parser/common/types.d.ts +1 -0
  49. package/dist/parser/flink/flinkEntityCollector.js +40 -6
  50. package/dist/parser/flink/flinkErrorListener.d.ts +9 -0
  51. package/dist/parser/flink/flinkErrorListener.js +67 -0
  52. package/dist/parser/flink/index.d.ts +4 -1
  53. package/dist/parser/flink/index.js +16 -12
  54. package/dist/parser/hive/hiveEntityCollector.js +40 -6
  55. package/dist/parser/hive/hiveErrorListener.d.ts +9 -0
  56. package/dist/parser/hive/hiveErrorListener.js +65 -0
  57. package/dist/parser/hive/index.d.ts +4 -1
  58. package/dist/parser/hive/index.js +16 -12
  59. package/dist/parser/impala/ImpalaErrorListener.d.ts +9 -0
  60. package/dist/parser/impala/ImpalaErrorListener.js +63 -0
  61. package/dist/parser/impala/impalaEntityCollector.js +51 -6
  62. package/dist/parser/impala/index.d.ts +4 -1
  63. package/dist/parser/impala/index.js +7 -3
  64. package/dist/parser/mysql/index.d.ts +4 -1
  65. package/dist/parser/mysql/index.js +7 -3
  66. package/dist/parser/mysql/mysqlEntityCollector.d.ts +3 -1
  67. package/dist/parser/mysql/mysqlEntityCollector.js +40 -5
  68. package/dist/parser/mysql/mysqlErrorListener.d.ts +9 -0
  69. package/dist/parser/mysql/mysqlErrorListener.js +63 -0
  70. package/dist/parser/postgresql/index.d.ts +4 -1
  71. package/dist/parser/postgresql/index.js +20 -16
  72. package/dist/parser/postgresql/postgreEntityCollector.d.ts +5 -1
  73. package/dist/parser/postgresql/postgreEntityCollector.js +44 -4
  74. package/dist/parser/postgresql/postgreErrorListener.d.ts +9 -0
  75. package/dist/parser/postgresql/postgreErrorListener.js +71 -0
  76. package/dist/parser/spark/index.d.ts +4 -1
  77. package/dist/parser/spark/index.js +7 -3
  78. package/dist/parser/spark/sparkEntityCollector.d.ts +1 -1
  79. package/dist/parser/spark/sparkEntityCollector.js +43 -6
  80. package/dist/parser/spark/sparkErrorListener.d.ts +9 -0
  81. package/dist/parser/spark/sparkErrorListener.js +63 -0
  82. package/dist/parser/trino/index.d.ts +4 -1
  83. package/dist/parser/trino/index.js +26 -13
  84. package/dist/parser/trino/trinoEntityCollector.d.ts +6 -4
  85. package/dist/parser/trino/trinoEntityCollector.js +44 -9
  86. package/dist/parser/trino/trinoErrorListener.d.ts +9 -0
  87. package/dist/parser/trino/trinoErrorListener.js +65 -0
  88. package/package.json +35 -11
@@ -1,11 +1,92 @@
1
+ import { Token, LexerNoViableAltException, InputMismatchException, NoViableAltException, } from 'antlr4ng';
2
+ import { transform } from './transform';
1
3
  export class ParseErrorListener {
2
- constructor(errorListener) {
4
+ constructor(errorListener, locale = 'en_US') {
5
+ this.locale = locale;
3
6
  this._errorListener = errorListener;
4
7
  }
5
8
  reportAmbiguity() { }
6
9
  reportAttemptingFullContext() { }
7
10
  reportContextSensitivity() { }
8
11
  syntaxError(recognizer, offendingSymbol, line, charPositionInLine, msg, e) {
12
+ var _a;
13
+ let message = '';
14
+ // If not undefined then offendingSymbol is of type Token.
15
+ if (offendingSymbol) {
16
+ let token = offendingSymbol;
17
+ const parser = recognizer;
18
+ // judge token is EOF
19
+ const isEof = token.type === Token.EOF;
20
+ if (isEof) {
21
+ token = parser.tokenStream.get(token.tokenIndex - 1);
22
+ }
23
+ const wrongText = (_a = token.text) !== null && _a !== void 0 ? _a : '';
24
+ const isInComplete = isEof && wrongText !== ' ';
25
+ const expectedText = isInComplete ? '' : this.getExpectedText(parser, token);
26
+ if (!e) {
27
+ // handle missing or unwanted tokens.
28
+ message = msg;
29
+ if (msg.includes('extraneous')) {
30
+ message = `'${wrongText}' {noValidPosition}${expectedText.length ? `{expecting}${expectedText}` : ''}`;
31
+ }
32
+ if (msg.includes('missing')) {
33
+ const regex = /missing\s+'([^']+)'/;
34
+ const match = msg.match(regex);
35
+ message = `{missing}`;
36
+ if (match) {
37
+ const missKeyword = match[1];
38
+ message += `'${missKeyword}'`;
39
+ }
40
+ else {
41
+ message += `{keyword}`;
42
+ }
43
+ message += `{at}'${wrongText}'`;
44
+ }
45
+ }
46
+ else {
47
+ // handle mismatch exception or no viable alt exception
48
+ if (e instanceof InputMismatchException || e instanceof NoViableAltException) {
49
+ if (isEof) {
50
+ message = `{stmtInComplete}`;
51
+ }
52
+ else {
53
+ message = `'${wrongText}' {noValidPosition}`;
54
+ }
55
+ if (expectedText.length > 0) {
56
+ message += `{expecting}${expectedText}`;
57
+ }
58
+ }
59
+ else {
60
+ message = msg;
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ // No offending symbol, which indicates this is a lexer error.
66
+ if (e instanceof LexerNoViableAltException) {
67
+ const lexer = recognizer;
68
+ const input = lexer.inputStream;
69
+ let text = lexer.getErrorDisplay(input.getText(lexer._tokenStartCharIndex, input.index));
70
+ switch (text[0]) {
71
+ case '/':
72
+ message = '{unfinishedMultilineComment}';
73
+ break;
74
+ case '"':
75
+ message = '{unfinishedDoubleQuoted}';
76
+ break;
77
+ case "'":
78
+ message = '{unfinishedSingleQuoted}';
79
+ break;
80
+ case '`':
81
+ message = '{unfinishedTickQuoted}';
82
+ break;
83
+ default:
84
+ message = '"' + text + '" {noValidInput}';
85
+ break;
86
+ }
87
+ }
88
+ }
89
+ message = transform(message, this.locale);
9
90
  let endCol = charPositionInLine + 1;
10
91
  if (offendingSymbol && offendingSymbol.text !== null) {
11
92
  endCol = charPositionInLine + offendingSymbol.text.length;
@@ -16,7 +97,7 @@ export class ParseErrorListener {
16
97
  endLine: line,
17
98
  startColumn: charPositionInLine + 1,
18
99
  endColumn: endCol + 1,
19
- message: msg,
100
+ message,
20
101
  }, {
21
102
  e,
22
103
  line,
@@ -35,18 +35,15 @@ export interface TextSlice extends TextPosition {
35
35
  /**
36
36
  * Convert Token to Word
37
37
  */
38
- export declare function tokenToWord(token: Token, input: string): WordPosition & {
39
- text: string;
40
- };
41
- /**
42
- * Convert ParserRuleContext to Word
43
- */
44
- export declare function ctxToWord(ctx: ParserRuleContext, input: string): (WordPosition & {
45
- text: string;
46
- }) | null;
38
+ export declare function tokenToWord(token: Token, input: string): WordRange;
47
39
  /**
48
40
  * Convert ParserRuleContext to Text
49
41
  */
50
42
  export declare function ctxToText(ctx: ParserRuleContext, input: string): (TextPosition & {
51
43
  text: string;
52
44
  }) | null;
45
+ /**
46
+ * judge whether the context is a WordRange
47
+ * @param textOrWord TextSlice or WordRange object
48
+ * */
49
+ export declare function isWordRange(textOrWord: TextSlice | WordRange): textOrWord is WordRange;
@@ -15,26 +15,6 @@ export function tokenToWord(token, input) {
15
15
  endColumn: token.column + 1 + text.length,
16
16
  };
17
17
  }
18
- /**
19
- * Convert ParserRuleContext to Word
20
- */
21
- export function ctxToWord(ctx, input) {
22
- var _a, _b;
23
- if (!ctx.start || !ctx.stop) {
24
- return null;
25
- }
26
- const startIndex = ctx.start.start;
27
- const endIndex = ctx.stop.stop;
28
- const text = input.slice(startIndex, endIndex + 1);
29
- return {
30
- text,
31
- line: ctx.start.line,
32
- startIndex,
33
- endIndex,
34
- startColumn: ctx.start.column + 1,
35
- endColumn: ctx.stop.column + 1 + ((_b = (_a = ctx.stop.text) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0),
36
- };
37
- }
38
18
  /**
39
19
  * Convert ParserRuleContext to Text
40
20
  */
@@ -56,3 +36,12 @@ export function ctxToText(ctx, input) {
56
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),
57
37
  };
58
38
  }
39
+ /**
40
+ * judge whether the context is a WordRange
41
+ * @param textOrWord TextSlice or WordRange object
42
+ * */
43
+ export function isWordRange(textOrWord) {
44
+ if (!textOrWord)
45
+ return false;
46
+ return 'line' in textOrWord;
47
+ }
@@ -0,0 +1,8 @@
1
+ import { LOCALE_TYPE } from './types';
2
+ /**
3
+ * transform message to locale language
4
+ * @param message error msg
5
+ * @param locale language setting
6
+ */
7
+ declare function transform(message: string, locale: LOCALE_TYPE): string;
8
+ export { transform };
@@ -0,0 +1,11 @@
1
+ import { i18n } from '../../locale/locale';
2
+ /**
3
+ * transform message to locale language
4
+ * @param message error msg
5
+ * @param locale language setting
6
+ */
7
+ function transform(message, locale) {
8
+ const regex = /{([^}]+)}/g;
9
+ return message.replace(regex, (_, key) => i18n[locale][key] || '');
10
+ }
11
+ export { transform };
@@ -63,3 +63,4 @@ export interface Suggestions<T = WordRange> {
63
63
  */
64
64
  readonly keywords: string[];
65
65
  }
66
+ export type LOCALE_TYPE = 'zh_CN' | 'en_US';
@@ -1,5 +1,6 @@
1
+ import { CreateDatabaseContext, CreateTableContext, CreateViewContext, PhysicalColumnDefinitionContext, TableReferenceContext, } from '../../lib/flink/FlinkSqlParser';
2
+ import { AttrName, EntityCollector, StmtContextType } from '../common/entityCollector';
1
3
  import { EntityContextType } from '../common/types';
2
- import { StmtContextType, EntityCollector } from '../common/entityCollector';
3
4
  export class FlinkEntityCollector extends EntityCollector {
4
5
  /** ====== Entity Begin */
5
6
  exitCatalogPathCreate(ctx) {
@@ -9,25 +10,58 @@ export class FlinkEntityCollector extends EntityCollector {
9
10
  this.pushEntity(ctx, EntityContextType.CATALOG);
10
11
  }
11
12
  exitDatabasePathCreate(ctx) {
12
- this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
13
+ this.pushEntity(ctx, EntityContextType.DATABASE_CREATE, [
14
+ {
15
+ attrName: AttrName.comment,
16
+ endContextList: [CreateDatabaseContext.name],
17
+ },
18
+ ]);
13
19
  }
14
20
  exitDatabasePath(ctx) {
15
21
  this.pushEntity(ctx, EntityContextType.DATABASE);
16
22
  }
17
23
  exitTablePath(ctx) {
18
- this.pushEntity(ctx, EntityContextType.TABLE);
24
+ var _a;
25
+ const needCollectAttr = ((_a = this.getRootStmt()) === null || _a === void 0 ? void 0 : _a.stmtContextType) === StmtContextType.SELECT_STMT;
26
+ this.pushEntity(ctx, EntityContextType.TABLE, needCollectAttr
27
+ ? [
28
+ {
29
+ attrName: AttrName.alias,
30
+ endContextList: [TableReferenceContext.name],
31
+ },
32
+ ]
33
+ : undefined);
19
34
  }
20
35
  exitTablePathCreate(ctx) {
21
- this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
36
+ this.pushEntity(ctx, EntityContextType.TABLE_CREATE, [
37
+ {
38
+ attrName: AttrName.comment,
39
+ endContextList: [CreateTableContext.name],
40
+ },
41
+ ]);
22
42
  }
23
43
  exitViewPath(ctx) {
24
44
  this.pushEntity(ctx, EntityContextType.VIEW);
25
45
  }
26
46
  exitViewPathCreate(ctx) {
27
- this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
47
+ this.pushEntity(ctx, EntityContextType.VIEW_CREATE, [
48
+ {
49
+ attrName: AttrName.comment,
50
+ endContextList: [CreateViewContext.name],
51
+ },
52
+ ]);
28
53
  }
29
54
  exitColumnNameCreate(ctx) {
30
- this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
55
+ this.pushEntity(ctx, EntityContextType.COLUMN_CREATE, [
56
+ {
57
+ attrName: AttrName.comment,
58
+ endContextList: [PhysicalColumnDefinitionContext.name],
59
+ },
60
+ {
61
+ attrName: AttrName.colType,
62
+ endContextList: [PhysicalColumnDefinitionContext.name],
63
+ },
64
+ ]);
31
65
  }
32
66
  exitFunctionNameCreate(ctx) {
33
67
  this.pushEntity(ctx, EntityContextType.FUNCTION_CREATE);
@@ -0,0 +1,9 @@
1
+ import { ErrorListener, ParseErrorListener } from '../common/parseErrorListener';
2
+ import { Parser, Token } from 'antlr4ng';
3
+ import { LOCALE_TYPE } from '../common/types';
4
+ export declare class FlinkErrorListener extends ParseErrorListener {
5
+ private preferredRules;
6
+ private objectNames;
7
+ constructor(errorListener: ErrorListener, preferredRules: Set<number>, locale: LOCALE_TYPE);
8
+ getExpectedText(parser: Parser, token: Token): string;
9
+ }
@@ -0,0 +1,67 @@
1
+ import { CodeCompletionCore } from 'antlr4-c3';
2
+ import { ParseErrorListener } from '../common/parseErrorListener';
3
+ import { FlinkSqlParser } from '../../lib/flink/FlinkSqlParser';
4
+ export class FlinkErrorListener extends ParseErrorListener {
5
+ constructor(errorListener, preferredRules, locale) {
6
+ super(errorListener, locale);
7
+ this.objectNames = new Map([
8
+ [FlinkSqlParser.RULE_catalogPath, 'catalog'],
9
+ [FlinkSqlParser.RULE_catalogPathCreate, 'catalog'],
10
+ [FlinkSqlParser.RULE_databasePath, 'database'],
11
+ [FlinkSqlParser.RULE_databasePathCreate, 'database'],
12
+ [FlinkSqlParser.RULE_tablePath, 'table'],
13
+ [FlinkSqlParser.RULE_tablePathCreate, 'table'],
14
+ [FlinkSqlParser.RULE_viewPath, 'view'],
15
+ [FlinkSqlParser.RULE_viewPathCreate, 'view'],
16
+ [FlinkSqlParser.RULE_functionName, 'function'],
17
+ [FlinkSqlParser.RULE_functionNameCreate, 'function'],
18
+ [FlinkSqlParser.RULE_columnName, 'column'],
19
+ [FlinkSqlParser.RULE_columnNameCreate, 'column'],
20
+ ]);
21
+ this.preferredRules = preferredRules;
22
+ }
23
+ getExpectedText(parser, token) {
24
+ var _a;
25
+ let expectedText = '';
26
+ let currentContext = (_a = parser.context) !== null && _a !== void 0 ? _a : undefined;
27
+ while (currentContext === null || currentContext === void 0 ? void 0 : currentContext.parent) {
28
+ currentContext = currentContext.parent;
29
+ }
30
+ const core = new CodeCompletionCore(parser);
31
+ core.preferredRules = this.preferredRules;
32
+ const candidates = core.collectCandidates(token.tokenIndex, currentContext);
33
+ if (candidates.rules.size) {
34
+ const result = [];
35
+ // get expectedText as collect rules first
36
+ for (const candidate of candidates.rules) {
37
+ const [ruleType] = candidate;
38
+ const name = this.objectNames.get(ruleType);
39
+ switch (ruleType) {
40
+ case FlinkSqlParser.RULE_databasePath:
41
+ case FlinkSqlParser.RULE_tablePath:
42
+ case FlinkSqlParser.RULE_viewPath:
43
+ case FlinkSqlParser.RULE_functionName:
44
+ case FlinkSqlParser.RULE_columnName:
45
+ case FlinkSqlParser.RULE_catalogPath: {
46
+ result.push(`{existing}${name}`);
47
+ break;
48
+ }
49
+ case FlinkSqlParser.RULE_databasePathCreate:
50
+ case FlinkSqlParser.RULE_tablePathCreate:
51
+ case FlinkSqlParser.RULE_functionNameCreate:
52
+ case FlinkSqlParser.RULE_viewPathCreate:
53
+ case FlinkSqlParser.RULE_columnNameCreate:
54
+ case FlinkSqlParser.RULE_catalogPathCreate: {
55
+ result.push(`{new}${name}`);
56
+ break;
57
+ }
58
+ }
59
+ }
60
+ expectedText = result.join('{or}');
61
+ }
62
+ if (candidates.tokens.size) {
63
+ expectedText += expectedText ? '{orKeyword}' : '{keyword}';
64
+ }
65
+ return expectedText;
66
+ }
67
+ }
@@ -6,12 +6,15 @@ import { Suggestions } from '../common/types';
6
6
  import { BasicSQL } from '../common/basicSQL';
7
7
  import { FlinkSqlSplitListener } from './flinkSplitListener';
8
8
  import { FlinkEntityCollector } from './flinkEntityCollector';
9
+ import { ErrorListener } from '../common/parseErrorListener';
10
+ import { FlinkErrorListener } from './flinkErrorListener';
9
11
  export { FlinkSqlSplitListener, FlinkEntityCollector };
10
12
  export declare class FlinkSQL extends BasicSQL<FlinkSqlLexer, ProgramContext, FlinkSqlParser> {
11
13
  protected createLexerFromCharStream(charStreams: CharStream): FlinkSqlLexer;
12
14
  protected createParserFromTokenStream(tokenStream: CommonTokenStream): FlinkSqlParser;
13
15
  protected preferredRules: Set<number>;
14
16
  protected get splitListener(): FlinkSqlSplitListener;
17
+ protected createErrorListener(_errorListener: ErrorListener): FlinkErrorListener;
15
18
  protected createEntityCollector(input: string, caretTokenIndex?: number): FlinkEntityCollector;
16
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
19
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
17
20
  }
@@ -4,20 +4,21 @@ import { EntityContextType } from '../common/types';
4
4
  import { BasicSQL } from '../common/basicSQL';
5
5
  import { FlinkSqlSplitListener } from './flinkSplitListener';
6
6
  import { FlinkEntityCollector } from './flinkEntityCollector';
7
+ import { FlinkErrorListener } from './flinkErrorListener';
7
8
  export { FlinkSqlSplitListener, FlinkEntityCollector };
8
9
  export class FlinkSQL extends BasicSQL {
9
10
  constructor() {
10
11
  super(...arguments);
11
12
  this.preferredRules = new Set([
12
- FlinkSqlParser.RULE_catalogPath,
13
- FlinkSqlParser.RULE_databasePath,
14
- FlinkSqlParser.RULE_databasePathCreate,
15
- FlinkSqlParser.RULE_tablePath,
16
- FlinkSqlParser.RULE_tablePathCreate,
17
- FlinkSqlParser.RULE_viewPath,
18
- FlinkSqlParser.RULE_viewPathCreate,
19
- FlinkSqlParser.RULE_functionName,
20
- FlinkSqlParser.RULE_functionNameCreate,
13
+ FlinkSqlParser.RULE_catalogPath, // catalog name
14
+ FlinkSqlParser.RULE_databasePath, // database name
15
+ FlinkSqlParser.RULE_databasePathCreate, // database name that will be created
16
+ FlinkSqlParser.RULE_tablePath, // table name
17
+ FlinkSqlParser.RULE_tablePathCreate, // table name that will be created
18
+ FlinkSqlParser.RULE_viewPath, // view name path
19
+ FlinkSqlParser.RULE_viewPathCreate, // viewName that will be created
20
+ FlinkSqlParser.RULE_functionName, // functionName
21
+ FlinkSqlParser.RULE_functionNameCreate, // functionName that will be created
21
22
  FlinkSqlParser.RULE_columnName,
22
23
  FlinkSqlParser.RULE_columnNameCreate,
23
24
  ]);
@@ -31,16 +32,19 @@ export class FlinkSQL extends BasicSQL {
31
32
  get splitListener() {
32
33
  return new FlinkSqlSplitListener();
33
34
  }
35
+ createErrorListener(_errorListener) {
36
+ return new FlinkErrorListener(_errorListener, this.preferredRules, this.locale);
37
+ }
34
38
  createEntityCollector(input, caretTokenIndex) {
35
39
  return new FlinkEntityCollector(input, caretTokenIndex);
36
40
  }
37
- processCandidates(candidates, allTokens, caretTokenIndex, tokenIndexOffset) {
41
+ processCandidates(candidates, allTokens, caretTokenIndex) {
38
42
  const originalSyntaxSuggestions = [];
39
43
  const keywords = [];
40
44
  for (let candidate of candidates.rules) {
41
45
  const [ruleType, candidateRule] = candidate;
42
- const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
43
- const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + tokenIndexOffset + 1);
46
+ const startTokenIndex = candidateRule.startTokenIndex;
47
+ const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + 1);
44
48
  let syntaxContextType = void 0;
45
49
  switch (ruleType) {
46
50
  case FlinkSqlParser.RULE_catalogPath: {
@@ -1,24 +1,58 @@
1
+ import { ColumnNameCommentContext, ColumnNameTypeConstraintContext, CreateDatabaseStatementContext, CreateTableStatementContext, CreateViewStatementContext, TableSourceContext, UniqueJoinSourceContext, } from '../../lib/hive/HiveSqlParser';
2
+ import { AttrName, EntityCollector, StmtContextType } from '../common/entityCollector';
1
3
  import { EntityContextType } from '../common/types';
2
- import { StmtContextType, EntityCollector } from '../common/entityCollector';
3
4
  export class HiveEntityCollector extends EntityCollector {
4
5
  /** ====== Entity Begin */
5
6
  exitTableNameCreate(ctx) {
6
- this.pushEntity(ctx, EntityContextType.TABLE_CREATE);
7
+ this.pushEntity(ctx, EntityContextType.TABLE_CREATE, [
8
+ {
9
+ attrName: AttrName.comment,
10
+ endContextList: [CreateTableStatementContext.name],
11
+ },
12
+ ]);
7
13
  }
8
14
  exitTableName(ctx) {
9
- this.pushEntity(ctx, EntityContextType.TABLE);
15
+ var _a;
16
+ const needCollectAttr = ((_a = this.getRootStmt()) === null || _a === void 0 ? void 0 : _a.stmtContextType) === StmtContextType.SELECT_STMT;
17
+ this.pushEntity(ctx, EntityContextType.TABLE, needCollectAttr
18
+ ? [
19
+ {
20
+ attrName: AttrName.alias,
21
+ endContextList: [TableSourceContext.name, UniqueJoinSourceContext.name],
22
+ },
23
+ ]
24
+ : undefined);
10
25
  }
11
26
  exitColumnNameCreate(ctx) {
12
- this.pushEntity(ctx, EntityContextType.COLUMN_CREATE);
27
+ this.pushEntity(ctx, EntityContextType.COLUMN_CREATE, [
28
+ {
29
+ attrName: AttrName.comment,
30
+ endContextList: [ColumnNameCommentContext.name],
31
+ },
32
+ {
33
+ attrName: AttrName.colType,
34
+ endContextList: [ColumnNameTypeConstraintContext.name],
35
+ },
36
+ ]);
13
37
  }
14
38
  exitViewNameCreate(ctx) {
15
- this.pushEntity(ctx, EntityContextType.VIEW_CREATE);
39
+ this.pushEntity(ctx, EntityContextType.VIEW_CREATE, [
40
+ {
41
+ attrName: AttrName.comment,
42
+ endContextList: [CreateViewStatementContext.name],
43
+ },
44
+ ]);
16
45
  }
17
46
  exitViewName(ctx) {
18
47
  this.pushEntity(ctx, EntityContextType.VIEW);
19
48
  }
20
49
  exitDbSchemaNameCreate(ctx) {
21
- this.pushEntity(ctx, EntityContextType.DATABASE_CREATE);
50
+ this.pushEntity(ctx, EntityContextType.DATABASE_CREATE, [
51
+ {
52
+ attrName: AttrName.comment,
53
+ endContextList: [CreateDatabaseStatementContext.name],
54
+ },
55
+ ]);
22
56
  }
23
57
  exitDbSchemaName(ctx) {
24
58
  this.pushEntity(ctx, EntityContextType.DATABASE);
@@ -0,0 +1,9 @@
1
+ import { ErrorListener, ParseErrorListener } from '../common/parseErrorListener';
2
+ import { Parser, Token } from 'antlr4ng';
3
+ import { LOCALE_TYPE } from '../common/types';
4
+ export declare class HiveErrorListener extends ParseErrorListener {
5
+ private preferredRules;
6
+ private objectNames;
7
+ constructor(errorListener: ErrorListener, preferredRules: Set<number>, locale: LOCALE_TYPE);
8
+ getExpectedText(parser: Parser, token: Token): string;
9
+ }
@@ -0,0 +1,65 @@
1
+ import { CodeCompletionCore } from 'antlr4-c3';
2
+ import { ParseErrorListener } from '../common/parseErrorListener';
3
+ import { HiveSqlParser } from '../../lib/hive/HiveSqlParser';
4
+ export class HiveErrorListener extends ParseErrorListener {
5
+ constructor(errorListener, preferredRules, locale) {
6
+ super(errorListener, locale);
7
+ this.objectNames = new Map([
8
+ [HiveSqlParser.RULE_dbSchemaName, 'database'],
9
+ [HiveSqlParser.RULE_dbSchemaNameCreate, 'database'],
10
+ [HiveSqlParser.RULE_tableName, 'table'],
11
+ [HiveSqlParser.RULE_tableNameCreate, 'table'],
12
+ [HiveSqlParser.RULE_viewName, 'view'],
13
+ [HiveSqlParser.RULE_viewNameCreate, 'view'],
14
+ [HiveSqlParser.RULE_functionNameForDDL, 'function'],
15
+ [HiveSqlParser.RULE_functionNameForInvoke, 'function'],
16
+ [HiveSqlParser.RULE_functionNameCreate, 'function'],
17
+ [HiveSqlParser.RULE_columnName, 'column'],
18
+ [HiveSqlParser.RULE_columnNameCreate, 'column'],
19
+ ]);
20
+ this.preferredRules = preferredRules;
21
+ }
22
+ getExpectedText(parser, token) {
23
+ var _a;
24
+ let expectedText = '';
25
+ let currentContext = (_a = parser.context) !== null && _a !== void 0 ? _a : undefined;
26
+ while (currentContext === null || currentContext === void 0 ? void 0 : currentContext.parent) {
27
+ currentContext = currentContext.parent;
28
+ }
29
+ const core = new CodeCompletionCore(parser);
30
+ core.preferredRules = this.preferredRules;
31
+ const candidates = core.collectCandidates(token.tokenIndex, currentContext);
32
+ if (candidates.rules.size) {
33
+ const result = [];
34
+ // get expectedText as collect rules first
35
+ for (const candidate of candidates.rules) {
36
+ const [ruleType] = candidate;
37
+ const name = this.objectNames.get(ruleType);
38
+ switch (ruleType) {
39
+ case HiveSqlParser.RULE_dbSchemaName:
40
+ case HiveSqlParser.RULE_tableName:
41
+ case HiveSqlParser.RULE_viewName:
42
+ case HiveSqlParser.RULE_functionNameForDDL:
43
+ case HiveSqlParser.RULE_functionNameForInvoke:
44
+ case HiveSqlParser.RULE_columnName: {
45
+ result.push(`{existing}${name}`);
46
+ break;
47
+ }
48
+ case HiveSqlParser.RULE_dbSchemaNameCreate:
49
+ case HiveSqlParser.RULE_tableNameCreate:
50
+ case HiveSqlParser.RULE_functionNameCreate:
51
+ case HiveSqlParser.RULE_viewNameCreate:
52
+ case HiveSqlParser.RULE_columnNameCreate: {
53
+ result.push(`{new}${name}`);
54
+ break;
55
+ }
56
+ }
57
+ }
58
+ expectedText = result.join('{or}');
59
+ }
60
+ if (candidates.tokens.size) {
61
+ expectedText += expectedText ? '{orKeyword}' : '{keyword}';
62
+ }
63
+ return expectedText;
64
+ }
65
+ }
@@ -6,12 +6,15 @@ import { BasicSQL } from '../common/basicSQL';
6
6
  import { Suggestions } from '../common/types';
7
7
  import { HiveSqlSplitListener } from './hiveSplitListener';
8
8
  import { HiveEntityCollector } from './hiveEntityCollector';
9
+ import { ErrorListener } from '../common/parseErrorListener';
10
+ import { HiveErrorListener } from './hiveErrorListener';
9
11
  export { HiveEntityCollector, HiveSqlSplitListener };
10
12
  export declare class HiveSQL extends BasicSQL<HiveSqlLexer, ProgramContext, HiveSqlParser> {
11
13
  protected createLexerFromCharStream(charStreams: CharStream): HiveSqlLexer;
12
14
  protected createParserFromTokenStream(tokenStream: CommonTokenStream): HiveSqlParser;
13
15
  protected preferredRules: Set<number>;
14
16
  protected get splitListener(): HiveSqlSplitListener;
17
+ protected createErrorListener(_errorListener: ErrorListener): HiveErrorListener;
15
18
  protected createEntityCollector(input: string, caretTokenIndex?: number): HiveEntityCollector;
16
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
19
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
17
20
  }
@@ -4,20 +4,21 @@ import { BasicSQL } from '../common/basicSQL';
4
4
  import { EntityContextType } from '../common/types';
5
5
  import { HiveSqlSplitListener } from './hiveSplitListener';
6
6
  import { HiveEntityCollector } from './hiveEntityCollector';
7
+ import { HiveErrorListener } from './hiveErrorListener';
7
8
  export { HiveEntityCollector, HiveSqlSplitListener };
8
9
  export class HiveSQL extends BasicSQL {
9
10
  constructor() {
10
11
  super(...arguments);
11
12
  this.preferredRules = new Set([
12
- HiveSqlParser.RULE_dbSchemaName,
13
- HiveSqlParser.RULE_dbSchemaNameCreate,
14
- HiveSqlParser.RULE_tableName,
15
- HiveSqlParser.RULE_tableNameCreate,
16
- HiveSqlParser.RULE_viewName,
17
- HiveSqlParser.RULE_viewNameCreate,
18
- HiveSqlParser.RULE_functionNameForDDL,
19
- HiveSqlParser.RULE_functionNameForInvoke,
20
- HiveSqlParser.RULE_functionNameCreate,
13
+ HiveSqlParser.RULE_dbSchemaName, // db or schema name
14
+ HiveSqlParser.RULE_dbSchemaNameCreate, // db or schema name that will be created
15
+ HiveSqlParser.RULE_tableName, // table name
16
+ HiveSqlParser.RULE_tableNameCreate, // table name that will be created
17
+ HiveSqlParser.RULE_viewName, // view name
18
+ HiveSqlParser.RULE_viewNameCreate, // view name that will be created
19
+ HiveSqlParser.RULE_functionNameForDDL, // function name
20
+ HiveSqlParser.RULE_functionNameForInvoke, // function name
21
+ HiveSqlParser.RULE_functionNameCreate, // function name that will be created
21
22
  HiveSqlParser.RULE_columnName,
22
23
  HiveSqlParser.RULE_columnNameCreate,
23
24
  ]);
@@ -31,16 +32,19 @@ export class HiveSQL extends BasicSQL {
31
32
  get splitListener() {
32
33
  return new HiveSqlSplitListener();
33
34
  }
35
+ createErrorListener(_errorListener) {
36
+ return new HiveErrorListener(_errorListener, this.preferredRules, this.locale);
37
+ }
34
38
  createEntityCollector(input, caretTokenIndex) {
35
39
  return new HiveEntityCollector(input, caretTokenIndex);
36
40
  }
37
- processCandidates(candidates, allTokens, caretTokenIndex, tokenIndexOffset) {
41
+ processCandidates(candidates, allTokens, caretTokenIndex) {
38
42
  const originalSyntaxSuggestions = [];
39
43
  const keywords = [];
40
44
  for (let candidate of candidates.rules) {
41
45
  const [ruleType, candidateRule] = candidate;
42
- const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
43
- const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + tokenIndexOffset + 1);
46
+ const startTokenIndex = candidateRule.startTokenIndex;
47
+ const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + 1);
44
48
  let syntaxContextType = void 0;
45
49
  switch (ruleType) {
46
50
  case HiveSqlParser.RULE_dbSchemaName: {
@@ -0,0 +1,9 @@
1
+ import { ErrorListener, ParseErrorListener } from '../common/parseErrorListener';
2
+ import { Parser, Token } from 'antlr4ng';
3
+ import { LOCALE_TYPE } from '../common/types';
4
+ export declare class ImpalaErrorListener extends ParseErrorListener {
5
+ private preferredRules;
6
+ private objectNames;
7
+ constructor(errorListener: ErrorListener, preferredRules: Set<number>, locale: LOCALE_TYPE);
8
+ getExpectedText(parser: Parser, token: Token): string;
9
+ }