dt-sql-parser 4.5.1-beta.1 → 4.5.1-beta.3

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.
@@ -138,8 +138,6 @@ import { RelationDefaultContext } from "./TrinoSqlParser.js";
138
138
  import { JoinRelationContext } from "./TrinoSqlParser.js";
139
139
  import { JoinTypeContext } from "./TrinoSqlParser.js";
140
140
  import { JoinCriteriaContext } from "./TrinoSqlParser.js";
141
- import { JoinColumnEqualityContext } from "./TrinoSqlParser.js";
142
- import { JoinColumnReferenceContext } from "./TrinoSqlParser.js";
143
141
  import { SampledRelationContext } from "./TrinoSqlParser.js";
144
142
  import { SampleTypeContext } from "./TrinoSqlParser.js";
145
143
  import { TrimsSpecificationContext } from "./TrinoSqlParser.js";
@@ -358,7 +356,6 @@ import { CatalogNameCreateContext } from "./TrinoSqlParser.js";
358
356
  import { FunctionNameContext } from "./TrinoSqlParser.js";
359
357
  import { FunctionNameCreateContext } from "./TrinoSqlParser.js";
360
358
  import { ColumnRefContext } from "./TrinoSqlParser.js";
361
- import { EmptyColumnContext } from "./TrinoSqlParser.js";
362
359
  import { ColumnNameContext } from "./TrinoSqlParser.js";
363
360
  import { ColumnNameCreateContext } from "./TrinoSqlParser.js";
364
361
  import { QualifiedNameContext } from "./TrinoSqlParser.js";
@@ -1323,18 +1320,6 @@ export declare class TrinoSqlVisitor<Result> extends AbstractParseTreeVisitor<Re
1323
1320
  * @return the visitor result
1324
1321
  */
1325
1322
  visitJoinCriteria?: (ctx: JoinCriteriaContext) => Result;
1326
- /**
1327
- * Visit a parse tree produced by `TrinoSqlParser.joinColumnEquality`.
1328
- * @param ctx the parse tree
1329
- * @return the visitor result
1330
- */
1331
- visitJoinColumnEquality?: (ctx: JoinColumnEqualityContext) => Result;
1332
- /**
1333
- * Visit a parse tree produced by `TrinoSqlParser.joinColumnReference`.
1334
- * @param ctx the parse tree
1335
- * @return the visitor result
1336
- */
1337
- visitJoinColumnReference?: (ctx: JoinColumnReferenceContext) => Result;
1338
1323
  /**
1339
1324
  * Visit a parse tree produced by `TrinoSqlParser.sampledRelation`.
1340
1325
  * @param ctx the parse tree
@@ -2784,12 +2769,6 @@ export declare class TrinoSqlVisitor<Result> extends AbstractParseTreeVisitor<Re
2784
2769
  * @return the visitor result
2785
2770
  */
2786
2771
  visitColumnRef?: (ctx: ColumnRefContext) => Result;
2787
- /**
2788
- * Visit a parse tree produced by `TrinoSqlParser.emptyColumn`.
2789
- * @param ctx the parse tree
2790
- * @return the visitor result
2791
- */
2792
- visitEmptyColumn?: (ctx: EmptyColumnContext) => Result;
2793
2772
  /**
2794
2773
  * Visit a parse tree produced by `TrinoSqlParser.columnName`.
2795
2774
  * @param ctx the parse tree
@@ -7,7 +7,7 @@ import { ErrorListener, ParseError } from './parseErrorListener';
7
7
  import SemanticContextCollector from './semanticContextCollector';
8
8
  import type { SplitListener } from './splitListener';
9
9
  import { TextSlice } from './textAndWord';
10
- import { CaretPosition, LOCALE_TYPE, SemanticCollectOptions, Suggestions } from './types';
10
+ import { CaretPosition, LOCALE_TYPE, SemanticCollectOptions, SuggestionOptions, Suggestions } from './types';
11
11
  export declare const SQL_SPLIT_SYMBOL_TEXT = ";";
12
12
  /**
13
13
  * Basic SQL class, every sql needs extends it.
@@ -21,6 +21,7 @@ export declare abstract class BasicSQL<L extends Lexer = Lexer, PRC extends Pars
21
21
  protected _parseTree: PRC | null;
22
22
  protected _parsedInput: string;
23
23
  protected _parseErrors: ParseError[];
24
+ private _statementStartTokenTypes;
24
25
  /** members for cache end */
25
26
  private _errorListener;
