dt-sql-parser 4.1.2-beta.1 → 4.3.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.
Files changed (83) hide show
  1. package/README.md +51 -0
  2. package/dist/lib/flink/FlinkSqlLexer.d.ts +2 -2
  3. package/dist/lib/flink/FlinkSqlLexer.js +21 -20
  4. package/dist/lib/flink/FlinkSqlParser.d.ts +178 -168
  5. package/dist/lib/flink/FlinkSqlParser.js +2799 -2741
  6. package/dist/lib/flink/FlinkSqlParserListener.d.ts +11 -0
  7. package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +7 -0
  8. package/dist/lib/hive/HiveSqlParser.d.ts +241 -221
  9. package/dist/lib/hive/HiveSqlParser.js +6229 -5639
  10. package/dist/lib/hive/HiveSqlParserListener.d.ts +22 -0
  11. package/dist/lib/hive/HiveSqlParserVisitor.d.ts +14 -0
  12. package/dist/lib/impala/ImpalaSqlLexer.d.ts +2 -2
  13. package/dist/lib/impala/ImpalaSqlLexer.js +5 -5
  14. package/dist/lib/impala/ImpalaSqlParser.d.ts +147 -109
  15. package/dist/lib/impala/ImpalaSqlParser.js +3448 -3234
  16. package/dist/lib/impala/ImpalaSqlParserListener.d.ts +44 -0
  17. package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +28 -0
  18. package/dist/lib/mysql/MySqlLexer.d.ts +2 -2
  19. package/dist/lib/mysql/MySqlLexer.js +43 -43
  20. package/dist/lib/mysql/MySqlParser.d.ts +2 -2
  21. package/dist/lib/mysql/MySqlParser.js +42 -42
  22. package/dist/lib/postgresql/PostgreSqlLexer.d.ts +14 -15
  23. package/dist/lib/postgresql/PostgreSqlLexer.js +2077 -2092
  24. package/dist/lib/postgresql/PostgreSqlParser.d.ts +152 -131
  25. package/dist/lib/postgresql/PostgreSqlParser.js +10052 -9925
  26. package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +22 -0
  27. package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +14 -0
  28. package/dist/lib/spark/SparkSqlLexer.d.ts +2 -2
  29. package/dist/lib/spark/SparkSqlLexer.js +6 -6
  30. package/dist/lib/spark/SparkSqlParser.d.ts +391 -623
  31. package/dist/lib/spark/SparkSqlParser.js +6749 -8109
  32. package/dist/lib/spark/SparkSqlParserListener.d.ts +38 -326
  33. package/dist/lib/spark/SparkSqlParserVisitor.d.ts +24 -207
  34. package/dist/lib/trino/TrinoSqlLexer.d.ts +2 -2
  35. package/dist/lib/trino/TrinoSqlLexer.js +5 -5
  36. package/dist/lib/trino/TrinoSqlListener.d.ts +44 -0
  37. package/dist/lib/trino/TrinoSqlParser.d.ts +182 -153
  38. package/dist/lib/trino/TrinoSqlParser.js +4758 -4599
  39. package/dist/lib/trino/TrinoSqlVisitor.d.ts +28 -0
  40. package/dist/parser/common/basicSQL.d.ts +43 -9
  41. package/dist/parser/common/basicSQL.js +147 -40
  42. package/dist/parser/common/semanticContextCollector.d.ts +50 -0
  43. package/dist/parser/common/semanticContextCollector.js +202 -0
  44. package/dist/parser/common/tokenUtils.d.ts +12 -0
  45. package/dist/parser/common/tokenUtils.js +38 -0
  46. package/dist/parser/common/types.d.ts +30 -1
  47. package/dist/parser/common/types.js +11 -0
  48. package/dist/parser/flink/flinkErrorListener.js +14 -2
  49. package/dist/parser/flink/flinkSemanticContextCollector.d.ts +9 -0
  50. package/dist/parser/flink/flinkSemanticContextCollector.js +14 -0
  51. package/dist/parser/flink/index.d.ts +4 -2
  52. package/dist/parser/flink/index.js +32 -14
  53. package/dist/parser/hive/hiveErrorListener.js +9 -3
  54. package/dist/parser/hive/hiveSemanticContextCollector.d.ts +9 -0
  55. package/dist/parser/hive/hiveSemanticContextCollector.js +14 -0
  56. package/dist/parser/hive/index.d.ts +4 -2
  57. package/dist/parser/hive/index.js +29 -14
  58. package/dist/parser/impala/ImpalaErrorListener.js +8 -2
  59. package/dist/parser/impala/impalaSemanticContextCollector.d.ts +9 -0
  60. package/dist/parser/impala/impalaSemanticContextCollector.js +14 -0
  61. package/dist/parser/impala/index.d.ts +4 -2
  62. package/dist/parser/impala/index.js +21 -14
  63. package/dist/parser/mysql/index.d.ts +4 -2
  64. package/dist/parser/mysql/index.js +10 -14
  65. package/dist/parser/mysql/mysqlErrorListener.js +6 -2
  66. package/dist/parser/mysql/mysqlSemanticContextCollector.d.ts +9 -0
  67. package/dist/parser/mysql/mysqlSemanticContextCollector.js +14 -0
  68. package/dist/parser/postgresql/index.d.ts +4 -2
  69. package/dist/parser/postgresql/index.js +23 -14
  70. package/dist/parser/postgresql/postgreErrorListener.js +9 -3
  71. package/dist/parser/postgresql/postgreSemanticContextCollector.d.ts +9 -0
  72. package/dist/parser/postgresql/postgreSemanticContextCollector.js +14 -0
  73. package/dist/parser/spark/index.d.ts +4 -2
  74. package/dist/parser/spark/index.js +26 -14
  75. package/dist/parser/spark/sparkErrorListener.js +9 -3
  76. package/dist/parser/spark/sparkSemanticContextCollector.d.ts +9 -0
  77. package/dist/parser/spark/sparkSemanticContextCollector.js +14 -0
  78. package/dist/parser/trino/index.d.ts +4 -2
  79. package/dist/parser/trino/index.js +22 -14
  80. package/dist/parser/trino/trinoErrorListener.js +9 -3
  81. package/dist/parser/trino/trinoSemanticContextCollector.d.ts +9 -0
  82. package/dist/parser/trino/trinoSemanticContextCollector.js +14 -0
  83. package/package.json +2 -1
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Utility function for processing SQL tokens and generating keyword suggestions
3
+ */
4
+ import { Parser } from 'antlr4ng';
5
+ import { CandidatesCollection } from 'antlr4-c3';
6
+ /**
7
+ * Process token candidates and generate a list of keyword suggestions
8
+ * @param parser SQL parser instance
9
+ * @param tokens token candidates
10
+ * @returns list of keyword suggestions
11
+ */
12
+ export declare function processTokenCandidates(parser: Parser, tokens: CandidatesCollection['tokens']): string[];
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Utility function for processing SQL tokens and generating keyword suggestions
3
+ */
4
+ /**
5
+ * Process token candidates and generate a list of keyword suggestions
6
+ * @param parser SQL parser instance
7
+ * @param tokens token candidates
8
+ * @returns list of keyword suggestions
9
+ */
10
+ export function processTokenCandidates(parser, tokens) {
11
+ const keywords = [];
12
+ const cleanDisplayName = (displayName) => {
13
+ return displayName && displayName.startsWith("'") && displayName.endsWith("'")
14
+ ? displayName.slice(1, -1)
15
+ : displayName || '';
16
+ };
17
+ const isKeywordToken = (token) => {
18
+ const symbolicName = parser.vocabulary.getSymbolicName(token);
19
+ return Boolean(symbolicName === null || symbolicName === void 0 ? void 0 : symbolicName.startsWith('KW_'));
20
+ };
21
+ for (const [token, followSets] of tokens) {
22
+ const displayName = parser.vocabulary.getDisplayName(token);
23
+ if (!displayName || !isKeywordToken(token))
24
+ continue;
25
+ const keyword = cleanDisplayName(displayName);
26
+ keywords.push(keyword);
27
+ if (followSets.length && followSets.every((s) => isKeywordToken(s))) {
28
+ const followKeywords = followSets
29
+ .map((s) => cleanDisplayName(parser.vocabulary.getDisplayName(s)))
30
+ .filter(Boolean);
31
+ if (followKeywords.length) {
32
+ const combinedKeyword = [keyword, ...followKeywords].join(' ');
33
+ keywords.push(combinedKeyword);
34
+ }
35
+ }
36
+ }
37
+ return keywords;
38
+ }
@@ -41,7 +41,11 @@ export declare enum EntityContextType {
41
41
  /** column name */
42
42
  COLUMN = "column",
43
43
  /** column name that will be created */
44
- COLUMN_CREATE = "columnCreate"
44
+ COLUMN_CREATE = "columnCreate",
45
+ /** table property key when creating table*/
46
+ TABLE_PROPERTY_KEY = "tablePropertyKey",
47
+ /** table property value when creating table*/
48
+ TABLE_PROPERTY_VALUE = "tablePropertyValue"
45
49
  }
