dt-sql-parser 4.0.0-beta.4.10 → 4.0.0-beta.4.11

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 CHANGED
@@ -187,8 +187,9 @@ class MyVisitor extends AbstractParseTreeVisitor<Result> implements MySqlParserV
187
187
  console.log('SelectElements:', selectElements);
188
188
  return '';
189
189
  }
190
- visitProgram(ctx) {
191
- return 'Return by program node'
190
+ visitProgram(ctx) { // program is root rule
191
+ this.visitChildren(ctx);
192
+ return 'Return by program context'
192
193
  }
193
194
  }
194
195
  const visitor = new MyVisitor();
@@ -289,7 +290,7 @@ console.log(sqlSlices)
289
290
  Obtaining code completion information at a specified position in SQL.
290
291
  We can refer to the example of using `FlinkSQL`.
291
292
 
292
- Invoke the `getSuggestionAtCaretPosition` method, pass the SQL content and the row and column numbers indicating the position where code completion is desired.
293
+ Invoke the `getSuggestionAtCaretPosition` method, pass the SQL content and the row and column numbers indicating the position where code completion is desired. The following are some additional explanations about [CaretPosition](#caretposition-of-code-completion).
293
294
  + **keyword candidates list**
294
295
 
295
296
  ```javascript
@@ -357,6 +358,76 @@ The grammar-related code completion information returns an array, where each ite
357
358
 
358
359
  <br/>
359
360
 
361
+ ## Position and Range
362
+ Some return results of the APIs provided by `dt-sql-parser` contain text information, among which the range and start value of line number, column number and index may cause some confusion.
363
+
364
+ ### Index
365
+ The index starts at 0. In the programming field, it is more intuitive.
366
+
367
+ ![index-image](./docs/images/index.png)
368
+
369
+ For an index range, the start index starts from 0 and ends with n-1, as shown in the figure above, an index range of blue text should be represented as follows:
370
+
371
+ ```javascript
372
+ {
373
+ startIndex: 0,
374
+ endIndex: 3
375
+ }
376
+ ```
377
+
378
+ ### Line
379
+ The line starts at 1.
380
+
381
+ ![line-image](./docs/images/line.png)
382
+
383
+ For a range of multiple lines, the line number starts from 1 and ends with n. A range of the first and second lines is represented as follows:
384
+
385
+ ```javascript
386
+ {
387
+ startLine: 1,
388
+ endLine: 2
389
+ }
390
+ ```
391
+
392
+ ### Column
393
+ The column also starts at 1.
394
+
395
+ ![column-image](./docs/images/column.png)
396
+
397
+ It is easier to understand by comparing the column number with the cursor position of the editor. For a range of multiple columns, the column number starts from 1 and ends with n+1, as shown in the figure above, a range of blue text columns is represented as follows:
398
+
399
+ ```javascript
400
+ {
401
+ startColumn: 1,
402
+ endColumn: 5
403
+ }
404
+ ```
405
+
406
+ ### CaretPosition Of Code Completion
407
+ The code completion of `dt-sql-parser` was designed to be used in the editor, so the format of the second parameter (CaretPosition) of the `getSuggestionAtCaretPosition` method is line and column number instead of character position index. This makes it easier to integrate the code completion into the editor. For the editor, it only needs to get the text content and cursor position in the editor at a specific time to call the code completion of `dt-sql-parser`, without any additional calculation.
408
+
409
+ But in some other scenarios, you may need to get the caret position required by the code completion through conversion or calculation. Then, there are some precautions that you may need to care about before that.
410
+
411
+ The code completion of `dt-sql-parser` depends on [antlr4-c3](https://github.com/mike-lischke/antlr4-c3), which is a great library. The code completion of `dt-sql-parser` is just encapsulated and converted based on antlr4-c3, including converting the line and column number information into the token index required by antlr4-c3, as shown in the figure below:
412
+
413
+ ![column-image](./docs/images/token.png)
414
+
415
+ Regard the column in the figure as the cursor position, and put this text into the editor, you will get 13 possible cursor positions, while for dt-sql-parser, this text will generate 4 Tokens after being parsed. An important strategy of the code completion is: **When the cursor (CaretPosition) has not completely left a Token, dt-sql-parser thinks that this Token has not been completed, and the code completion will infer what can be filled in the position of this Token.**
416
+
417
+ For example, if you want to know what to fill in after `SHOW` through the code completion, the caret position should be:
418
+
419
+ ```javascript
420
+ {
421
+ lineNumber: 1,
422
+ column: 6
423
+ }
424
+ ```
425
+
426
+ At this time, dt-sql-parser will think that `SHOW` is already a complete Token, and it should infer what can be filled in after `SHOW`. If the column in the passed-in caret position is 5, then dt-sql-parser will think that `SHOW` has not been completed, and then infer what can be filled in the position of `SHOW`. In other words, in the figure above, `column: 5` belongs to `token: 0`, and `column: 6` belongs to `token: 1`.
427
+
428
+ For the editor, this strategy is also more intuitive. After the user enters `SHOW`, before pressing the space key, the user probably has not finished entering, maybe the user wants to enter something like `SHOWS`. When the user presses the space key, the editor thinks that the user wants to enter the next Token, and it is time to ask dt-sql-parser what can be filled in the next Token position.
429
+
430
+ <br/>
360
431
  ## License
361
432
 
362
433
  [MIT](./LICENSE)
@@ -46,11 +46,13 @@ export interface WordRange {
46
46
  readonly text: string;
47
47
  /** start at 0 */
48
48
  readonly startIndex: number;
49
- readonly stopIndex: number;
49
+ /** end at ..n-1 */
50
+ readonly endIndex: number;
50
51
  /** start at 1 */
51
52
  readonly line: number;
52
53
  /** start at 1 */
53
54
  readonly startColumn: number;
55
+ /** end at ..n + 1 */
54
56
  readonly stopColumn: number;
55
57
  }
56
58
  /**
@@ -76,12 +78,15 @@ export interface Suggestions<T = WordRange> {
76
78
  export interface TextSlice {
77
79
  /** start at 0 */
78
80
  readonly startIndex: number;
81
+ /** end at ..n-1 */
79
82
  readonly endIndex: number;
80
83
  /** start at 1 */
81
84
  readonly startLine: number;
85
+ /** end at ..n */
82
86
  readonly endLine: number;
83
87
  /** start at 1 */
84
88
  readonly startColumn: number;
89
+ /** end at ..n + 1 */
85
90
  readonly endColumn: number;
86
91
  readonly text: string;
87
92
  }
@@ -31,7 +31,7 @@ export default abstract class BasicParser<L extends Lexer = Lexer, PRC extends P
31
31
  * Create a antlr4 Lexer instance.
32
32
  * @param input source string
33
33
  */
34
- protected abstract createLexerFormCharStream(charStreams: CodePointCharStream): L;
34
+ protected abstract createLexerFromCharStream(charStreams: CodePointCharStream): L;
35
35
  /**
36
36
  * Create Parser by CommonTokenStream
37
37
  * @param tokenStream CommonTokenStream
@@ -22,7 +22,7 @@ export default class BasicParser {
22
22
  */
23
23
  createLexer(input, errorListener) {
24
24
  const charStreams = CharStreams.fromString(input.toUpperCase());
25
- const lexer = this.createLexerFormCharStream(charStreams);
25
+ const lexer = this.createLexerFromCharStream(charStreams);
26
26
  if (errorListener) {
27
27
  lexer.removeErrorListeners();
28
28
  lexer.addErrorListener(new ParseErrorListener(errorListener));
@@ -63,7 +63,7 @@ export default class BasicParser {
63
63
  createParserWithCache(input) {
64
64
  this._parseTree = null;
65
65
  this._charStreams = CharStreams.fromString(input.toUpperCase());
66
- this._lexer = this.createLexerFormCharStream(this._charStreams);
66
+ this._lexer = this.createLexerFromCharStream(this._charStreams);
67
67
  this._lexer.removeErrorListeners();
68
68
  this._lexer.addErrorListener(new ParseErrorListener(this._errorListener));
69
69
  this._tokenStream = new CommonTokenStream(this._lexer);
@@ -151,7 +151,7 @@ export default class BasicParser {
151
151
  startLine: start.line,
152
152
  endLine: stop.line,
153
153
  startColumn: start.charPositionInLine + 1,
154
- endColumn: stop.charPositionInLine + stop.text.length,
154
+ endColumn: stop.charPositionInLine + 1 + stop.text.length,
155
155
  text: this._parsedInput.slice(start.startIndex, stop.stopIndex + 1),
156
156
  };
157
157
  });
@@ -246,10 +246,10 @@ export default class BasicParser {
246
246
  return {
247
247
  text: this._parsedInput.slice(token.startIndex, token.stopIndex + 1),
248
248
  startIndex: token.startIndex,
249
- stopIndex: token.stopIndex,
249
+ endIndex: token.stopIndex,
250
250
  line: token.line,
251
251
  startColumn: token.charPositionInLine + 1,
252
- stopColumn: token.charPositionInLine + token.text.length,
252
+ stopColumn: token.charPositionInLine + 1 + token.text.length,
253
253
  };
254
254
  });
255
255
  return {
@@ -4,10 +4,14 @@ import { ATNSimulator } from 'antlr4ts/atn/ATNSimulator';
4
4
  * Converted from {@link SyntaxError}.
5
5
  */
6
6
  export interface ParseError {
7
+ /** start at 1 */
7
8
  readonly startLine: number;
9
+ /** end at ..n */
8
10
  readonly endLine: number;
9
- readonly startCol: number;
10
- readonly endCol: number;
11
+ /** start at 1 */
12
+ readonly startColumn: number;
13
+ /** end at ..n + 1 */
14
+ readonly endColumn: number;
11
15
  readonly message: string;
12
16
  }
13
17
  /**
@@ -11,8 +11,8 @@ export default class ParseErrorListener {
11
11
  this._errorListener({
12
12
  startLine: line,
13
13
  endLine: line,
14
- startCol: charPositionInLine,
15
- endCol: endCol,
14
+ startColumn: charPositionInLine + 1,
15
+ endColumn: endCol + 1,
16
16
  message: msg,
17
17
  }, {
18
18
  e,
@@ -6,7 +6,7 @@ import { FlinkSqlParserListener } from '../lib/flinksql/FlinkSqlParserListener';
6
6
  import { Suggestions } from './common/basic-parser-types';
7
7
  import BasicParser from './common/basicParser';
8
8
  export default class FlinkSQL extends BasicParser<FlinkSqlLexer, ProgramContext, FlinkSqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): FlinkSqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): FlinkSqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): FlinkSqlParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): FlinkSqlSplitListener;
@@ -19,7 +19,7 @@ export default class FlinkSQL extends BasicParser {
19
19
  FlinkSqlParser.RULE_columnNameCreate,
20
20
  ]);
21
21
  }
22
- createLexerFormCharStream(charStreams) {
22
+ createLexerFromCharStream(charStreams) {
23
23
  const lexer = new FlinkSqlLexer(charStreams);
24
24
  return lexer;
25
25
  }
@@ -6,7 +6,7 @@ import BasicParser from './common/basicParser';
6
6
  import { HiveSqlParserListener } from '../lib/hive/HiveSqlParserListener';
7
7
  import { Suggestions } from './common/basic-parser-types';
8
8
  export default class HiveSQL extends BasicParser<HiveSqlLexer, ProgramContext, HiveSqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): HiveSqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): HiveSqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): HiveSqlParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): HiveSqlSplitListener;
@@ -19,7 +19,7 @@ export default class HiveSQL extends BasicParser {
19
19
  HiveSqlParser.RULE_columnNameCreate,
20
20
  ]);
21
21
  }
22
- createLexerFormCharStream(charStreams) {
22
+ createLexerFromCharStream(charStreams) {
23
23
  const lexer = new HiveSqlLexer(charStreams);
24
24
  return lexer;
25
25
  }
@@ -6,7 +6,7 @@ import BasicParser from './common/basicParser';
6
6
  import { ImpalaSqlParserListener } from '../lib/impala/ImpalaSqlParserListener';
7
7
  import { Suggestions } from './common/basic-parser-types';
8
8
  export default class ImpalaSQL extends BasicParser<ImpalaSqlLexer, ProgramContext, ImpalaSqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): ImpalaSqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): ImpalaSqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): ImpalaSqlParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): ImpalaSqlSplitListener;
@@ -18,7 +18,7 @@ export default class ImpalaSQL extends BasicParser {
18
18
  ImpalaSqlParser.RULE_columnNamePath,
19
19
  ]);
20
20
  }
21
- createLexerFormCharStream(charStreams) {
21
+ createLexerFromCharStream(charStreams) {
22
22
  const lexer = new ImpalaSqlLexer(charStreams);
23
23
  return lexer;
24
24
  }
@@ -6,7 +6,7 @@ import BasicParser from './common/basicParser';
6
6
  import { Suggestions } from './common/basic-parser-types';
7
7
  import { MySqlParserListener } from '../lib/mysql/MySqlParserListener';
8
8
  export default class MySQL extends BasicParser<MySqlLexer, ProgramContext, MySqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): MySqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): MySqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): MySqlParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): MysqlSplitListener;
@@ -18,7 +18,7 @@ export default class MySQL extends BasicParser {
18
18
  MySqlParser.RULE_columnNameCreate,
19
19
  ]);
20
20
  }
21
- createLexerFormCharStream(charStreams) {
21
+ createLexerFromCharStream(charStreams) {
22
22
  const lexer = new MySqlLexer(charStreams);
23
23
  return lexer;
24
24
  }
@@ -6,7 +6,7 @@ import BasicParser from './common/basicParser';
6
6
  import { PostgreSQLParserListener } from '../lib/pgsql/PostgreSQLParserListener';
7
7
  import { Suggestions } from './common/basic-parser-types';
8
8
  export default class PostgresSQL extends BasicParser<PostgreSQLLexer, ProgramContext, PostgreSQLParser> {
9
- protected createLexerFormCharStream(charStreams: any): PostgreSQLLexer;
9
+ protected createLexerFromCharStream(charStreams: any): PostgreSQLLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): PostgreSQLParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): PgSqlSplitListener;
@@ -22,7 +22,7 @@ export default class PostgresSQL extends BasicParser {
22
22
  PostgreSQLParser.RULE_column_name, // column name
23
23
  ]);
24
24
  }
25
- createLexerFormCharStream(charStreams) {
25
+ createLexerFromCharStream(charStreams) {
26
26
  const lexer = new PostgreSQLLexer(charStreams);
27
27
  return lexer;
28
28
  }
@@ -5,7 +5,7 @@ import { PlSqlParser, ProgramContext } from '../lib/plsql/PlSqlParser';
5
5
  import BasicParser from './common/basicParser';
6
6
  import { Suggestions } from './common/basic-parser-types';
7
7
  export default class PLSQL extends BasicParser<PlSqlLexer, ProgramContext, PlSqlParser> {
8
- protected createLexerFormCharStream(charStreams: any): PlSqlLexer;
8
+ protected createLexerFromCharStream(charStreams: any): PlSqlLexer;
9
9
  protected createParserFromTokenStream(tokenStream: any): PlSqlParser;
10
10
  protected preferredRules: Set<number>;
11
11
  protected get splitListener(): any;
@@ -6,7 +6,7 @@ export default class PLSQL extends BasicParser {
6
6
  super(...arguments);
7
7
  this.preferredRules = new Set();
8
8
  }
9
- createLexerFormCharStream(charStreams) {
9
+ createLexerFromCharStream(charStreams) {
10
10
  const lexer = new PlSqlLexer(charStreams);
11
11
  return lexer;
12
12
  }
@@ -6,7 +6,7 @@ import BasicParser from './common/basicParser';
6
6
  import { Suggestions } from './common/basic-parser-types';
7
7
  import { SparkSqlParserListener } from '../lib/spark/SparkSqlParserListener';
8
8
  export default class SparkSQL extends BasicParser<SparkSqlLexer, ProgramContext, SparkSqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): SparkSqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): SparkSqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): SparkSqlParser;
11
11
  protected preferredRules: Set<number>;
12
12
  protected get splitListener(): SparkSqlSplitListener;
@@ -18,7 +18,7 @@ export default class SparkSQL extends BasicParser {
18
18
  SparkSqlParser.RULE_columnNameCreate,
19
19
  ]);
20
20
  }
21
- createLexerFormCharStream(charStreams) {
21
+ createLexerFromCharStream(charStreams) {
22
22
  const lexer = new SparkSqlLexer(charStreams);
23
23
  return lexer;
24
24
  }
@@ -6,7 +6,7 @@ import { TrinoSqlListener } from '../lib/trinosql/TrinoSqlListener';
6
6
  import BasicParser from './common/basicParser';
7
7
  import { Suggestions } from './common/basic-parser-types';
8
8
  export default class TrinoSQL extends BasicParser<TrinoSqlLexer, ProgramContext, TrinoSqlParser> {
9
- protected createLexerFormCharStream(charStreams: any): TrinoSqlLexer;
9
+ protected createLexerFromCharStream(charStreams: any): TrinoSqlLexer;
10
10
  protected createParserFromTokenStream(tokenStream: any): TrinoSqlParser;
11
11
  protected get splitListener(): TrinoSqlSplitListener;
12
12
  protected preferredRules: Set<number>;
@@ -19,7 +19,7 @@ export default class TrinoSQL extends BasicParser {
19
19
  TrinoSqlParser.RULE_columnNameCreate,
20
20
  ]);
21
21
  }
22
- createLexerFormCharStream(charStreams) {
22
+ createLexerFromCharStream(charStreams) {
23
23
  const lexer = new TrinoSqlLexer(charStreams);
24
24
  return lexer;
25
25
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dt-sql-parser",
3
- "version": "4.0.0-beta.4.10",
3
+ "version": "4.0.0-beta.4.11",
4
4
  "authors": "DTStack Corporation",
5
5
  "description": "SQL Parsers for BigData, built with antlr4",
6
6
  "keywords": [