dt-sql-parser 4.4.2 → 4.5.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 (61) hide show
  1. package/README.md +140 -3
  2. package/dist/lib/SQLParserBase.d.ts +13 -1
  3. package/dist/lib/SQLParserBase.js +40 -5
  4. package/dist/lib/flink/FlinkSqlLexer.d.ts +397 -399
  5. package/dist/lib/flink/FlinkSqlLexer.js +2489 -2504
  6. package/dist/lib/flink/FlinkSqlParser.d.ts +726 -728
  7. package/dist/lib/flink/FlinkSqlParser.js +4727 -5330
  8. package/dist/lib/flink/FlinkSqlParserListener.d.ts +132 -90
  9. package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +84 -57
  10. package/dist/lib/hive/HiveSqlParser.d.ts +338 -239
  11. package/dist/lib/hive/HiveSqlParser.js +6466 -5794
  12. package/dist/lib/hive/HiveSqlParserListener.d.ts +88 -0
  13. package/dist/lib/hive/HiveSqlParserVisitor.d.ts +56 -0
  14. package/dist/lib/impala/ImpalaSqlParser.d.ts +236 -125
  15. package/dist/lib/impala/ImpalaSqlParser.js +4257 -3483
  16. package/dist/lib/impala/ImpalaSqlParserListener.d.ts +109 -14
  17. package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +69 -8
  18. package/dist/lib/mysql/MySqlParser.d.ts +403 -306
  19. package/dist/lib/mysql/MySqlParser.js +10694 -10030
  20. package/dist/lib/mysql/MySqlParserListener.d.ts +121 -18
  21. package/dist/lib/mysql/MySqlParserVisitor.d.ts +75 -10
  22. package/dist/lib/postgresql/PostgreSqlParser.d.ts +256 -173
  23. package/dist/lib/postgresql/PostgreSqlParser.js +14934 -11710
  24. package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +97 -5
  25. package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +61 -3
  26. package/dist/lib/spark/SparkSqlParser.d.ts +314 -149
  27. package/dist/lib/spark/SparkSqlParser.js +6185 -5227
  28. package/dist/lib/spark/SparkSqlParserListener.d.ts +180 -5
  29. package/dist/lib/spark/SparkSqlParserVisitor.d.ts +113 -3
  30. package/dist/lib/trino/TrinoSqlListener.d.ts +90 -37
  31. package/dist/lib/trino/TrinoSqlParser.d.ts +219 -165
  32. package/dist/lib/trino/TrinoSqlParser.js +4942 -4615
  33. package/dist/lib/trino/TrinoSqlVisitor.d.ts +55 -21
  34. package/dist/parser/common/basicSQL.d.ts +5 -5
  35. package/dist/parser/common/basicSQL.js +4 -2
  36. package/dist/parser/common/entityCollector.d.ts +91 -4
  37. package/dist/parser/common/entityCollector.js +227 -11
  38. package/dist/parser/common/textAndWord.d.ts +9 -1
  39. package/dist/parser/common/textAndWord.js +2 -0
  40. package/dist/parser/common/types.d.ts +2 -0
  41. package/dist/parser/common/types.js +2 -0
  42. package/dist/parser/flink/flinkEntityCollector.d.ts +10 -2
  43. package/dist/parser/flink/flinkEntityCollector.js +76 -14
  44. package/dist/parser/flink/index.js +5 -2
  45. package/dist/parser/hive/hiveEntityCollector.d.ts +13 -1
  46. package/dist/parser/hive/hiveEntityCollector.js +85 -12
  47. package/dist/parser/impala/impalaEntityCollector.d.ts +7 -1
  48. package/dist/parser/impala/impalaEntityCollector.js +63 -12
  49. package/dist/parser/impala/index.js +2 -1
  50. package/dist/parser/mysql/index.js +3 -1
  51. package/dist/parser/mysql/mysqlEntityCollector.d.ts +10 -1
  52. package/dist/parser/mysql/mysqlEntityCollector.js +65 -12
  53. package/dist/parser/mysql/mysqlErrorListener.js +2 -0
  54. package/dist/parser/postgresql/postgreEntityCollector.d.ts +12 -1
  55. package/dist/parser/postgresql/postgreEntityCollector.js +99 -22
  56. package/dist/parser/spark/index.js +3 -1
  57. package/dist/parser/spark/sparkEntityCollector.d.ts +13 -1
  58. package/dist/parser/spark/sparkEntityCollector.js +88 -12
  59. package/dist/parser/trino/trinoEntityCollector.d.ts +7 -1
  60. package/dist/parser/trino/trinoEntityCollector.js +53 -12
  61. package/package.json +1 -1
package/README.md CHANGED
@@ -347,9 +347,8 @@ Call the `getAllEntities` method on the SQL instance, and pass in the sql text a
347
347
  },
348
348
  relatedEntities: null,
349
349
  columns: null,
350
- isAlias: false,
351
- origin: null,
352
- alias: null
350
+ _alias: null,
351
+ _comment: null
353
352
  }