46
50
  /**
47
51
  * Suggested information analyzed from the input
@@ -64,3 +68,28 @@ export interface Suggestions<T = WordRange> {
64
68
  readonly keywords: string[];
65
69
  }
66
70
  export type LOCALE_TYPE = 'zh_CN' | 'en_US';
71
+ export interface SemanticContext {
72
+ isStatementBeginning: boolean;
73
+ }
74
+ export declare enum SqlSplitStrategy {
75
+ /** Only end the statement with semicolon symbol */
76
+ STRICT = 0,
77
+ /** Based on parse tree to split statements */
78
+ LOOSE = 1
79
+ }
80
+ export interface SemanticCollectOptions {
81
+ /**
82
+ * `sqlSplitStrategy` will affects the result of `isStatementBeginning`;
83
+ *
84
+ * For example:
85
+ *
86
+ * The sql is "select id from t1 create\<cart_position\>"
87
+ *
88
+ * - `SqlSplitStrategy.STRICT`: split symbol `;` is missing after select statement so that it considerd as one statement, and `isStatementBeginning` is false
89
+ *
90
+ * - `SqlSplitStrategy.LOOSE`: in parse tree, it will parse to "select id from t1" and "create" two single statement, so `isStatementBeginning` is true
91
+ *
92
+ * @default SqlSplitStrategy.STRICT
93
+ */
94
+ sqlSplitStrategy?: SqlSplitStrategy;
95
+ }
@@ -31,4 +31,15 @@ export var EntityContextType;
31
31
  EntityContextType["COLUMN"] = "column";
32
32
  /** column name that will be created */
33
33
  EntityContextType["COLUMN_CREATE"] = "columnCreate";