26
27
  /**
@@ -166,13 +167,22 @@ export declare abstract class BasicSQL<L extends Lexer = Lexer, PRC extends Pars
166
167
  tokenIndexOffset: number;
167
168
  newTokenIndex: number;
168
169
  } | null;
170
+ /**
171
+ * Get the minimum statement tree for collecting completion candidates
172
+ */
173
+ private getSuggestionParseTree;
174
+ /**
175
+ * Collect candidates for the current statement and remove new-statement-only keywords
176
+ */
177
+ private collectSuggestionCandidates;
169
178
  /**
170
179
  * Get suggestions of syntax and token at caretPosition
171
180
  * @param input source string
172
181
  * @param caretPosition caret position, such as cursor position
182
+ * @param options suggestion options
173
183
  * @returns suggestion
174
184
  */
175
- getSuggestionAtCaretPosition(input: string, caretPosition: CaretPosition): Suggestions | null;
185
+ getSuggestionAtCaretPosition(input: string, caretPosition: CaretPosition, options?: SuggestionOptions): Suggestions | null;
176
186
  getAllEntities(input: string, caretPosition?: CaretPosition): EntityContext[] | null;
177
187
  /**
178
188
  * Get semantic context infos
@@ -1,5 +1,5 @@
1
1
  import { CodeCompletionCore } from 'antlr4-c3';
2
- import { CharStreams, CommonTokenStream, ParseTreeWalker, PredictionMode, } from 'antlr4ng';
2
+ import { CharStreams, CommonTokenStream, ParserRuleContext, ParseTreeWalker, PredictionMode, } from 'antlr4ng';
3
3
  import { ErrorStrategy } from './errorStrategy';
4
4
  import { findCaretTokenIndex } from './findCaretTokenIndex';
5
5
  import { ctxToText, tokenToWord } from './textAndWord';
@@ -10,6 +10,7 @@ export const SQL_SPLIT_SYMBOL_TEXT = ';';
10
10
  export class BasicSQL {
11
11
  constructor() {
12
12
  this._parseErrors = [];
13
+ this._statementStartTokenTypes = null;
13
14
  /** members for cache end */
14
15
  this._errorListener = (error) => {
15
16
  this._parseErrors.push(error);
@@ -384,13 +385,74 @@ export class BasicSQL {
384
385
  newTokenIndex: caretTokenIndex,
385
386
  };
386
387
  }
388
+ /**
389
+ * Get the minimum statement tree for collecting completion candidates
390
+ */
391
+ getSuggestionParseTree(parseTree, caretTokenIndex) {
392
+ var _a, _b, _c;
393
+ const children = parseTree.children;
394
+ if (!(children === null || children === void 0 ? void 0 : children.length))
395
+ return parseTree;
396
+ for (let index = children.length - 1; index >= 0; index--) {
397
+ const child = children[index];
398
+ if (!(child instanceof ParserRuleContext))
399
+ continue;
400
+ const startTokenIndex = (_a = child.start) === null || _a === void 0 ? void 0 : _a.tokenIndex;
401
+ const stopTokenIndex = (_b = child.stop) === null || _b === void 0 ? void 0 : _b.tokenIndex;
402
+ if (startTokenIndex === undefined ||
403
+ stopTokenIndex === undefined ||
404
+ startTokenIndex > caretTokenIndex)
405
+ continue;
406
+ // Use the current statement tree when the caret is inside it
407
+ if (stopTokenIndex >= caretTokenIndex)
408
+ return child;
409
+ // Keep using the current statement until it ends with a semicolon
410
+ return ((_c = child.stop) === null || _c === void 0 ? void 0 : _c.text) === SQL_SPLIT_SYMBOL_TEXT ? parseTree : child;
411
+ }
412
+ return parseTree;
413
+ }
414
+ /**
415
+ * Collect candidates for the current statement and remove new-statement-only keywords
416
+ */
417
+ collectSuggestionCandidates(parser, parseTree, caretTokenIndex) {
418
+ const core = new CodeCompletionCore(parser);
419
+ core.preferredRules = this.preferredRules;
420
+ const candidates = core.collectCandidates(caretTokenIndex, parseTree);
421
+ const suggestionParseTree = this.getSuggestionParseTree(parseTree, caretTokenIndex);
422
+ if (suggestionParseTree === parseTree)
423
+ return candidates;
424
+ const statementCore = new CodeCompletionCore(parser);
425
+ statementCore.preferredRules = this.preferredRules;
426
+ const statementCandidates = statementCore.collectCandidates(caretTokenIndex, suggestionParseTree);
427
+ if (this._statementStartTokenTypes === null) {
428
+ const statementStartCore = new CodeCompletionCore(parser);
429
+ statementStartCore.preferredRules = this.preferredRules;
430
+ const statementStartCandidates = statementStartCore.collectCandidates(0, parseTree);
431
+ this._statementStartTokenTypes = new Set(statementStartCandidates.tokens.keys());
432
+ }
433
+ const tokens = new Map(candidates.tokens);
434
+ for (const tokenType of this._statementStartTokenTypes) {
435
+ if (!statementCandidates.tokens.has(tokenType)) {
436
+ tokens.delete(tokenType);
437
+ }
438
+ else if (tokens.has(tokenType)) {
439
+ // Use the current statement follow-list to preserve valid combined keywords
440
+ tokens.set(tokenType, statementCandidates.tokens.get(tokenType));
441
+ }
442
+ }
443
+ return {
444
+ rules: candidates.rules,
445
+ tokens,
446
+ };
447
+ }
387
448
  /**
388
449
  * Get suggestions of syntax and token at caretPosition
389
450
  * @param input source string
390
451
  * @param caretPosition caret position, such as cursor position
452
+ * @param options suggestion options
391
453
  * @returns suggestion
392
454
  */