354
353
  ]
355
354
  */
@@ -357,6 +356,144 @@ Call the `getAllEntities` method on the SQL instance, and pass in the sql text a
357
356
 
358
357
  Position is not required, if the position is passed, then in the collected entities, if the entity is located under the statement where the corresponding position is located, then the statement object to which the entity belongs will be marked with `isContainCaret`, which can help you quickly filter out the required entities when combined with the code completion function.
359
358
 
359
+ In nested subquery scenarios, `isContainCaret` may not be sufficient to filter out the required entities. For example, for SQL: `SELECT id FROM t1 LEFT JOIN (SELECT id, name FROM t2) AS t3 ON t1.id = t3.id`, when our cursor is inside the inner query `t3` derived table, we expect to provide field completion for the `t2` table, but since both `t1` and `t2` have `isContainCaret` as `true`, we cannot distinguish available table entities in more detail.
360
+
361
+ Therefore, for entity types with `entityContextType` as `table`, collected entities will have an `isAccessible` flag to indicate whether the entity is accessible. `isAccessible` uses scope depth internally to determine accessibility. When the entity's statement scope depth equals the cursor's statement scope depth and `isContainCaret` is `true`, the entity is considered accessible (though this determination method is not absolute, it can exclude most irrelevant entities).
362
+
363
+ #### Additional Entity Information
364
+
365
+ **Alias Information**
366
+
367
+ When an entity has an alias, the entity object will contain the `_alias` field:
368
+ - `_alias`: Detailed alias information, including text content and position information
369
+
370
+ ```typescript
371
+ // Example: SELECT u.name FROM users AS u
372
+ {
373
+ entityContextType: 'table',
374
+ text: 'users',
375
+ _alias: { // Table alias information
376
+ text: 'u',
377
+ startIndex: 29,
378
+ endIndex: 29,
379
+ startColumn: 30,
380
+ endColumn: 31,
381
+ line: 1
382
+ }
383
+ }
384
+
385
+ // Example: SELECT name AS username FROM users
386
+ {
387
+ entityContextType: 'column',
388
+ text: 'name',
389
+ _alias: { // Column alias information
390
+ text: 'username',
391
+ startIndex: 15,
392
+ endIndex: 22,
393
+ startColumn: 16,
394
+ endColumn: 24,
395
+ line: 1
396
+ }
397
+ }
398
+ ```
399
+
400
+ **Declaration Type (DeclareType)**
401
+
402
+ The `declareType` field identifies how an entity is declared, with different entity types having different declaration types:
403
+
404
+ **Table Entity Declaration Types (TableDeclareType):**
405
+ - `LITERAL`: Literal table name, e.g., `SELECT * FROM users`
406
+ - `EXPRESSION`: Table defined by expression, e.g., subquery `SELECT * FROM (SELECT * FROM users) AS t`
407
+
408
+ **Column Entity Declaration Types (ColumnDeclareType):**
409
+ - `LITERAL`: Literal column name, e.g., `SELECT id, name FROM users`
410
+ - `ALL`: Wildcard syntax, e.g., `SELECT users.* FROM users`
411
+ - `EXPRESSION`: Complex expressions like subqueries, CASE statements, function calls, etc.
412
+
413
+ ```typescript
414
+ // Examples of different declareType values
415
+ // 1. Literal column
416
+ {
417
+ entityContextType: 'column',
418
+ text: 'name',
419
+ declareType: ColumnDeclareType.LITERAL,
420
+ }
421
+
422
+ // 2. Wildcard column
423
+ {
424
+ entityContextType: 'column',
425
+ text: 'users.*',
426
+ declareType: ColumnDeclareType.ALL,
427
+ }
428
+
429
+ // 3. Expression column
430
+ {
431
+ entityContextType: 'column',
432
+ text: 'CASE WHEN age > 18 THEN "adult" ELSE "minor" END',
433
+ declareType: ColumnDeclareType.EXPRESSION,
434
+ }
435
+ ```
436
+
437
+ **Other Metadata Fields**
438
+
439
+ **Comment Information**
440
+ - `_comment`: Entity comment information, mainly used for column or table comments in CREATE statements
441
+
442
+ ```typescript
443
+ // Example: CREATE TABLE users (id INT COMMENT 'USERID', name VARCHAR(50) COMMENT 'USERNAME')
444
+ {
445
+ entityContextType: 'column',
446
+ text: 'id',
447
+ _comment: {
448
+ text: "'USERID'",
449
+ startIndex: 35,
450
+ endIndex: 42,
451
+ startColumn: 36,
452
+ endColumn: 44,
453
+ line: 1
454
+ },
455
+ _colType: {
456
+ text: 'INT',
457
+ startIndex: 23,
458
+ endIndex: 42,
459
+ startColumn: 24,
460
+ endColumn: 44,
461
+ line: 1
462
+ }
463
+ }
464
+ ```
465
+
466
+ **Column Type Information**
467
+ - `_colType`: Column data type information, only used for column entities in CREATE TABLE statements, includes type name and position information
468
+
469
+ ```typescript
470
+ // Example: CREATE TABLE users (name VARCHAR(50) NOT NULL)
471
+ {
472
+ entityContextType: 'columnCreate',
473
+ text: 'name',
474
+ _colType: {
475
+ text: 'VARCHAR(50)',
476
+ startIndex: 25,
477
+ endIndex: 35,
478
+ startColumn: 26,
479
+ endColumn: 37,
480
+ line: 1
481
+ }
482
+ }
483
+ ```
484
+
485
+ **Relationship Fields**
486
+ - `relatedEntities`: List of other entities related to the current entity, e.g., query result entities related to table entities
487
+ - `columns`: List of contained columns
488
+
489
+ A simple entity relationship example:
490
+
491
+ ```sql
492
+ CREATE TABLE tb1 AS SELECT id FROM tb2;
493
+ ```
494
+
495
+ ![relation-image](./docs/images/relation.png)
496
+
360
497
  ### Get semantic context information