34
+ /** table property key when creating table*/
35
+ EntityContextType["TABLE_PROPERTY_KEY"] = "tablePropertyKey";
36
+ /** table property value when creating table*/
37
+ EntityContextType["TABLE_PROPERTY_VALUE"] = "tablePropertyValue";
34
38
  })(EntityContextType || (EntityContextType = {}));
39
+ export var SqlSplitStrategy;
40
+ (function (SqlSplitStrategy) {
41
+ /** Only end the statement with semicolon symbol */
42
+ SqlSplitStrategy[SqlSplitStrategy["STRICT"] = 0] = "STRICT";
43
+ /** Based on parse tree to split statements */
44
+ SqlSplitStrategy[SqlSplitStrategy["LOOSE"] = 1] = "LOOSE";
45
+ })(SqlSplitStrategy || (SqlSplitStrategy = {}));
@@ -14,8 +14,12 @@ export class FlinkErrorListener extends ParseErrorListener {
14
14
  [FlinkSqlParser.RULE_viewPath, 'view'],
15
15
  [FlinkSqlParser.RULE_viewPathCreate, 'view'],
16
16
  [FlinkSqlParser.RULE_functionName, 'function'],
17
+ [FlinkSqlParser.RULE_functionNameWithParams, 'function'],
18
+ [FlinkSqlParser.RULE_reservedKeywordsFollowParamsUsedAsFuncName, 'function'],
19
+ [FlinkSqlParser.RULE_reservedKeywordsNoParamsUsedAsFuncName, 'function'],
17
20
  [FlinkSqlParser.RULE_functionNameCreate, 'function'],
18
21
  [FlinkSqlParser.RULE_columnName, 'column'],
22
+ [FlinkSqlParser.RULE_columnNamePath, 'column'],
19
23
  [FlinkSqlParser.RULE_columnNameCreate, 'column'],
20
24
  ]);
21
25
  }
@@ -50,9 +54,15 @@ export class FlinkErrorListener extends ParseErrorListener {
50
54
  case FlinkSqlParser.RULE_tablePath:
51
55
  case FlinkSqlParser.RULE_viewPath:
52
56
  case FlinkSqlParser.RULE_functionName:
57
+ case FlinkSqlParser.RULE_functionNameWithParams:
58
+ case FlinkSqlParser.RULE_reservedKeywordsFollowParamsUsedAsFuncName:
59
+ case FlinkSqlParser.RULE_reservedKeywordsNoParamsUsedAsFuncName:
53
60
  case FlinkSqlParser.RULE_columnName:
61
+ case FlinkSqlParser.RULE_columnNamePath:
54
62
  case FlinkSqlParser.RULE_catalogPath: {
55
- result.push(`{existing}${name}`);
63
+ if (!result.includes(`{existing}${name}`)) {
64
+ result.push(`{existing}${name}`);
65
+ }
56
66
  break;
57
67
  }
58
68
  case FlinkSqlParser.RULE_databasePathCreate:
@@ -61,7 +71,9 @@ export class FlinkErrorListener extends ParseErrorListener {
61
71
  case FlinkSqlParser.RULE_viewPathCreate:
62
72
  case FlinkSqlParser.RULE_columnNameCreate:
63
73
  case FlinkSqlParser.RULE_catalogPathCreate: {
64
- result.push(`{new}${name}`);
74
+ if (!result.includes(`{new}${name}`)) {
75
+ result.push(`{new}${name}`);
76
+ }
65
77
  break;
66
78
  }
67
79
  }
@@ -0,0 +1,9 @@
1
+ import { FlinkSqlParserListener } from '../../lib';
2
+ import { SingleStatementContext } from '../../lib/flink/FlinkSqlParser';
3
+ import SemanticContextCollector from '../common/semanticContextCollector';
4
+ declare class FlinkSemanticContextCollector extends SemanticContextCollector implements FlinkSqlParserListener {
5
+ getWhiteSpaceRuleType(): number;
6
+ getStatementRuleType(): number;
7
+ enterSingleStatement(ctx: SingleStatementContext): void;
8
+ }
9
+ export { FlinkSemanticContextCollector };
@@ -0,0 +1,14 @@
1
+ import { FlinkSqlParser } from '../../lib/flink/FlinkSqlParser';
2
+ import SemanticContextCollector from '../common/semanticContextCollector';
3
+ class FlinkSemanticContextCollector extends SemanticContextCollector {
4
+ getWhiteSpaceRuleType() {
5
+ return FlinkSqlParser.WHITE_SPACE;
6
+ }
7
+ getStatementRuleType() {
8
+ return FlinkSqlParser.RULE_singleStatement;
9
+ }
10
+ enterSingleStatement(ctx) {
11
+ this.visitStatement(ctx);
12
+ }
13
+ }
14
+ export { FlinkSemanticContextCollector };
@@ -2,12 +2,13 @@ import { CandidatesCollection } from 'antlr4-c3';
2
2
  import { CharStream, CommonTokenStream, Token } from 'antlr4ng';
3
3
  import { FlinkSqlLexer } from '../../lib/flink/FlinkSqlLexer';
4
4
  import { FlinkSqlParser, ProgramContext } from '../../lib/flink/FlinkSqlParser';
5
+ import { CaretPosition, SemanticCollectOptions, Suggestions } from '../common/types';
5
6
  import { BasicSQL } from '../common/basicSQL';
6
7
  import { ErrorListener } from '../common/parseErrorListener';
7
- import { Suggestions } from '../common/types';
8
8
  import { FlinkEntityCollector } from './flinkEntityCollector';
9
9
  import { FlinkErrorListener } from './flinkErrorListener';
10
10
  import { FlinkSqlSplitListener } from './flinkSplitListener';
11
+ import { FlinkSemanticContextCollector } from './flinkSemanticContextCollector';
11
12
  export { FlinkEntityCollector, FlinkSqlSplitListener };
12
13
  export declare class FlinkSQL extends BasicSQL<FlinkSqlLexer, ProgramContext, FlinkSqlParser> {
13
14
  protected createLexerFromCharStream(charStreams: CharStream): FlinkSqlLexer;
@@ -16,5 +17,6 @@ export declare class FlinkSQL extends BasicSQL<FlinkSqlLexer, ProgramContext, Fl
16
17
  protected get splitListener(): FlinkSqlSplitListener;
17
18
  protected createErrorListener(_errorListener: ErrorListener): FlinkErrorListener;
18
19
  protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number): FlinkEntityCollector;
19
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
20
+ protected createSemanticContextCollector(input: string, caretPosition: CaretPosition, allTokens: Token[], options?: SemanticCollectOptions): FlinkSemanticContextCollector;
21
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
20
22
  }
