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.
- package/README.md +140 -3
- package/dist/lib/SQLParserBase.d.ts +13 -1
- package/dist/lib/SQLParserBase.js +40 -5
- package/dist/lib/flink/FlinkSqlLexer.d.ts +397 -399
- package/dist/lib/flink/FlinkSqlLexer.js +2489 -2504
- package/dist/lib/flink/FlinkSqlParser.d.ts +726 -728
- package/dist/lib/flink/FlinkSqlParser.js +4727 -5330
- package/dist/lib/flink/FlinkSqlParserListener.d.ts +132 -90
- package/dist/lib/flink/FlinkSqlParserVisitor.d.ts +84 -57
- package/dist/lib/hive/HiveSqlParser.d.ts +338 -239
- package/dist/lib/hive/HiveSqlParser.js +6466 -5794
- package/dist/lib/hive/HiveSqlParserListener.d.ts +88 -0
- package/dist/lib/hive/HiveSqlParserVisitor.d.ts +56 -0
- package/dist/lib/impala/ImpalaSqlParser.d.ts +236 -125
- package/dist/lib/impala/ImpalaSqlParser.js +4257 -3483
- package/dist/lib/impala/ImpalaSqlParserListener.d.ts +109 -14
- package/dist/lib/impala/ImpalaSqlParserVisitor.d.ts +69 -8
- package/dist/lib/mysql/MySqlParser.d.ts +403 -306
- package/dist/lib/mysql/MySqlParser.js +10694 -10030
- package/dist/lib/mysql/MySqlParserListener.d.ts +121 -18
- package/dist/lib/mysql/MySqlParserVisitor.d.ts +75 -10
- package/dist/lib/postgresql/PostgreSqlParser.d.ts +256 -173
- package/dist/lib/postgresql/PostgreSqlParser.js +14934 -11710
- package/dist/lib/postgresql/PostgreSqlParserListener.d.ts +97 -5
- package/dist/lib/postgresql/PostgreSqlParserVisitor.d.ts +61 -3
- package/dist/lib/spark/SparkSqlParser.d.ts +314 -149
- package/dist/lib/spark/SparkSqlParser.js +6185 -5227
- package/dist/lib/spark/SparkSqlParserListener.d.ts +180 -5
- package/dist/lib/spark/SparkSqlParserVisitor.d.ts +113 -3
- package/dist/lib/trino/TrinoSqlListener.d.ts +90 -37
- package/dist/lib/trino/TrinoSqlParser.d.ts +219 -165
- package/dist/lib/trino/TrinoSqlParser.js +4942 -4615
- package/dist/lib/trino/TrinoSqlVisitor.d.ts +55 -21
- package/dist/parser/common/basicSQL.d.ts +5 -5
- package/dist/parser/common/basicSQL.js +4 -2
- package/dist/parser/common/entityCollector.d.ts +91 -4
- package/dist/parser/common/entityCollector.js +227 -11
- package/dist/parser/common/textAndWord.d.ts +9 -1
- package/dist/parser/common/textAndWord.js +2 -0
- package/dist/parser/common/types.d.ts +2 -0
- package/dist/parser/common/types.js +2 -0
- package/dist/parser/flink/flinkEntityCollector.d.ts +10 -2
- package/dist/parser/flink/flinkEntityCollector.js +76 -14
- package/dist/parser/flink/index.js +5 -2
- package/dist/parser/hive/hiveEntityCollector.d.ts +13 -1
- package/dist/parser/hive/hiveEntityCollector.js +85 -12
- package/dist/parser/impala/impalaEntityCollector.d.ts +7 -1
- package/dist/parser/impala/impalaEntityCollector.js +63 -12
- package/dist/parser/impala/index.js +2 -1
- package/dist/parser/mysql/index.js +3 -1
- package/dist/parser/mysql/mysqlEntityCollector.d.ts +10 -1
- package/dist/parser/mysql/mysqlEntityCollector.js +65 -12
- package/dist/parser/mysql/mysqlErrorListener.js +2 -0
- package/dist/parser/postgresql/postgreEntityCollector.d.ts +12 -1
- package/dist/parser/postgresql/postgreEntityCollector.js +99 -22
- package/dist/parser/spark/index.js +3 -1
- package/dist/parser/spark/sparkEntityCollector.d.ts +13 -1
- package/dist/parser/spark/sparkEntityCollector.js +88 -12
- package/dist/parser/trino/trinoEntityCollector.d.ts +7 -1
- package/dist/parser/trino/trinoEntityCollector.js +53 -12
- 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
|
-
|
|
351
|
-
|
|
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
|
+

|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
}
|