361
498
 
362
499
  Call the `getSemanticContextAtCaretPosition` method on the SQL instance, passing in the sql text and the line and column numbers at the specified position, for example:
@@ -4,5 +4,17 @@ export declare abstract class SQLParserBase<T = antlr.ParserRuleContext> extends
4
4
  abstract program(): T;
5
5
  caretTokenIndex: number;
6
6
  entityCollecting: boolean;
7
- shouldMatchEmpty(): boolean;
7
+ /**
8
+ * Semantic predicate to determine whether to match empty column.
9
+ *
10
+ * Key design:
11
+ * 1. Only match empty column in entityCollecting mode
12
+ * 2. Check if caret position is at the empty column position
13
+ * 3. In validate mode (entityCollecting=false), this predicate returns false
14
+ * and reports an error to ensure incomplete SQL is caught
15
+ *
16
+ * IMPORTANT: This predicate should be used carefully to avoid affecting
17
+ * prediction in non-entity-collecting contexts.
18
+ */
19
+ shouldMatchEmpty(ruleName?: string): boolean;
8
20
  }
@@ -5,10 +5,45 @@ export class SQLParserBase extends antlr.Parser {
5
5
  this.caretTokenIndex = -1;
6
6
  this.entityCollecting = false;
7
7
  }
8
- shouldMatchEmpty() {
9
- var _a, _b, _c, _d;
10
- return this.entityCollecting
11
- && ((_b = (_a = this.tokenStream.LT(-1)) === null || _a === void 0 ? void 0 : _a.tokenIndex) !== null && _b !== void 0 ? _b : Infinity) <= this.caretTokenIndex
12
- && ((_d = (_c = this.tokenStream.LT(1)) === null || _c === void 0 ? void 0 : _c.tokenIndex) !== null && _d !== void 0 ? _d : -Infinity) >= this.caretTokenIndex;
8
+ /**
9
+ * Semantic predicate to determine whether to match empty column.
10
+ *
11
+ * Key design:
12
+ * 1. Only match empty column in entityCollecting mode
13
+ * 2. Check if caret position is at the empty column position
14
+ * 3. In validate mode (entityCollecting=false), this predicate returns false
15
+ * and reports an error to ensure incomplete SQL is caught
16
+ *
17
+ * IMPORTANT: This predicate should be used carefully to avoid affecting
18
+ * prediction in non-entity-collecting contexts.
19
+ */
20
+ shouldMatchEmpty(ruleName) {
21
+ var _a, _b;
22
+ // Only match in entityCollecting mode or when caret position is specified (suggestion mode)
23
+ if (this.entityCollecting || this.caretTokenIndex >= 0) {
24
+ // If no caret position specified, match all empty columns
25
+ if (this.caretTokenIndex < 0) {
26
+ return true;
27
+ }
28
+ // Check if caret is at the position where empty column would be
29
+ const prevTokenIndex = (_a = this.tokenStream.LT(-1)) === null || _a === void 0 ? void 0 : _a.tokenIndex;
30
+ const nextTokenIndex = (_b = this.tokenStream.LT(1)) === null || _b === void 0 ? void 0 : _b.tokenIndex;
31
+ // Match if caret is between previous and next token
32
+ if (prevTokenIndex !== undefined && nextTokenIndex !== undefined) {
33
+ return prevTokenIndex <= this.caretTokenIndex && nextTokenIndex >= this.caretTokenIndex;
34
+ }
35
+ // If only previous token exists, match if caret is after it
36
+ if (prevTokenIndex !== undefined) {
37
+ return prevTokenIndex <= this.caretTokenIndex;
38
+ }
39
+ // If only next token exists, match if caret is before it
40
+ if (nextTokenIndex !== undefined) {
41
+ return nextTokenIndex >= this.caretTokenIndex;
42
+ }
43
+ return false;
44
+ }
45
+ // In pure validate mode, don't match empty columns
46
+ // This allows ANTLR to report errors naturally
47
+ return false;
13
48
  }
14
49
  }