@@ -1,10 +1,12 @@
1
+ import { processTokenCandidates } from '../common/tokenUtils';
1
2
  import { FlinkSqlLexer } from '../../lib/flink/FlinkSqlLexer';
2
3
  import { FlinkSqlParser } from '../../lib/flink/FlinkSqlParser';
4
+ import { EntityContextType, } from '../common/types';
3
5
  import { BasicSQL } from '../common/basicSQL';
4
- import { EntityContextType } from '../common/types';
5
6
  import { FlinkEntityCollector } from './flinkEntityCollector';
6
7
  import { FlinkErrorListener } from './flinkErrorListener';
7
8
  import { FlinkSqlSplitListener } from './flinkSplitListener';
9
+ import { FlinkSemanticContextCollector } from './flinkSemanticContextCollector';
8
10
  export { FlinkEntityCollector, FlinkSqlSplitListener };
9
11
  export class FlinkSQL extends BasicSQL {
10
12
  constructor() {
@@ -23,7 +25,10 @@ export class FlinkSQL extends BasicSQL {
23
25
  FlinkSqlParser.RULE_reservedKeywordsNoParamsUsedAsFuncName, // functionName
24
26
  FlinkSqlParser.RULE_functionNameCreate, // functionName that will be created
25
27
  FlinkSqlParser.RULE_columnName,
28
+ FlinkSqlParser.RULE_columnNamePath,
26
29
  FlinkSqlParser.RULE_columnNameCreate,
30
+ FlinkSqlParser.RULE_tablePropertyKey,
31
+ FlinkSqlParser.RULE_tablePropertyValue,
27
32
  ]);
28
33
  }