393
- getSuggestionAtCaretPosition(input, caretPosition) {
455
+ getSuggestionAtCaretPosition(input, caretPosition, options) {
394
456
  this.parseWithCache(input);
395
457
  if (!this._parseTree)
396
458
  return null;
@@ -428,11 +490,7 @@ export class BasicSQL {
428
490
  sqlParserIns = this.createParser(inputSlice);
429
491
  parseTree = sqlParserIns.program();
430
492
  }
431
- const core = new CodeCompletionCore(sqlParserIns);
432
- core.preferredRules = this.preferredRules;
433
- // core.showRuleStack = true;
434
- // core.showResult = true;
435
- const candidates = core.collectCandidates(caretTokenIndex, parseTree);
493
+ const candidates = this.collectSuggestionCandidates(sqlParserIns, parseTree, caretTokenIndex);
436
494
  const originalSuggestions = this.processCandidates(candidates, allTokens, caretTokenIndex);
437
495
  const syntaxSuggestions = originalSuggestions.syntax.map((syntaxCtx) => {
438
496
  const wordRanges = syntaxCtx.wordRanges.map((token) => {
@@ -443,9 +501,13 @@ export class BasicSQL {
443
501
  wordRanges,
444
502
  };
445
503
  });
504
+ const keywordFilter = options === null || options === void 0 ? void 0 : options.keywordFilter;
505
+ const keywords = keywordFilter
506
+ ? originalSuggestions.keywords.filter((keyword) => keywordFilter(keyword))
507
+ : originalSuggestions.keywords;
446
508
  return {
447
509
  syntax: syntaxSuggestions,
448
- keywords: originalSuggestions.keywords,
510
+ keywords,
449
511
  };
450
512
  }
451
513
  getAllEntities(input, caretPosition) {
@@ -69,6 +69,15 @@ export interface Suggestions<T = WordRange> {
69
69
  */
70
70
  readonly keywords: string[];
71
71
  }
72
+ /**
73
+ * Suggested information options
74
+ */
75
+ export interface SuggestionOptions {
76
+ /**
77
+ * Return true to keep the keyword, otherwise remove it
78
+ */
79
+ keywordFilter?: (keyword: string) => boolean;
80
+ }
72
81
  export type LOCALE_TYPE = 'zh_CN' | 'en_US';
73
82
  export interface SemanticContext {
74
83
  isStatementBeginning: boolean;
@@ -26,7 +26,6 @@ export class MySQL extends BasicSQL {
26
26
  MySqlParser.RULE_functionNameCreate,
27
27
  MySqlParser.RULE_columnName,
28
28
  MySqlParser.RULE_columnNamePath,
29
- MySqlParser.RULE_columnNamePathAllowEmpty,
30
29
  MySqlParser.RULE_columnNameCreate,
31
30
  ...this.excludeKeywordRules,
32
31
  ]);
@@ -95,16 +94,6 @@ export class MySQL extends BasicSQL {
95
94
  syntaxContextType = EntityContextType.COLUMN;
96
95
  break;
97
96
  }
98
- case MySqlParser.RULE_columnNamePathAllowEmpty: {
99
- if (candidateRule.ruleList.includes(MySqlParser.RULE_joinSpec) ||
100
- candidateRule.ruleList.includes(MySqlParser.RULE_fromClause) ||
101
- candidateRule.ruleList.includes(MySqlParser.RULE_orderByExpression) ||
102
- candidateRule.ruleList.includes(MySqlParser.RULE_groupByItem) ||
103
- candidateRule.ruleList.includes(MySqlParser.RULE_havingClause)) {
104
- syntaxContextType = EntityContextType.COLUMN;
105
- }
106
- break;
107
- }
108
97
  case MySqlParser.RULE_columnNameCreate: {
109
98
  syntaxContextType = EntityContextType.COLUMN_CREATE;
110
99
  break;
@@ -1,4 +1,4 @@
1
- import { ColumnCreateTableContext, ColumnNameCreateContext, CopyCreateTableContext, CreateDatabaseContext, CreateFunctionContext, CreateFunctionLoadableContext, CreateViewContext, DatabaseNameContext, DatabaseNameCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryCreateTableContext, SelectElementsContext, SelectExpressionElementContext, SelectLiteralColumnNameContext, SelectStatementContext, SingleStatementContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext, TableAllColumnsContext, AtomSubQueryTableSourceContext, PureAllColumnsContext, SelectElement_dot_emptyContext, ColumnNamePath_dot_emptyContext } from '../../lib/mysql/MySqlParser';
1
+ import { ColumnCreateTableContext, ColumnNameCreateContext, CopyCreateTableContext, CreateDatabaseContext, CreateFunctionContext, CreateFunctionLoadableContext, CreateViewContext, DatabaseNameContext, DatabaseNameCreateContext, FunctionNameCreateContext, InsertStatementContext, QueryCreateTableContext, SelectElementsContext, SelectExpressionElementContext, SelectLiteralColumnNameContext, SelectStatementContext, SingleStatementContext, TableNameContext, TableNameCreateContext, ViewNameContext, ViewNameCreateContext, TableAllColumnsContext, AtomSubQueryTableSourceContext, PureAllColumnsContext, SelectElement_dot_emptyContext } from '../../lib/mysql/MySqlParser';
2
2
  import type { MySqlParserListener } from '../../lib/mysql/MySqlParserListener';
3
3
  import { EntityCollector } from '../common/entityCollector';
4
4
  export declare class MySqlEntityCollector extends EntityCollector implements MySqlParserListener {
@@ -19,7 +19,6 @@ export declare class MySqlEntityCollector extends EntityCollector implements MyS
19
19
  exitPureAllColumns(ctx: PureAllColumnsContext): void;
20
20
  exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
21
21
  exitSelectElement_dot_empty(ctx: SelectElement_dot_emptyContext): void;
22
- exitColumnNamePath_dot_empty(ctx: ColumnNamePath_dot_emptyContext): void;
23
22
  exitSelectExpressionElement(ctx: SelectExpressionElementContext): void;
24
23
  /** ===== Statement begin */
25
24
  enterSingleStatement(ctx: SingleStatementContext): void;
@@ -98,11 +98,6 @@ export class MySqlEntityCollector extends EntityCollector {
98
98
  declareType: ColumnDeclareType.LITERAL,
99
99
  });
100
100
  }
101
- exitColumnNamePath_dot_empty(ctx) {
102
- this.pushEntity(ctx, EntityContextType.COLUMN, [], {
103
- declareType: ColumnDeclareType.LITERAL,
104
- });
105
- }
106
101
  exitSelectExpressionElement(ctx) {
107
102
  this.pushEntity(ctx, EntityContextType.COLUMN, [
108
103
  {
@@ -130,8 +130,7 @@ export class PostgreSQL extends BasicSQL {
130
130
  candidateRule.ruleList.includes(PostgreSqlParser.RULE_whereClause) ||
131
131
  candidateRule.ruleList.includes(PostgreSqlParser.RULE_havingClause) ||
132
132
  candidateRule.ruleList.includes(PostgreSqlParser.RULE_windowClause) ||
133
- candidateRule.ruleList.includes(PostgreSqlParser.RULE_triggerWhen) ||
134
- candidateRule.ruleList.includes(PostgreSqlParser.RULE_joinQual)) {
133
+ candidateRule.ruleList.includes(PostgreSqlParser.RULE_triggerWhen)) {
135
134
  syntaxContextType = EntityContextType.COLUMN;
136
135
  }
137
136
  break;
@@ -1,4 +1,4 @@
1
- import { type AlterTableStmtContext, type ColumnCreateTableContext, type ColumnNameCreateContext, type CreateDatabaseContext, type CreateForeignTableContext, type CreateFunctionStmtContext, type CreateMaterializedViewContext, type CreatePartitionForeignTableContext, type CreateViewContext, type DatabaseNameContext, type DatabaseNameCreateContext, FuncTableContext, type FunctionNameCreateContext, type InsertStatementContext, type ProcedureNameContext, type ProcedureNameCreateContext, type QueryCreateTableContext, SelectExpressionColumnNameContext, SelectLiteralColumnNameContext, SelectNoParensContext, type SelectStatementContext, SelectWithParensContext, type SingleStmtContext, TableAllColumnsContext, type TableNameContext, type TableNameCreateContext, Target_dot_emptyContext, Target_emptyContext, ColumnNamePath_dot_emptyContext, TargetListContext, type ViewNameContext, type ViewNameCreateContext, XmlTableContext } from '../../lib/postgresql/PostgreSqlParser';
1
+ import { type AlterTableStmtContext, type ColumnCreateTableContext, type ColumnNameCreateContext, type CreateDatabaseContext, type CreateForeignTableContext, type CreateFunctionStmtContext, type CreateMaterializedViewContext, type CreatePartitionForeignTableContext, type CreateViewContext, type DatabaseNameContext, type DatabaseNameCreateContext, FuncTableContext, type FunctionNameCreateContext, type InsertStatementContext, type ProcedureNameContext, type ProcedureNameCreateContext, type QueryCreateTableContext, SelectExpressionColumnNameContext, SelectLiteralColumnNameContext, SelectNoParensContext, type SelectStatementContext, SelectWithParensContext, type SingleStmtContext, TableAllColumnsContext, type TableNameContext, type TableNameCreateContext, Target_dot_emptyContext, Target_emptyContext, TargetListContext, type ViewNameContext, type ViewNameCreateContext, XmlTableContext } from '../../lib/postgresql/PostgreSqlParser';
2
2
  import type { PostgreSqlParserListener } from '../../lib/postgresql/PostgreSqlParserListener';
3
3
  import { EntityCollector } from '../common/entityCollector';
4
4
  export declare class PostgreSqlEntityCollector extends EntityCollector implements PostgreSqlParserListener {
@@ -18,7 +18,6 @@ export declare class PostgreSqlEntityCollector extends EntityCollector implement
18
18
  exitTableAllColumns(ctx: TableAllColumnsContext): void;
19
19
  exitTarget_empty(ctx: Target_emptyContext): void;
20
20
  exitTarget_dot_empty(ctx: Target_dot_emptyContext): void;
21
- exitColumnNamePath_dot_empty(ctx: ColumnNamePath_dot_emptyContext): void;
22
21
  exitSelectExpressionColumnName(ctx: SelectExpressionColumnNameContext): void;
23
22
  exitSelectLiteralColumnName(ctx: SelectLiteralColumnNameContext): void;
24
23
  exitProcedureName(ctx: ProcedureNameContext): void;
@@ -105,11 +105,6 @@ export class PostgreSqlEntityCollector extends EntityCollector {
105
105
  declareType: ColumnDeclareType.LITERAL,
106
106
  });
107
107
  }
108
- exitColumnNamePath_dot_empty(ctx) {
109
- this.pushEntity(ctx, EntityContextType.COLUMN, [], {
110
- declareType: ColumnDeclareType.LITERAL,
111
- });
112
- }
113
108
  exitSelectExpressionColumnName(ctx) {
114
109
  this.pushEntity(ctx, EntityContextType.COLUMN, [
115
110
  {
@@ -115,11 +115,9 @@ export class TrinoSQL extends BasicSQL {
115
115
  candidateRule.ruleList.includes(TrinoSqlParser.RULE_havingClause) ||
116
116
  candidateRule.ruleList.includes(TrinoSqlParser.RULE_partitionBy) ||
117
117
  candidateRule.ruleList.includes(TrinoSqlParser.RULE_whenClause) ||
118
- candidateRule.ruleList.includes(TrinoSqlParser.RULE_relation) ||
119
- candidateRule.ruleList.includes(TrinoSqlParser.RULE_joinCriteria)) {
118
+ candidateRule.ruleList.includes(TrinoSqlParser.RULE_relation)) {
120
119
  syntaxContextType = EntityContextType.COLUMN;
121
120
  }
122
- break;
123
121
  }
124
122
  default:
125
123
  break;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dt-sql-parser",
3
- "version": "4.5.1-beta.1",
3
+ "version": "4.5.1-beta.3",
4
4
  "authors": "DTStack Corporation",
5
5
  "description": "SQL Parsers for BigData, built with antlr4",
6
6
  "keywords": [