29
34
  createLexerFromCharStream(charStreams) {
@@ -42,13 +47,15 @@ export class FlinkSQL extends BasicSQL {
42
47
  createEntityCollector(input, allTokens, caretTokenIndex) {
43
48
  return new FlinkEntityCollector(input, allTokens, caretTokenIndex);
44
49
  }
45
- processCandidates(candidates, allTokens, caretTokenIndex, tokenIndexOffset) {
50
+ createSemanticContextCollector(input, caretPosition, allTokens, options) {
51
+ return new FlinkSemanticContextCollector(input, caretPosition, allTokens, options);
52
+ }
53
+ processCandidates(candidates, allTokens, caretTokenIndex) {
46
54
  const originalSyntaxSuggestions = [];
47
55
  const keywords = [];
48
56
  for (let candidate of candidates.rules) {
49
57
  const [ruleType, candidateRule] = candidate;
50
- const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
51
- const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + tokenIndexOffset + 1);
58
+ const tokenRanges = allTokens.slice(candidateRule.startTokenIndex, caretTokenIndex + 1);
52
59
  let syntaxContextType = void 0;
53
60
  switch (ruleType) {
54
61
  case FlinkSqlParser.RULE_catalogPath: {
@@ -98,6 +105,25 @@ export class FlinkSQL extends BasicSQL {
98
105
  syntaxContextType = EntityContextType.COLUMN_CREATE;
99
106
  break;
100
107
  }
108
+ case FlinkSqlParser.RULE_columnNamePath: {
109
+ if (candidateRule.ruleList.includes(FlinkSqlParser.RULE_selectClause) ||
110
+ candidateRule.ruleList.includes(FlinkSqlParser.RULE_whereClause) ||
111
+ candidateRule.ruleList.includes(FlinkSqlParser.RULE_groupByClause) ||
112
+ candidateRule.ruleList.includes(FlinkSqlParser.RULE_limitClause) ||
113
+ candidateRule.ruleList.includes(FlinkSqlParser.RULE_whenClause) ||
114
+ candidateRule.ruleList.includes(FlinkSqlParser.RULE_havingClause)) {
115
+ syntaxContextType = EntityContextType.COLUMN;
116
+ }
117
+ break;
118
+ }
119
+ case FlinkSqlParser.RULE_tablePropertyKey: {
120
+ syntaxContextType = EntityContextType.TABLE_PROPERTY_KEY;
121
+ break;
122
+ }
123
+ case FlinkSqlParser.RULE_tablePropertyValue: {
124
+ syntaxContextType = EntityContextType.TABLE_PROPERTY_VALUE;
125
+ break;
126
+ }
101
127
  default:
102
128
  break;
103
129
  }
@@ -108,16 +134,8 @@ export class FlinkSQL extends BasicSQL {
108
134
  });
109
135
  }
110
136
  }
111
- for (let candidate of candidates.tokens) {
112
- const symbolicName = this._parser.vocabulary.getSymbolicName(candidate[0]);
113
- const displayName = this._parser.vocabulary.getDisplayName(candidate[0]);
114
- if (displayName && symbolicName && symbolicName.startsWith('KW_')) {
115
- const keyword = displayName.startsWith("'") && displayName.endsWith("'")
116
- ? displayName.slice(1, -1)
117
- : displayName;
118
- keywords.push(keyword);
119
- }
120
- }
137
+ const processedKeywords = processTokenCandidates(this._parser, candidates.tokens);
138
+ keywords.push(...processedKeywords);
121
139
  return {
122
140
  syntax: originalSyntaxSuggestions,
123
141
  keywords,
@@ -16,6 +16,7 @@ export class HiveErrorListener extends ParseErrorListener {
16
16
  [HiveSqlParser.RULE_functionNameCreate, 'function'],
17
17
  [HiveSqlParser.RULE_columnName, 'column'],
18
18
  [HiveSqlParser.RULE_columnNameCreate, 'column'],
19
+ [HiveSqlParser.RULE_columnNamePath, 'column'],
19
20
  ]);
20
21
  }
21
22
  getExpectedText(parser, token) {
@@ -50,8 +51,11 @@ export class HiveErrorListener extends ParseErrorListener {
50
51
  case HiveSqlParser.RULE_viewName:
51
52
  case HiveSqlParser.RULE_functionNameForDDL:
52
53
  case HiveSqlParser.RULE_functionNameForInvoke:
53
- case HiveSqlParser.RULE_columnName: {
54
- result.push(`{existing}${name}`);
54
+ case HiveSqlParser.RULE_columnName:
55
+ case HiveSqlParser.RULE_columnNamePath: {
56
+ if (!result.includes(`{existing}${name}`)) {
57
+ result.push(`{existing}${name}`);
58
+ }
55
59
  break;
56
60
  }
57
61
  case HiveSqlParser.RULE_dbSchemaNameCreate:
@@ -59,7 +63,9 @@ export class HiveErrorListener extends ParseErrorListener {
59
63
  case HiveSqlParser.RULE_functionNameCreate:
60
64
  case HiveSqlParser.RULE_viewNameCreate:
61
65
  case HiveSqlParser.RULE_columnNameCreate: {
62
- result.push(`{new}${name}`);
66
+ if (!result.includes(`{new}${name}`)) {
67
+ result.push(`{new}${name}`);
68
+ }
63
69
  break;
64
70
  }
65
71
  }
@@ -0,0 +1,9 @@
1
+ import { HiveSqlParserListener } from '../../lib';
2
+ import { StatementContext } from '../../lib/hive/HiveSqlParser';
3
+ import SemanticContextCollector from '../common/semanticContextCollector';
4
+ declare class HiveSemanticContextCollector extends SemanticContextCollector implements HiveSqlParserListener {
5
+ getWhiteSpaceRuleType(): number;
6
+ getStatementRuleType(): number;
7
+ enterStatement(ctx: StatementContext): void;
8
+ }
9
+ export { HiveSemanticContextCollector };
@@ -0,0 +1,14 @@
1
+ import { HiveSqlParser } from '../../lib/hive/HiveSqlParser';
2
+ import SemanticContextCollector from '../common/semanticContextCollector';
3
+ class HiveSemanticContextCollector extends SemanticContextCollector {
4
+ getWhiteSpaceRuleType() {
5
+ return HiveSqlParser.WHITE_SPACE;
6
+ }
7
+ getStatementRuleType() {
8
+ return HiveSqlParser.RULE_statement;
9
+ }
10
+ enterStatement(ctx) {
11
+ this.visitStatement(ctx);
12
+ }
13
+ }
14
+ export { HiveSemanticContextCollector };
@@ -3,11 +3,12 @@ import { CharStream, CommonTokenStream, Token } from 'antlr4ng';
3
3
  import { HiveSqlLexer } from '../../lib/hive/HiveSqlLexer';
4
4
  import { HiveSqlParser, ProgramContext } from '../../lib/hive/HiveSqlParser';
5
5
  import { BasicSQL } from '../common/basicSQL';
6
+ import { CaretPosition, SemanticCollectOptions, Suggestions } from '../common/types';
6
7
  import { ErrorListener } from '../common/parseErrorListener';
7
- import { Suggestions } from '../common/types';
8
8
  import { HiveEntityCollector } from './hiveEntityCollector';
9
9
  import { HiveErrorListener } from './hiveErrorListener';
10
10
  import { HiveSqlSplitListener } from './hiveSplitListener';
11
+ import { HiveSemanticContextCollector } from './hiveSemanticContextCollector';
11
12
  export { HiveEntityCollector, HiveSqlSplitListener };
12
13
  export declare class HiveSQL extends BasicSQL<HiveSqlLexer, ProgramContext, HiveSqlParser> {
13
14
  protected createLexerFromCharStream(charStreams: CharStream): HiveSqlLexer;
@@ -16,5 +17,6 @@ export declare class HiveSQL extends BasicSQL<HiveSqlLexer, ProgramContext, Hive
16
17
  protected get splitListener(): HiveSqlSplitListener;
17
18
  protected createErrorListener(_errorListener: ErrorListener): HiveErrorListener;
18
19
  protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number): HiveEntityCollector;
19
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
20
+ protected createSemanticContextCollector(input: string, caretPosition: CaretPosition, allTokens: Token[], options?: SemanticCollectOptions): HiveSemanticContextCollector;
21
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
20
22
  }
@@ -1,10 +1,12 @@
1
+ import { processTokenCandidates } from '../common/tokenUtils';
1
2
  import { HiveSqlLexer } from '../../lib/hive/HiveSqlLexer';
2
3
  import { HiveSqlParser } from '../../lib/hive/HiveSqlParser';
3
4
  import { BasicSQL } from '../common/basicSQL';
4
- import { EntityContextType } from '../common/types';
5
+ import { EntityContextType, } from '../common/types';
5
6
  import { HiveEntityCollector } from './hiveEntityCollector';
6
7
  import { HiveErrorListener } from './hiveErrorListener';
7
8
  import { HiveSqlSplitListener } from './hiveSplitListener';
9
+ import { HiveSemanticContextCollector } from './hiveSemanticContextCollector';
8
10
  export { HiveEntityCollector, HiveSqlSplitListener };
9
11
  export class HiveSQL extends BasicSQL {
10
12
  constructor() {
@@ -20,6 +22,7 @@ export class HiveSQL extends BasicSQL {
20
22
  HiveSqlParser.RULE_functionNameForInvoke, // function name
21
23
  HiveSqlParser.RULE_functionNameCreate, // function name that will be created
22
24
  HiveSqlParser.RULE_columnName,
25
+ HiveSqlParser.RULE_columnNamePath,
23
26
  HiveSqlParser.RULE_columnNameCreate,
24
27
  ]);
25
28
  }
@@ -39,13 +42,15 @@ export class HiveSQL extends BasicSQL {
39
42
  createEntityCollector(input, allTokens, caretTokenIndex) {
40
43
  return new HiveEntityCollector(input, allTokens, caretTokenIndex);
41
44
  }
42
- processCandidates(candidates, allTokens, caretTokenIndex, tokenIndexOffset) {
45
+ createSemanticContextCollector(input, caretPosition, allTokens, options) {
46
+ return new HiveSemanticContextCollector(input, caretPosition, allTokens, options);
47
+ }
48
+ processCandidates(candidates, allTokens, caretTokenIndex) {
43
49
  const originalSyntaxSuggestions = [];
44
50
  const keywords = [];
45
51
  for (let candidate of candidates.rules) {
46
52
  const [ruleType, candidateRule] = candidate;
47
- const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
48
- const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + tokenIndexOffset + 1);
53
+ const tokenRanges = allTokens.slice(candidateRule.startTokenIndex, caretTokenIndex + 1);
49
54
  let syntaxContextType = void 0;
50
55
  switch (ruleType) {
51
56
  case HiveSqlParser.RULE_dbSchemaName: {
@@ -89,6 +94,24 @@ export class HiveSQL extends BasicSQL {
89
94
  syntaxContextType = EntityContextType.COLUMN_CREATE;
90
95
  break;
91
96
  }
97
+ case HiveSqlParser.RULE_columnNamePath: {
98
+ if (candidateRule.ruleList.includes(HiveSqlParser.RULE_orderByClause) ||
99
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_havingClause) ||
100
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_groupByClause) ||
101
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_sortByClause) ||
102
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_whereClause) ||
103
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_qualifyClause) ||
104
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_clusterByClause) ||
105
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_distributeByClause) ||
106
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_selectClause) ||
107
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_joinSource) ||
108
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_caseExpression) ||
109
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_whenExpression) ||
110
+ candidateRule.ruleList.includes(HiveSqlParser.RULE_castExpression)) {
111
+ syntaxContextType = EntityContextType.COLUMN;
112
+ }
113
+ break;
114
+ }
92
115
  default:
93
116
  break;
94
117
  }
@@ -99,16 +122,8 @@ export class HiveSQL extends BasicSQL {
99
122
  });
100
123
  }
101
124
  }
102
- for (let candidate of candidates.tokens) {
103
- const symbolicName = this._parser.vocabulary.getSymbolicName(candidate[0]);
104
- const displayName = this._parser.vocabulary.getDisplayName(candidate[0]);
105
- if (displayName && symbolicName && symbolicName.startsWith('KW_')) {
106
- const keyword = displayName.startsWith("'") && displayName.endsWith("'")
107
- ? displayName.slice(1, -1)
108
- : displayName;
109
- keywords.push(keyword);
110
- }
111
- }
125
+ const processedKeywords = processTokenCandidates(this._parser, candidates.tokens);
126
+ keywords.push(...processedKeywords);
112
127
  return {
113
128
  syntax: originalSyntaxSuggestions,
114
129
  keywords,
@@ -13,6 +13,7 @@ export class ImpalaErrorListener extends ParseErrorListener {
13
13
  [ImpalaSqlParser.RULE_viewNameCreate, 'view'],
14
14
  [ImpalaSqlParser.RULE_functionNamePath, 'function'],
15
15
  [ImpalaSqlParser.RULE_functionNameCreate, 'function'],
16
+ [ImpalaSqlParser.RULE_columnName, 'column'],
16
17
  [ImpalaSqlParser.RULE_columnNamePath, 'column'],
17
18
  [ImpalaSqlParser.RULE_columnNamePathCreate, 'column'],
18
19
  ]);
@@ -48,8 +49,11 @@ export class ImpalaErrorListener extends ParseErrorListener {
48
49
  case ImpalaSqlParser.RULE_tableNamePath:
49
50
  case ImpalaSqlParser.RULE_functionNamePath:
50
51
  case ImpalaSqlParser.RULE_viewNamePath:
52
+ case ImpalaSqlParser.RULE_columnName:
51
53
  case ImpalaSqlParser.RULE_columnNamePath: {
52
- result.push(`{existing}${name}`);
54
+ if (!result.includes(`{existing}${name}`)) {
55
+ result.push(`{existing}${name}`);
56
+ }
53
57
  break;
54
58
  }
55
59
  case ImpalaSqlParser.RULE_databaseNameCreate:
@@ -57,7 +61,9 @@ export class ImpalaErrorListener extends ParseErrorListener {
57
61
  case ImpalaSqlParser.RULE_functionNameCreate:
58
62
  case ImpalaSqlParser.RULE_viewNameCreate:
59
63
  case ImpalaSqlParser.RULE_columnNamePathCreate: {
60
- result.push(`{new}${name}`);
64
+ if (!result.includes(`{new}${name}`)) {
65
+ result.push(`{new}${name}`);
66
+ }
61
67
  break;
62
68
  }
63
69
  }
@@ -0,0 +1,9 @@
1
+ import { ImpalaSqlParserListener } from '../../lib';
2
+ import { SingleStatementContext } from '../../lib/impala/ImpalaSqlParser';
3
+ import SemanticContextCollector from '../common/semanticContextCollector';
4
+ declare class ImpalaSemanticContextCollector extends SemanticContextCollector implements ImpalaSqlParserListener {
5
+ getWhiteSpaceRuleType(): number;
6
+ getStatementRuleType(): number;
7
+ enterSingleStatement(ctx: SingleStatementContext): void;
8
+ }
9
+ export { ImpalaSemanticContextCollector };
@@ -0,0 +1,14 @@
1
+ import { ImpalaSqlParser } from '../../lib/impala/ImpalaSqlParser';
2
+ import SemanticContextCollector from '../common/semanticContextCollector';
3
+ class ImpalaSemanticContextCollector extends SemanticContextCollector {
4
+ getWhiteSpaceRuleType() {
5
+ return ImpalaSqlParser.WHITE_SPACE;
6
+ }
7
+ getStatementRuleType() {
8
+ return ImpalaSqlParser.RULE_singleStatement;
9
+ }
10
+ enterSingleStatement(ctx) {
11
+ this.visitStatement(ctx);
12
+ }
13
+ }
14
+ export { ImpalaSemanticContextCollector };
@@ -3,11 +3,12 @@ import { CharStream, CommonTokenStream, Token } from 'antlr4ng';
3
3
  import { ImpalaSqlLexer } from '../../lib/impala/ImpalaSqlLexer';
4
4
  import { ImpalaSqlParser, ProgramContext } from '../../lib/impala/ImpalaSqlParser';
5
5
  import { BasicSQL } from '../common/basicSQL';
6
+ import { CaretPosition, SemanticCollectOptions, Suggestions } from '../common/types';
6
7
  import { ErrorListener } from '../common/parseErrorListener';
7
- import { Suggestions } from '../common/types';
8
8
  import { ImpalaEntityCollector } from './impalaEntityCollector';
9
9
  import { ImpalaErrorListener } from './ImpalaErrorListener';
10
10
  import { ImpalaSqlSplitListener } from './impalaSplitListener';
11
+ import { ImpalaSemanticContextCollector } from './impalaSemanticContextCollector';
11
12
  export { ImpalaEntityCollector, ImpalaSqlSplitListener };
12
13
  export declare class ImpalaSQL extends BasicSQL<ImpalaSqlLexer, ProgramContext, ImpalaSqlParser> {
13
14
  protected createLexerFromCharStream(charStreams: CharStream): ImpalaSqlLexer;
@@ -16,5 +17,6 @@ export declare class ImpalaSQL extends BasicSQL<ImpalaSqlLexer, ProgramContext,
16
17
  protected get splitListener(): ImpalaSqlSplitListener;
17
18
  protected createErrorListener(_errorListener: ErrorListener): ImpalaErrorListener;
18
19
  protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number): ImpalaEntityCollector;
19
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
20
+ protected createSemanticContextCollector(input: string, caretPosition: CaretPosition, allTokens: Token[], options?: SemanticCollectOptions): ImpalaSemanticContextCollector;
21
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
20
22
  }
@@ -1,10 +1,12 @@
1
+ import { processTokenCandidates } from '../common/tokenUtils';
1
2
  import { ImpalaSqlLexer } from '../../lib/impala/ImpalaSqlLexer';
2
3
  import { ImpalaSqlParser } from '../../lib/impala/ImpalaSqlParser';
3
4
  import { BasicSQL } from '../common/basicSQL';
4
- import { EntityContextType } from '../common/types';
5
+ import { EntityContextType, } from '../common/types';
5
6
  import { ImpalaEntityCollector } from './impalaEntityCollector';
6
7
  import { ImpalaErrorListener } from './ImpalaErrorListener';
7
8
  import { ImpalaSqlSplitListener } from './impalaSplitListener';
9
+ import { ImpalaSemanticContextCollector } from './impalaSemanticContextCollector';
8
10
  export { ImpalaEntityCollector, ImpalaSqlSplitListener };
9
11
  export class ImpalaSQL extends BasicSQL {
10
12
  constructor() {
@@ -20,6 +22,7 @@ export class ImpalaSQL extends BasicSQL {
20
22
  ImpalaSqlParser.RULE_viewNamePath,
21
23
  ImpalaSqlParser.RULE_databaseNamePath,
22
24
  ImpalaSqlParser.RULE_columnNamePath,
25
+ ImpalaSqlParser.RULE_columnName,
23
26
  ]);
24
27
  }
25
28
  createLexerFromCharStream(charStreams) {
@@ -38,13 +41,15 @@ export class ImpalaSQL extends BasicSQL {
38
41
  createEntityCollector(input, allTokens, caretTokenIndex) {
39
42
  return new ImpalaEntityCollector(input, allTokens, caretTokenIndex);
40
43
  }
41
- processCandidates(candidates, allTokens, caretTokenIndex, tokenIndexOffset) {
44
+ createSemanticContextCollector(input, caretPosition, allTokens, options) {
45
+ return new ImpalaSemanticContextCollector(input, caretPosition, allTokens, options);
46
+ }
47
+ processCandidates(candidates, allTokens, caretTokenIndex) {
42
48
  const originalSyntaxSuggestions = [];
43
49
  const keywords = [];
44
50
  for (let candidate of candidates.rules) {
45
51
  const [ruleType, candidateRule] = candidate;
46
- const startTokenIndex = candidateRule.startTokenIndex + tokenIndexOffset;
47
- const tokenRanges = allTokens.slice(startTokenIndex, caretTokenIndex + tokenIndexOffset + 1);
52
+ const tokenRanges = allTokens.slice(candidateRule.startTokenIndex, caretTokenIndex + 1);
48
53
  let syntaxContextType = void 0;
49
54
  switch (ruleType) {
50
55
  case ImpalaSqlParser.RULE_functionNameCreate: {
@@ -86,6 +91,16 @@ export class ImpalaSQL extends BasicSQL {
86
91
  case ImpalaSqlParser.RULE_columnNamePath: {
87
92
  syntaxContextType = EntityContextType.COLUMN;
88
93
  }
94
+ case ImpalaSqlParser.RULE_columnName: {
95
+ if (candidateRule.ruleList.includes(ImpalaSqlParser.RULE_columnItem) ||
96
+ candidateRule.ruleList.includes(ImpalaSqlParser.RULE_havingClause) ||
97
+ candidateRule.ruleList.includes(ImpalaSqlParser.RULE_whereClause) ||
98
+ candidateRule.ruleList.includes(ImpalaSqlParser.RULE_whenClause) ||
99
+ candidateRule.ruleList.includes(ImpalaSqlParser.RULE_partitionByClause) ||
100
+ candidateRule.ruleList.includes(ImpalaSqlParser.RULE_relation)) {
101
+ syntaxContextType = EntityContextType.COLUMN;
102
+ }
103
+ }
89
104
  default:
90
105
  break;
91
106
  }
@@ -96,16 +111,8 @@ export class ImpalaSQL extends BasicSQL {
96
111
  });
97
112
  }
98
113
  }
99
- for (let candidate of candidates.tokens) {
100
- const symbolicName = this._parser.vocabulary.getSymbolicName(candidate[0]);
101
- const displayName = this._parser.vocabulary.getDisplayName(candidate[0]);
102
- if (displayName && symbolicName && symbolicName.startsWith('KW_')) {
103
- const keyword = displayName.startsWith("'") && displayName.endsWith("'")
104
- ? displayName.slice(1, -1)
105
- : displayName;
106
- keywords.push(keyword);
107
- }
108
- }
114
+ const processedKeywords = processTokenCandidates(this._parser, candidates.tokens);
115
+ keywords.push(...processedKeywords);
109
116
  return {
110
117
  syntax: originalSyntaxSuggestions,
111
118
  keywords,
@@ -3,11 +3,12 @@ import { CharStream, CommonTokenStream, Token } from 'antlr4ng';
3
3
  import { MySqlLexer } from '../../lib/mysql/MySqlLexer';
4
4
  import { MySqlParser, ProgramContext } from '../../lib/mysql/MySqlParser';
5
5
  import { BasicSQL } from '../common/basicSQL';
6
+ import { Suggestions, CaretPosition, SemanticCollectOptions } from '../common/types';
6
7
  import { ErrorListener } from '../common/parseErrorListener';
7
- import { Suggestions } from '../common/types';
8
8
  import { MySqlEntityCollector } from './mysqlEntityCollector';
9
9
  import { MysqlErrorListener } from './mysqlErrorListener';
10
10
  import { MysqlSplitListener } from './mysqlSplitListener';
11
+ import { MySqlSemanticContextCollector } from '../mysql/mysqlSemanticContextCollector';
11
12
  export { MySqlEntityCollector, MysqlSplitListener };
12
13
  export declare class MySQL extends BasicSQL<MySqlLexer, ProgramContext, MySqlParser> {
13
14
  protected createLexerFromCharStream(charStreams: CharStream): MySqlLexer;
@@ -16,5 +17,6 @@ export declare class MySQL extends BasicSQL<MySqlLexer, ProgramContext, MySqlPar
16
17
  protected get splitListener(): MysqlSplitListener;
17
18
  protected createErrorListener(_errorListener: ErrorListener): MysqlErrorListener;
18
19
  protected createEntityCollector(input: string, allTokens?: Token[], caretTokenIndex?: number): MySqlEntityCollector;
19
- protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number, tokenIndexOffset: number): Suggestions<Token>;
20
+ protected createSemanticContextCollector(input: string, caretPosition: CaretPosition, allTokens: Token[], options?: SemanticCollectOptions): MySqlSemanticContextCollector;
21
+ protected processCandidates(candidates: CandidatesCollection, allTokens: Token[], caretTokenIndex: number): Suggestions<Token>;
20
22
  }