@questdb/sql-parser 0.1.0 → 0.1.2
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/CHANGELOG.md +11 -0
- package/dist/autocomplete/content-assist.d.ts +27 -0
- package/dist/index.cjs +375 -176
- package/dist/index.js +375 -176
- package/dist/parser/parser.d.ts +6 -0
- package/dist/parser/visitor.d.ts +7 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1478,7 +1478,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
1478
1478
|
ALT: () => this.CONSUME(VariableReference)
|
|
1479
1479
|
},
|
|
1480
1480
|
{ ALT: () => this.CONSUME(StringLiteral) },
|
|
1481
|
-
{ ALT: () => this.SUBRULE(this.
|
|
1481
|
+
{ ALT: () => this.SUBRULE(this.tableName) }
|
|
1482
1482
|
]);
|
|
1483
1483
|
this.OPTION2(() => {
|
|
1484
1484
|
this.CONSUME(Timestamp);
|
|
@@ -1526,47 +1526,95 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
1526
1526
|
this.tableFunctionName = this.RULE("tableFunctionName", () => {
|
|
1527
1527
|
this.SUBRULE(this.identifier);
|
|
1528
1528
|
});
|
|
1529
|
+
// ---- Join clause: dispatches to type-specific sub-rules so that each
|
|
1530
|
+
// join type only offers its own valid postamble tokens.
|
|
1529
1531
|
this.joinClause = this.RULE("joinClause", () => {
|
|
1530
|
-
this.
|
|
1531
|
-
this.
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
this.OPTION1(() => this.CONSUME(Outer));
|
|
1544
|
-
});
|
|
1532
|
+
this.OR([
|
|
1533
|
+
{ ALT: () => this.SUBRULE(this.asofLtJoin) },
|
|
1534
|
+
{ ALT: () => this.SUBRULE(this.spliceJoin) },
|
|
1535
|
+
{ ALT: () => this.SUBRULE(this.windowJoin) },
|
|
1536
|
+
{ ALT: () => this.SUBRULE(this.standardJoin) }
|
|
1537
|
+
]);
|
|
1538
|
+
});
|
|
1539
|
+
// ASOF/LT JOIN: ON + TOLERANCE
|
|
1540
|
+
this.asofLtJoin = this.RULE("asofLtJoin", () => {
|
|
1541
|
+
this.OR([
|
|
1542
|
+
{ ALT: () => this.CONSUME(Asof) },
|
|
1543
|
+
{ ALT: () => this.CONSUME(Lt) }
|
|
1544
|
+
]);
|
|
1545
1545
|
this.CONSUME(Join);
|
|
1546
1546
|
this.SUBRULE(this.tableRef);
|
|
1547
|
-
this.
|
|
1547
|
+
this.OPTION(() => {
|
|
1548
1548
|
this.CONSUME(On);
|
|
1549
1549
|
this.SUBRULE(this.expression);
|
|
1550
1550
|
});
|
|
1551
|
-
this.
|
|
1551
|
+
this.OPTION1(() => {
|
|
1552
1552
|
this.CONSUME(Tolerance);
|
|
1553
1553
|
this.CONSUME(DurationLiteral);
|
|
1554
1554
|
});
|
|
1555
|
-
|
|
1555
|
+
});
|
|
1556
|
+
// SPLICE JOIN: ON only
|
|
1557
|
+
this.spliceJoin = this.RULE("spliceJoin", () => {
|
|
1558
|
+
this.CONSUME(Splice);
|
|
1559
|
+
this.CONSUME(Join);
|
|
1560
|
+
this.SUBRULE(this.tableRef);
|
|
1561
|
+
this.OPTION(() => {
|
|
1562
|
+
this.CONSUME(On);
|
|
1563
|
+
this.SUBRULE(this.expression);
|
|
1564
|
+
});
|
|
1565
|
+
});
|
|
1566
|
+
// WINDOW/PREVAILING JOIN: ON + RANGE BETWEEN + INCLUDE/EXCLUDE PREVAILING
|
|
1567
|
+
this.windowJoin = this.RULE("windowJoin", () => {
|
|
1568
|
+
this.OR([
|
|
1569
|
+
{ ALT: () => this.CONSUME(Window) },
|
|
1570
|
+
{ ALT: () => this.CONSUME(Prevailing) }
|
|
1571
|
+
]);
|
|
1572
|
+
this.CONSUME(Join);
|
|
1573
|
+
this.SUBRULE(this.tableRef);
|
|
1574
|
+
this.OPTION(() => {
|
|
1575
|
+
this.CONSUME(On);
|
|
1576
|
+
this.SUBRULE(this.expression);
|
|
1577
|
+
});
|
|
1578
|
+
this.OPTION1(() => {
|
|
1556
1579
|
this.CONSUME(Range);
|
|
1557
1580
|
this.CONSUME(Between);
|
|
1558
1581
|
this.SUBRULE(this.windowJoinBound);
|
|
1559
1582
|
this.CONSUME(And);
|
|
1560
1583
|
this.SUBRULE1(this.windowJoinBound);
|
|
1561
1584
|
});
|
|
1562
|
-
this.
|
|
1563
|
-
this.
|
|
1585
|
+
this.OPTION2(() => {
|
|
1586
|
+
this.OR1([
|
|
1564
1587
|
{ ALT: () => this.CONSUME(Include) },
|
|
1565
1588
|
{ ALT: () => this.CONSUME(Exclude) }
|
|
1566
1589
|
]);
|
|
1567
1590
|
this.CONSUME1(Prevailing);
|
|
1568
1591
|
});
|
|
1569
1592
|
});
|
|
1593
|
+
// Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
|
|
1594
|
+
this.standardJoin = this.RULE("standardJoin", () => {
|
|
1595
|
+
this.OPTION(() => {
|
|
1596
|
+
this.OR([
|
|
1597
|
+
{
|
|
1598
|
+
ALT: () => {
|
|
1599
|
+
this.OR1([
|
|
1600
|
+
{ ALT: () => this.CONSUME(Left) },
|
|
1601
|
+
{ ALT: () => this.CONSUME(Right) },
|
|
1602
|
+
{ ALT: () => this.CONSUME(Full) }
|
|
1603
|
+
]);
|
|
1604
|
+
this.OPTION1(() => this.CONSUME(Outer));
|
|
1605
|
+
}
|
|
1606
|
+
},
|
|
1607
|
+
{ ALT: () => this.CONSUME(Inner) },
|
|
1608
|
+
{ ALT: () => this.CONSUME(Cross) }
|
|
1609
|
+
]);
|
|
1610
|
+
});
|
|
1611
|
+
this.CONSUME(Join);
|
|
1612
|
+
this.SUBRULE(this.tableRef);
|
|
1613
|
+
this.OPTION2(() => {
|
|
1614
|
+
this.CONSUME(On);
|
|
1615
|
+
this.SUBRULE(this.expression);
|
|
1616
|
+
});
|
|
1617
|
+
});
|
|
1570
1618
|
// Window join bound: <number> <timeUnit> PRECEDING/FOLLOWING | CURRENT ROW [PRECEDING/FOLLOWING] | DurationLiteral PRECEDING/FOLLOWING
|
|
1571
1619
|
this.windowJoinBound = this.RULE("windowJoinBound", () => {
|
|
1572
1620
|
this.OR([
|
|
@@ -1780,7 +1828,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
1780
1828
|
]);
|
|
1781
1829
|
});
|
|
1782
1830
|
this.CONSUME(Into);
|
|
1783
|
-
this.SUBRULE(this.
|
|
1831
|
+
this.SUBRULE(this.tableNameOrString);
|
|
1784
1832
|
this.OPTION2(() => this.SUBRULE1(this.batchClause));
|
|
1785
1833
|
this.OPTION3(() => {
|
|
1786
1834
|
this.CONSUME(LParen);
|
|
@@ -1818,7 +1866,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
1818
1866
|
// ==========================================================================
|
|
1819
1867
|
this.updateStatement = this.RULE("updateStatement", () => {
|
|
1820
1868
|
this.CONSUME(Update);
|
|
1821
|
-
this.SUBRULE(this.
|
|
1869
|
+
this.SUBRULE(this.tableName);
|
|
1822
1870
|
this.OPTION2(() => this.SUBRULE(this.identifier));
|
|
1823
1871
|
this.CONSUME(Set2);
|
|
1824
1872
|
this.SUBRULE(this.setClause);
|
|
@@ -1969,7 +2017,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
1969
2017
|
ALT: () => {
|
|
1970
2018
|
this.CONSUME2(LParen);
|
|
1971
2019
|
this.CONSUME(Like);
|
|
1972
|
-
this.
|
|
2020
|
+
this.SUBRULE(this.tableName);
|
|
1973
2021
|
this.CONSUME2(RParen);
|
|
1974
2022
|
}
|
|
1975
2023
|
}
|
|
@@ -2537,10 +2585,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2537
2585
|
});
|
|
2538
2586
|
this.alterTableStatement = this.RULE("alterTableStatement", () => {
|
|
2539
2587
|
this.CONSUME(Table);
|
|
2540
|
-
this.
|
|
2541
|
-
{ ALT: () => this.SUBRULE(this.qualifiedName) },
|
|
2542
|
-
{ ALT: () => this.CONSUME(StringLiteral) }
|
|
2543
|
-
]);
|
|
2588
|
+
this.SUBRULE(this.tableNameOrString);
|
|
2544
2589
|
this.SUBRULE(this.alterTableAction);
|
|
2545
2590
|
});
|
|
2546
2591
|
this.alterTableAction = this.RULE("alterTableAction", () => {
|
|
@@ -2571,10 +2616,10 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2571
2616
|
{
|
|
2572
2617
|
ALT: () => {
|
|
2573
2618
|
this.CONSUME1(Column);
|
|
2574
|
-
this.SUBRULE(this.
|
|
2619
|
+
this.SUBRULE(this.columnRef);
|
|
2575
2620
|
this.MANY1(() => {
|
|
2576
2621
|
this.CONSUME1(Comma);
|
|
2577
|
-
this.SUBRULE1(this.
|
|
2622
|
+
this.SUBRULE1(this.columnRef);
|
|
2578
2623
|
});
|
|
2579
2624
|
}
|
|
2580
2625
|
},
|
|
@@ -2610,7 +2655,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2610
2655
|
ALT: () => {
|
|
2611
2656
|
this.CONSUME(Rename);
|
|
2612
2657
|
this.CONSUME2(Column);
|
|
2613
|
-
this.SUBRULE2(this.
|
|
2658
|
+
this.SUBRULE2(this.columnRef);
|
|
2614
2659
|
this.CONSUME(To);
|
|
2615
2660
|
this.SUBRULE3(this.identifier);
|
|
2616
2661
|
}
|
|
@@ -2620,7 +2665,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2620
2665
|
ALT: () => {
|
|
2621
2666
|
this.CONSUME1(Alter);
|
|
2622
2667
|
this.CONSUME3(Column);
|
|
2623
|
-
this.
|
|
2668
|
+
this.SUBRULE3(this.columnRef);
|
|
2624
2669
|
this.OR9([
|
|
2625
2670
|
{
|
|
2626
2671
|
ALT: () => {
|
|
@@ -2839,7 +2884,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2839
2884
|
() => {
|
|
2840
2885
|
this.CONSUME(Materialized);
|
|
2841
2886
|
this.CONSUME(View);
|
|
2842
|
-
this.SUBRULE(this.
|
|
2887
|
+
this.SUBRULE(this.tableName);
|
|
2843
2888
|
this.SUBRULE(this.alterMaterializedViewAction);
|
|
2844
2889
|
}
|
|
2845
2890
|
);
|
|
@@ -2851,7 +2896,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2851
2896
|
ALT: () => {
|
|
2852
2897
|
this.CONSUME(Alter);
|
|
2853
2898
|
this.CONSUME(Column);
|
|
2854
|
-
this.SUBRULE(this.
|
|
2899
|
+
this.SUBRULE(this.columnRef);
|
|
2855
2900
|
this.OR1([
|
|
2856
2901
|
{
|
|
2857
2902
|
ALT: () => {
|
|
@@ -2998,7 +3043,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
2998
3043
|
this.CONSUME(If);
|
|
2999
3044
|
this.CONSUME(Exists);
|
|
3000
3045
|
});
|
|
3001
|
-
this.SUBRULE(this.
|
|
3046
|
+
this.SUBRULE(this.tableName);
|
|
3002
3047
|
}
|
|
3003
3048
|
}
|
|
3004
3049
|
]);
|
|
@@ -3054,10 +3099,10 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3054
3099
|
this.CONSUME(Exists);
|
|
3055
3100
|
});
|
|
3056
3101
|
this.OPTION1(() => this.CONSUME(Only));
|
|
3057
|
-
this.SUBRULE(this.
|
|
3102
|
+
this.SUBRULE(this.tableName);
|
|
3058
3103
|
this.MANY(() => {
|
|
3059
3104
|
this.CONSUME(Comma);
|
|
3060
|
-
this.SUBRULE1(this.
|
|
3105
|
+
this.SUBRULE1(this.tableName);
|
|
3061
3106
|
});
|
|
3062
3107
|
this.OPTION2(() => {
|
|
3063
3108
|
this.CONSUME(Keep);
|
|
@@ -3071,9 +3116,9 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3071
3116
|
this.renameTableStatement = this.RULE("renameTableStatement", () => {
|
|
3072
3117
|
this.CONSUME(Rename);
|
|
3073
3118
|
this.CONSUME(Table);
|
|
3074
|
-
this.SUBRULE(this.
|
|
3119
|
+
this.SUBRULE(this.tableNameOrString);
|
|
3075
3120
|
this.CONSUME(To);
|
|
3076
|
-
this.SUBRULE1(this.
|
|
3121
|
+
this.SUBRULE1(this.tableNameOrString);
|
|
3077
3122
|
});
|
|
3078
3123
|
this.addUserStatement = this.RULE("addUserStatement", () => {
|
|
3079
3124
|
this.CONSUME(Add);
|
|
@@ -3284,7 +3329,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3284
3329
|
this.CONSUME(Cancel);
|
|
3285
3330
|
});
|
|
3286
3331
|
this.copyFrom = this.RULE("copyFrom", () => {
|
|
3287
|
-
this.SUBRULE(this.
|
|
3332
|
+
this.SUBRULE(this.tableName);
|
|
3288
3333
|
this.CONSUME(From);
|
|
3289
3334
|
this.SUBRULE(this.stringOrIdentifier);
|
|
3290
3335
|
this.OPTION(() => this.SUBRULE(this.copyOptions));
|
|
@@ -3298,7 +3343,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3298
3343
|
this.CONSUME(RParen);
|
|
3299
3344
|
}
|
|
3300
3345
|
},
|
|
3301
|
-
{ ALT: () => this.SUBRULE(this.
|
|
3346
|
+
{ ALT: () => this.SUBRULE(this.tableName) }
|
|
3302
3347
|
]);
|
|
3303
3348
|
this.CONSUME(To);
|
|
3304
3349
|
this.SUBRULE1(this.stringOrIdentifier);
|
|
@@ -3449,7 +3494,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3449
3494
|
{
|
|
3450
3495
|
ALT: () => {
|
|
3451
3496
|
this.CONSUME(Table);
|
|
3452
|
-
this.SUBRULE(this.
|
|
3497
|
+
this.SUBRULE(this.tableName);
|
|
3453
3498
|
}
|
|
3454
3499
|
},
|
|
3455
3500
|
{ ALT: () => this.CONSUME(Abort) }
|
|
@@ -3461,7 +3506,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3461
3506
|
this.compileViewStatement = this.RULE("compileViewStatement", () => {
|
|
3462
3507
|
this.CONSUME(Compile);
|
|
3463
3508
|
this.CONSUME(View);
|
|
3464
|
-
this.SUBRULE(this.
|
|
3509
|
+
this.SUBRULE(this.tableName);
|
|
3465
3510
|
});
|
|
3466
3511
|
// ==========================================================================
|
|
3467
3512
|
// GRANT / REVOKE Statements
|
|
@@ -3577,7 +3622,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3577
3622
|
});
|
|
3578
3623
|
});
|
|
3579
3624
|
this.grantTableTarget = this.RULE("grantTableTarget", () => {
|
|
3580
|
-
this.SUBRULE(this.
|
|
3625
|
+
this.SUBRULE(this.tableName);
|
|
3581
3626
|
this.OPTION(() => {
|
|
3582
3627
|
this.CONSUME(LParen);
|
|
3583
3628
|
this.SUBRULE(this.identifier);
|
|
@@ -3623,7 +3668,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3623
3668
|
this.vacuumTableStatement = this.RULE("vacuumTableStatement", () => {
|
|
3624
3669
|
this.CONSUME(Vacuum);
|
|
3625
3670
|
this.CONSUME(Table);
|
|
3626
|
-
this.SUBRULE(this.
|
|
3671
|
+
this.SUBRULE(this.tableName);
|
|
3627
3672
|
});
|
|
3628
3673
|
this.resumeWalStatement = this.RULE("resumeWalStatement", () => {
|
|
3629
3674
|
this.CONSUME(Resume);
|
|
@@ -3649,7 +3694,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3649
3694
|
this.reindexTableStatement = this.RULE("reindexTableStatement", () => {
|
|
3650
3695
|
this.CONSUME(Reindex);
|
|
3651
3696
|
this.CONSUME(Table);
|
|
3652
|
-
this.SUBRULE(this.
|
|
3697
|
+
this.SUBRULE(this.tableName);
|
|
3653
3698
|
this.OPTION(() => {
|
|
3654
3699
|
this.CONSUME(Column);
|
|
3655
3700
|
this.SUBRULE(this.identifier);
|
|
@@ -3680,7 +3725,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3680
3725
|
this.CONSUME(Refresh);
|
|
3681
3726
|
this.CONSUME(Materialized);
|
|
3682
3727
|
this.CONSUME(View);
|
|
3683
|
-
this.SUBRULE(this.
|
|
3728
|
+
this.SUBRULE(this.tableName);
|
|
3684
3729
|
this.OPTION(() => {
|
|
3685
3730
|
this.OR([
|
|
3686
3731
|
{ ALT: () => this.CONSUME(Full) },
|
|
@@ -3710,7 +3755,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
3710
3755
|
this.CONSUME1(RParen);
|
|
3711
3756
|
}
|
|
3712
3757
|
},
|
|
3713
|
-
{ ALT: () => this.SUBRULE(this.
|
|
3758
|
+
{ ALT: () => this.SUBRULE(this.tableName) }
|
|
3714
3759
|
]);
|
|
3715
3760
|
this.OPTION(() => this.SUBRULE(this.whereClause));
|
|
3716
3761
|
this.CONSUME(Pivot);
|
|
@@ -4463,6 +4508,20 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
|
|
|
4463
4508
|
this.columnRef = this.RULE("columnRef", () => {
|
|
4464
4509
|
this.SUBRULE(this.qualifiedName);
|
|
4465
4510
|
});
|
|
4511
|
+
// Wrapper for qualifiedName in table/view name positions.
|
|
4512
|
+
// Mirrors columnRef but for table references, so computeContentAssist
|
|
4513
|
+
// ruleStack includes "tableName" → autocomplete suggests existing tables.
|
|
4514
|
+
this.tableName = this.RULE("tableName", () => {
|
|
4515
|
+
this.SUBRULE(this.qualifiedName);
|
|
4516
|
+
});
|
|
4517
|
+
// Accepts StringLiteral or tableName. Used for table references that
|
|
4518
|
+
// can be quoted (INSERT INTO, RENAME TABLE, ALTER TABLE).
|
|
4519
|
+
this.tableNameOrString = this.RULE("tableNameOrString", () => {
|
|
4520
|
+
this.OR([
|
|
4521
|
+
{ ALT: () => this.CONSUME(StringLiteral) },
|
|
4522
|
+
{ ALT: () => this.SUBRULE(this.tableName) }
|
|
4523
|
+
]);
|
|
4524
|
+
});
|
|
4466
4525
|
this.qualifiedName = this.RULE("qualifiedName", () => {
|
|
4467
4526
|
this.SUBRULE(this.identifier);
|
|
4468
4527
|
this.MANY(() => {
|
|
@@ -4890,7 +4949,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
4890
4949
|
parts: [ctx.StringLiteral[0].image.slice(1, -1)]
|
|
4891
4950
|
};
|
|
4892
4951
|
} else {
|
|
4893
|
-
table = this.visit(ctx.
|
|
4952
|
+
table = this.visit(ctx.tableName);
|
|
4894
4953
|
}
|
|
4895
4954
|
const result = {
|
|
4896
4955
|
type: "tableRef",
|
|
@@ -4934,39 +4993,73 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
4934
4993
|
return void 0;
|
|
4935
4994
|
}
|
|
4936
4995
|
joinClause(ctx) {
|
|
4996
|
+
if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
|
|
4997
|
+
if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
|
|
4998
|
+
if (ctx.windowJoin) return this.visit(ctx.windowJoin);
|
|
4999
|
+
return this.visit(ctx.standardJoin);
|
|
5000
|
+
}
|
|
5001
|
+
asofLtJoin(ctx) {
|
|
4937
5002
|
const result = {
|
|
4938
5003
|
type: "join",
|
|
4939
5004
|
table: this.visit(ctx.tableRef)
|
|
4940
5005
|
};
|
|
4941
|
-
if (ctx.
|
|
4942
|
-
else if (ctx.Left) result.joinType = "left";
|
|
4943
|
-
else if (ctx.Right) result.joinType = "right";
|
|
4944
|
-
else if (ctx.Full) result.joinType = "full";
|
|
4945
|
-
else if (ctx.Cross) result.joinType = "cross";
|
|
4946
|
-
else if (ctx.Asof) result.joinType = "asof";
|
|
5006
|
+
if (ctx.Asof) result.joinType = "asof";
|
|
4947
5007
|
else if (ctx.Lt) result.joinType = "lt";
|
|
4948
|
-
else if (ctx.Splice) result.joinType = "splice";
|
|
4949
|
-
else if (ctx.Window) result.joinType = "window";
|
|
4950
|
-
if (ctx.Outer) {
|
|
4951
|
-
result.outer = true;
|
|
4952
|
-
}
|
|
4953
5008
|
if (ctx.expression) {
|
|
4954
5009
|
result.on = this.visit(ctx.expression);
|
|
4955
5010
|
}
|
|
4956
5011
|
if (ctx.DurationLiteral) {
|
|
4957
5012
|
result.tolerance = ctx.DurationLiteral[0].image;
|
|
4958
5013
|
}
|
|
5014
|
+
return result;
|
|
5015
|
+
}
|
|
5016
|
+
spliceJoin(ctx) {
|
|
5017
|
+
const result = {
|
|
5018
|
+
type: "join",
|
|
5019
|
+
joinType: "splice",
|
|
5020
|
+
table: this.visit(ctx.tableRef)
|
|
5021
|
+
};
|
|
5022
|
+
if (ctx.expression) {
|
|
5023
|
+
result.on = this.visit(ctx.expression);
|
|
5024
|
+
}
|
|
5025
|
+
return result;
|
|
5026
|
+
}
|
|
5027
|
+
windowJoin(ctx) {
|
|
5028
|
+
const result = {
|
|
5029
|
+
type: "join",
|
|
5030
|
+
table: this.visit(ctx.tableRef)
|
|
5031
|
+
};
|
|
5032
|
+
if (ctx.Window) result.joinType = "window";
|
|
5033
|
+
if (ctx.expression) {
|
|
5034
|
+
result.on = this.visit(ctx.expression);
|
|
5035
|
+
}
|
|
4959
5036
|
if (ctx.windowJoinBound && ctx.windowJoinBound.length >= 2) {
|
|
4960
5037
|
result.range = {
|
|
4961
5038
|
start: this.visit(ctx.windowJoinBound[0]),
|
|
4962
5039
|
end: this.visit(ctx.windowJoinBound[1])
|
|
4963
5040
|
};
|
|
4964
5041
|
}
|
|
4965
|
-
if (ctx.
|
|
5042
|
+
if (ctx.Include || ctx.Exclude) {
|
|
4966
5043
|
result.prevailing = ctx.Include ? "include" : "exclude";
|
|
4967
5044
|
}
|
|
4968
5045
|
return result;
|
|
4969
5046
|
}
|
|
5047
|
+
standardJoin(ctx) {
|
|
5048
|
+
const result = {
|
|
5049
|
+
type: "join",
|
|
5050
|
+
table: this.visit(ctx.tableRef)
|
|
5051
|
+
};
|
|
5052
|
+
if (ctx.Inner) result.joinType = "inner";
|
|
5053
|
+
else if (ctx.Left) result.joinType = "left";
|
|
5054
|
+
else if (ctx.Right) result.joinType = "right";
|
|
5055
|
+
else if (ctx.Full) result.joinType = "full";
|
|
5056
|
+
else if (ctx.Cross) result.joinType = "cross";
|
|
5057
|
+
if (ctx.Outer) result.outer = true;
|
|
5058
|
+
if (ctx.expression) {
|
|
5059
|
+
result.on = this.visit(ctx.expression);
|
|
5060
|
+
}
|
|
5061
|
+
return result;
|
|
5062
|
+
}
|
|
4970
5063
|
windowJoinBound(ctx) {
|
|
4971
5064
|
const result = {
|
|
4972
5065
|
type: "windowJoinBound",
|
|
@@ -5104,7 +5197,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5104
5197
|
insertStatement(ctx) {
|
|
5105
5198
|
const result = {
|
|
5106
5199
|
type: "insert",
|
|
5107
|
-
table: this.visit(ctx.
|
|
5200
|
+
table: this.visit(ctx.tableNameOrString)
|
|
5108
5201
|
};
|
|
5109
5202
|
if (ctx.Atomic) {
|
|
5110
5203
|
result.atomic = true;
|
|
@@ -5145,7 +5238,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5145
5238
|
updateStatement(ctx) {
|
|
5146
5239
|
const result = {
|
|
5147
5240
|
type: "update",
|
|
5148
|
-
table: this.visit(ctx.
|
|
5241
|
+
table: this.visit(ctx.tableName),
|
|
5149
5242
|
set: ctx.setClause.map((s) => this.visit(s))
|
|
5150
5243
|
};
|
|
5151
5244
|
if (ctx.identifier) {
|
|
@@ -5246,8 +5339,8 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5246
5339
|
(c) => this.visit(c)
|
|
5247
5340
|
);
|
|
5248
5341
|
}
|
|
5249
|
-
if (ctx.Like && ctx.
|
|
5250
|
-
result.like = this.visit(ctx.
|
|
5342
|
+
if (ctx.Like && ctx.tableName) {
|
|
5343
|
+
result.like = this.visit(ctx.tableName[0]);
|
|
5251
5344
|
}
|
|
5252
5345
|
if (ctx.selectStatement) {
|
|
5253
5346
|
result.asSelect = this.visit(
|
|
@@ -5630,10 +5723,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5630
5723
|
};
|
|
5631
5724
|
}
|
|
5632
5725
|
alterTableStatement(ctx) {
|
|
5633
|
-
const table =
|
|
5634
|
-
type: "qualifiedName",
|
|
5635
|
-
parts: [ctx.StringLiteral[0].image.slice(1, -1)]
|
|
5636
|
-
};
|
|
5726
|
+
const table = this.visit(ctx.tableNameOrString);
|
|
5637
5727
|
return {
|
|
5638
5728
|
type: "alterTable",
|
|
5639
5729
|
table,
|
|
@@ -5643,7 +5733,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5643
5733
|
alterMaterializedViewStatement(ctx) {
|
|
5644
5734
|
return {
|
|
5645
5735
|
type: "alterMaterializedView",
|
|
5646
|
-
view: this.visit(ctx.
|
|
5736
|
+
view: this.visit(ctx.tableName),
|
|
5647
5737
|
action: this.visit(
|
|
5648
5738
|
ctx.alterMaterializedViewAction
|
|
5649
5739
|
)
|
|
@@ -5651,9 +5741,10 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5651
5741
|
}
|
|
5652
5742
|
alterMaterializedViewAction(ctx) {
|
|
5653
5743
|
if (ctx.Add && ctx.Index) {
|
|
5744
|
+
const colRef = this.visit(ctx.columnRef[0]);
|
|
5654
5745
|
const result = {
|
|
5655
5746
|
actionType: "addIndex",
|
|
5656
|
-
column:
|
|
5747
|
+
column: colRef.name.parts[colRef.name.parts.length - 1]
|
|
5657
5748
|
};
|
|
5658
5749
|
if (ctx.Capacity && ctx.NumberLiteral) {
|
|
5659
5750
|
result.capacity = parseInt(ctx.NumberLiteral[0].image, 10);
|
|
@@ -5661,9 +5752,10 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5661
5752
|
return result;
|
|
5662
5753
|
}
|
|
5663
5754
|
if (ctx.Symbol && ctx.Capacity) {
|
|
5755
|
+
const colRef = this.visit(ctx.columnRef[0]);
|
|
5664
5756
|
return {
|
|
5665
5757
|
actionType: "symbolCapacity",
|
|
5666
|
-
column:
|
|
5758
|
+
column: colRef.name.parts[colRef.name.parts.length - 1],
|
|
5667
5759
|
capacity: parseInt(ctx.NumberLiteral[0].image, 10)
|
|
5668
5760
|
};
|
|
5669
5761
|
}
|
|
@@ -5680,9 +5772,10 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5680
5772
|
};
|
|
5681
5773
|
}
|
|
5682
5774
|
if (ctx.Alter && ctx.Drop && ctx.Index) {
|
|
5775
|
+
const colRef = this.visit(ctx.columnRef[0]);
|
|
5683
5776
|
return {
|
|
5684
5777
|
actionType: "dropIndex",
|
|
5685
|
-
column:
|
|
5778
|
+
column: colRef.name.parts[colRef.name.parts.length - 1]
|
|
5686
5779
|
};
|
|
5687
5780
|
}
|
|
5688
5781
|
if (ctx.Resume) {
|
|
@@ -5772,26 +5865,28 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5772
5865
|
}
|
|
5773
5866
|
return result;
|
|
5774
5867
|
}
|
|
5775
|
-
if (ctx.Drop && ctx.
|
|
5868
|
+
if (ctx.Drop && ctx.columnRef && !ctx.Partition && !ctx.Alter) {
|
|
5776
5869
|
return {
|
|
5777
5870
|
actionType: "dropColumn",
|
|
5778
|
-
columns: ctx.
|
|
5779
|
-
|
|
5780
|
-
|
|
5871
|
+
columns: ctx.columnRef.map((c) => {
|
|
5872
|
+
const ref = this.visit(c);
|
|
5873
|
+
return ref.name.parts[ref.name.parts.length - 1];
|
|
5874
|
+
})
|
|
5781
5875
|
};
|
|
5782
5876
|
}
|
|
5783
5877
|
if (ctx.Rename) {
|
|
5784
|
-
const
|
|
5785
|
-
|
|
5786
|
-
);
|
|
5878
|
+
const oldRef = this.visit(ctx.columnRef[0]);
|
|
5879
|
+
const oldName = oldRef.name.parts[oldRef.name.parts.length - 1];
|
|
5880
|
+
const newName = this.extractIdentifierName(ctx.identifier[0].children);
|
|
5787
5881
|
return {
|
|
5788
5882
|
actionType: "renameColumn",
|
|
5789
|
-
oldName
|
|
5790
|
-
newName
|
|
5883
|
+
oldName,
|
|
5884
|
+
newName
|
|
5791
5885
|
};
|
|
5792
5886
|
}
|
|
5793
|
-
if (ctx.Alter && ctx.
|
|
5794
|
-
const
|
|
5887
|
+
if (ctx.Alter && ctx.columnRef) {
|
|
5888
|
+
const colRef = this.visit(ctx.columnRef[0]);
|
|
5889
|
+
const column = colRef.name.parts[colRef.name.parts.length - 1];
|
|
5795
5890
|
let alterType = "type";
|
|
5796
5891
|
let newType;
|
|
5797
5892
|
let capacity;
|
|
@@ -5975,7 +6070,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
5975
6070
|
if (ctx.All) {
|
|
5976
6071
|
result.allTables = true;
|
|
5977
6072
|
} else {
|
|
5978
|
-
result.table = this.visit(ctx.
|
|
6073
|
+
result.table = this.visit(ctx.tableName);
|
|
5979
6074
|
if (ctx.If) {
|
|
5980
6075
|
result.ifExists = true;
|
|
5981
6076
|
}
|
|
@@ -6021,7 +6116,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6021
6116
|
// TRUNCATE TABLE Statement
|
|
6022
6117
|
// ==========================================================================
|
|
6023
6118
|
truncateTableStatement(ctx) {
|
|
6024
|
-
const tables = ctx.
|
|
6119
|
+
const tables = ctx.tableName.map(
|
|
6025
6120
|
(qn) => this.visit(qn)
|
|
6026
6121
|
);
|
|
6027
6122
|
const result = {
|
|
@@ -6045,8 +6140,8 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6045
6140
|
renameTableStatement(ctx) {
|
|
6046
6141
|
return {
|
|
6047
6142
|
type: "renameTable",
|
|
6048
|
-
from: this.visit(ctx.
|
|
6049
|
-
to: this.visit(ctx.
|
|
6143
|
+
from: this.visit(ctx.tableNameOrString[0]),
|
|
6144
|
+
to: this.visit(ctx.tableNameOrString[1])
|
|
6050
6145
|
};
|
|
6051
6146
|
}
|
|
6052
6147
|
addUserStatement(ctx) {
|
|
@@ -6254,7 +6349,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6254
6349
|
copyFrom(ctx) {
|
|
6255
6350
|
const result = {
|
|
6256
6351
|
type: "copyFrom",
|
|
6257
|
-
table: this.visit(ctx.
|
|
6352
|
+
table: this.visit(ctx.tableName),
|
|
6258
6353
|
file: this.extractMaybeString(ctx.stringOrIdentifier[0])
|
|
6259
6354
|
};
|
|
6260
6355
|
if (ctx.copyOptions) {
|
|
@@ -6263,7 +6358,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6263
6358
|
return result;
|
|
6264
6359
|
}
|
|
6265
6360
|
copyTo(ctx) {
|
|
6266
|
-
const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.
|
|
6361
|
+
const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.tableName);
|
|
6267
6362
|
const result = {
|
|
6268
6363
|
type: "copyTo",
|
|
6269
6364
|
source,
|
|
@@ -6345,13 +6440,13 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6345
6440
|
return {
|
|
6346
6441
|
type: "backup",
|
|
6347
6442
|
action: "table",
|
|
6348
|
-
table: this.visit(ctx.
|
|
6443
|
+
table: this.visit(ctx.tableName)
|
|
6349
6444
|
};
|
|
6350
6445
|
}
|
|
6351
6446
|
compileViewStatement(ctx) {
|
|
6352
6447
|
return {
|
|
6353
6448
|
type: "compileView",
|
|
6354
|
-
view: this.visit(ctx.
|
|
6449
|
+
view: this.visit(ctx.tableName)
|
|
6355
6450
|
};
|
|
6356
6451
|
}
|
|
6357
6452
|
convertPartitionTarget(ctx) {
|
|
@@ -6450,7 +6545,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6450
6545
|
grantTableTarget(ctx) {
|
|
6451
6546
|
const result = {
|
|
6452
6547
|
type: "grantTableTarget",
|
|
6453
|
-
table: this.visit(ctx.
|
|
6548
|
+
table: this.visit(ctx.tableName)
|
|
6454
6549
|
};
|
|
6455
6550
|
if (ctx.identifier && ctx.identifier.length > 0) {
|
|
6456
6551
|
result.columns = ctx.identifier.map(
|
|
@@ -6480,7 +6575,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6480
6575
|
vacuumTableStatement(ctx) {
|
|
6481
6576
|
return {
|
|
6482
6577
|
type: "vacuumTable",
|
|
6483
|
-
table: this.visit(ctx.
|
|
6578
|
+
table: this.visit(ctx.tableName)
|
|
6484
6579
|
};
|
|
6485
6580
|
}
|
|
6486
6581
|
resumeWalStatement(ctx) {
|
|
@@ -6505,7 +6600,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6505
6600
|
reindexTableStatement(ctx) {
|
|
6506
6601
|
const result = {
|
|
6507
6602
|
type: "reindexTable",
|
|
6508
|
-
table: this.visit(ctx.
|
|
6603
|
+
table: this.visit(ctx.tableName)
|
|
6509
6604
|
};
|
|
6510
6605
|
if (ctx.Column && ctx.identifier) {
|
|
6511
6606
|
result.columns = ctx.identifier.map(
|
|
@@ -6525,7 +6620,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6525
6620
|
refreshMaterializedViewStatement(ctx) {
|
|
6526
6621
|
const result = {
|
|
6527
6622
|
type: "refreshMaterializedView",
|
|
6528
|
-
view: this.visit(ctx.
|
|
6623
|
+
view: this.visit(ctx.tableName)
|
|
6529
6624
|
};
|
|
6530
6625
|
if (ctx.Full) result.mode = "full";
|
|
6531
6626
|
if (ctx.Incremental) result.mode = "incremental";
|
|
@@ -6542,7 +6637,7 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
6542
6637
|
// PIVOT Statement
|
|
6543
6638
|
// ==========================================================================
|
|
6544
6639
|
pivotStatement(ctx) {
|
|
6545
|
-
const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.
|
|
6640
|
+
const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.tableName);
|
|
6546
6641
|
const body = ctx.pivotBody ? this.visit(ctx.pivotBody) : {};
|
|
6547
6642
|
const result = {
|
|
6548
6643
|
type: "pivot",
|
|
@@ -7397,6 +7492,19 @@ var QuestDBVisitor = class extends BaseVisitor {
|
|
|
7397
7492
|
name: this.visit(ctx.qualifiedName)
|
|
7398
7493
|
};
|
|
7399
7494
|
}
|
|
7495
|
+
tableName(ctx) {
|
|
7496
|
+
return this.visit(ctx.qualifiedName);
|
|
7497
|
+
}
|
|
7498
|
+
tableNameOrString(ctx) {
|
|
7499
|
+
if (ctx.StringLiteral) {
|
|
7500
|
+
return {
|
|
7501
|
+
type: "qualifiedName",
|
|
7502
|
+
parts: [ctx.StringLiteral[0].image.slice(1, -1)]
|
|
7503
|
+
};
|
|
7504
|
+
}
|
|
7505
|
+
if (ctx.tableName) return this.visit(ctx.tableName);
|
|
7506
|
+
return { type: "qualifiedName", parts: [] };
|
|
7507
|
+
}
|
|
7400
7508
|
qualifiedName(ctx) {
|
|
7401
7509
|
const parts = ctx.identifier.map((id) => {
|
|
7402
7510
|
return this.extractIdentifierName(id.children);
|
|
@@ -9222,6 +9330,18 @@ function extractTablesFromAst(ast) {
|
|
|
9222
9330
|
tables.push({ table: tableName });
|
|
9223
9331
|
}
|
|
9224
9332
|
}
|
|
9333
|
+
if ((n.type === "alterTable" || n.type === "alterMaterializedView") && n.table) {
|
|
9334
|
+
const tableName = normalizeTableName(n.table);
|
|
9335
|
+
if (tableName) {
|
|
9336
|
+
tables.push({ table: tableName });
|
|
9337
|
+
}
|
|
9338
|
+
}
|
|
9339
|
+
if (n.type === "alterMaterializedView" && n.view) {
|
|
9340
|
+
const viewName = normalizeTableName(n.view);
|
|
9341
|
+
if (viewName) {
|
|
9342
|
+
tables.push({ table: viewName });
|
|
9343
|
+
}
|
|
9344
|
+
}
|
|
9225
9345
|
for (const key of Object.keys(n)) {
|
|
9226
9346
|
const child = n[key];
|
|
9227
9347
|
if (Array.isArray(child)) {
|
|
@@ -9373,23 +9493,34 @@ function extractTables(fullSql, tokens) {
|
|
|
9373
9493
|
fullSql,
|
|
9374
9494
|
tokens
|
|
9375
9495
|
);
|
|
9496
|
+
const DDL_TABLE_PREFIXES = /* @__PURE__ */ new Set(["Alter", "Truncate", "Drop"]);
|
|
9376
9497
|
for (let i = outerQueryStart; i < tokens.length; i++) {
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
aliasStart
|
|
9498
|
+
const tokenName = tokens[i].tokenType.name;
|
|
9499
|
+
if (TABLE_PREFIX_TOKENS.has(tokenName)) {
|
|
9500
|
+
const tableNameResult = readQualifiedName(i + 1);
|
|
9501
|
+
if (!tableNameResult) continue;
|
|
9502
|
+
let alias;
|
|
9503
|
+
let aliasStart = tableNameResult.nextIndex;
|
|
9504
|
+
if (tokens[aliasStart]?.tokenType.name === "As") {
|
|
9505
|
+
aliasStart++;
|
|
9506
|
+
}
|
|
9507
|
+
if (isIdentifierLike(tokens[aliasStart])) {
|
|
9508
|
+
alias = tokenToNamePart(tokens[aliasStart]);
|
|
9509
|
+
}
|
|
9510
|
+
tables.push({
|
|
9511
|
+
table: tableNameResult.name,
|
|
9512
|
+
alias
|
|
9513
|
+
});
|
|
9514
|
+
i = alias ? aliasStart : tableNameResult.nextIndex - 1;
|
|
9515
|
+
continue;
|
|
9384
9516
|
}
|
|
9385
|
-
if (
|
|
9386
|
-
|
|
9517
|
+
if (DDL_TABLE_PREFIXES.has(tokenName) && tokens[i + 1]?.tokenType.name === "Table") {
|
|
9518
|
+
const tableNameResult = readQualifiedName(i + 2);
|
|
9519
|
+
if (tableNameResult) {
|
|
9520
|
+
tables.push({ table: tableNameResult.name });
|
|
9521
|
+
i = tableNameResult.nextIndex - 1;
|
|
9522
|
+
}
|
|
9387
9523
|
}
|
|
9388
|
-
tables.push({
|
|
9389
|
-
table: tableNameResult.name,
|
|
9390
|
-
alias
|
|
9391
|
-
});
|
|
9392
|
-
i = alias ? aliasStart : tableNameResult.nextIndex - 1;
|
|
9393
9524
|
}
|
|
9394
9525
|
for (const name of cteNames) {
|
|
9395
9526
|
tables.push({ table: name });
|
|
@@ -9425,6 +9556,13 @@ function collapseTrailingQualifiedRef(tokens) {
|
|
|
9425
9556
|
if (start >= i) return null;
|
|
9426
9557
|
return [...tokens.slice(0, start), lastToken];
|
|
9427
9558
|
}
|
|
9559
|
+
function classifyIdentifierPath(ruleStack) {
|
|
9560
|
+
if (ruleStack.includes("valuesClause")) return "newName";
|
|
9561
|
+
if (ruleStack.includes("identifierExpression") || ruleStack.includes("columnRef") || ruleStack.includes("qualifiedStar"))
|
|
9562
|
+
return "column";
|
|
9563
|
+
if (ruleStack.includes("tableName")) return "table";
|
|
9564
|
+
return "newName";
|
|
9565
|
+
}
|
|
9428
9566
|
function computeSuggestions(tokens) {
|
|
9429
9567
|
const ruleName = tokens.some((t) => t.tokenType.name === "Semicolon") ? "statements" : "statement";
|
|
9430
9568
|
const suggestions = parser.computeContentAssist(ruleName, tokens);
|
|
@@ -9436,10 +9574,21 @@ function computeSuggestions(tokens) {
|
|
|
9436
9574
|
const specific = suggestions.filter(
|
|
9437
9575
|
(s) => !isImplicitStatementPath(s.ruleStack, IMPLICIT_RULES)
|
|
9438
9576
|
);
|
|
9439
|
-
const result = (specific.length > 0 ? specific : suggestions).map(
|
|
9440
|
-
(s) => s.nextTokenType
|
|
9441
|
-
);
|
|
9442
9577
|
const effectiveSuggestions = specific.length > 0 ? specific : suggestions;
|
|
9578
|
+
const result = effectiveSuggestions.map((s) => s.nextTokenType);
|
|
9579
|
+
let suggestColumns = false;
|
|
9580
|
+
let suggestTables = false;
|
|
9581
|
+
for (const s of effectiveSuggestions) {
|
|
9582
|
+
if (s.nextTokenType.name === "IdentifierKeyword") {
|
|
9583
|
+
const cls = classifyIdentifierPath(s.ruleStack);
|
|
9584
|
+
if (cls === "column") {
|
|
9585
|
+
suggestColumns = true;
|
|
9586
|
+
suggestTables = true;
|
|
9587
|
+
} else if (cls === "table") {
|
|
9588
|
+
suggestTables = true;
|
|
9589
|
+
}
|
|
9590
|
+
}
|
|
9591
|
+
}
|
|
9443
9592
|
if (effectiveSuggestions.length > 0 && effectiveSuggestions.every((s) => s.ruleStack.includes("qualifiedStar"))) {
|
|
9444
9593
|
const collapsed = collapseTrailingQualifiedRef(tokens);
|
|
9445
9594
|
if (collapsed) {
|
|
@@ -9448,19 +9597,28 @@ function computeSuggestions(tokens) {
|
|
|
9448
9597
|
const filteredExtra = extra.filter(
|
|
9449
9598
|
(s) => !isImplicitStatementPath(s.ruleStack, IMPLICIT_RULES)
|
|
9450
9599
|
);
|
|
9451
|
-
const
|
|
9600
|
+
const extraEffective = filteredExtra.length > 0 ? filteredExtra : extra;
|
|
9452
9601
|
const seen = new Set(result.map((t) => t.name));
|
|
9453
|
-
for (const
|
|
9454
|
-
if (!seen.has(
|
|
9455
|
-
seen.add(
|
|
9456
|
-
result.push(
|
|
9602
|
+
for (const s of extraEffective) {
|
|
9603
|
+
if (!seen.has(s.nextTokenType.name)) {
|
|
9604
|
+
seen.add(s.nextTokenType.name);
|
|
9605
|
+
result.push(s.nextTokenType);
|
|
9606
|
+
}
|
|
9607
|
+
if (s.nextTokenType.name === "IdentifierKeyword") {
|
|
9608
|
+
const cls = classifyIdentifierPath(s.ruleStack);
|
|
9609
|
+
if (cls === "column") {
|
|
9610
|
+
suggestColumns = true;
|
|
9611
|
+
suggestTables = true;
|
|
9612
|
+
} else if (cls === "table") {
|
|
9613
|
+
suggestTables = true;
|
|
9614
|
+
}
|
|
9457
9615
|
}
|
|
9458
9616
|
}
|
|
9459
9617
|
} catch (e) {
|
|
9460
9618
|
}
|
|
9461
9619
|
}
|
|
9462
9620
|
}
|
|
9463
|
-
return result;
|
|
9621
|
+
return { nextTokenTypes: result, suggestColumns, suggestTables };
|
|
9464
9622
|
}
|
|
9465
9623
|
function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
|
|
9466
9624
|
const effective = isMidWord ? tokensBefore.slice(0, -1) : tokensBefore;
|
|
@@ -9472,6 +9630,32 @@ function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
|
|
|
9472
9630
|
const table = tableToken.tokenType.name === "QuotedIdentifier" ? tableToken.image.slice(1, -1) : tableToken.image;
|
|
9473
9631
|
return { table };
|
|
9474
9632
|
}
|
|
9633
|
+
function extractReferencedColumns(tokens, tableAndAliasSet) {
|
|
9634
|
+
const result = /* @__PURE__ */ new Set();
|
|
9635
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
9636
|
+
const token = tokens[i];
|
|
9637
|
+
const name = token.tokenType.name;
|
|
9638
|
+
if (name !== "Identifier" && name !== "QuotedIdentifier" && !IDENTIFIER_KEYWORD_TOKENS.has(name)) {
|
|
9639
|
+
continue;
|
|
9640
|
+
}
|
|
9641
|
+
if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
|
|
9642
|
+
continue;
|
|
9643
|
+
}
|
|
9644
|
+
if (i > 0 && tokens[i - 1].tokenType.name === "Dot" && i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
|
|
9645
|
+
continue;
|
|
9646
|
+
}
|
|
9647
|
+
if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "LParen") {
|
|
9648
|
+
continue;
|
|
9649
|
+
}
|
|
9650
|
+
const image = name === "QuotedIdentifier" ? token.image.slice(1, -1) : token.image;
|
|
9651
|
+
const lower = image.toLowerCase();
|
|
9652
|
+
if (tableAndAliasSet.has(lower)) {
|
|
9653
|
+
continue;
|
|
9654
|
+
}
|
|
9655
|
+
result.add(lower);
|
|
9656
|
+
}
|
|
9657
|
+
return result;
|
|
9658
|
+
}
|
|
9475
9659
|
function getContentAssist(fullSql, cursorOffset) {
|
|
9476
9660
|
const fullTokens = QuestDBLexer.tokenize(fullSql).tokens;
|
|
9477
9661
|
for (const token of fullTokens) {
|
|
@@ -9486,7 +9670,10 @@ function getContentAssist(fullSql, cursorOffset) {
|
|
|
9486
9670
|
cteColumns: {},
|
|
9487
9671
|
tokensBefore: [],
|
|
9488
9672
|
isMidWord: true,
|
|
9489
|
-
lexErrors: []
|
|
9673
|
+
lexErrors: [],
|
|
9674
|
+
suggestColumns: false,
|
|
9675
|
+
suggestTables: false,
|
|
9676
|
+
referencedColumns: /* @__PURE__ */ new Set()
|
|
9490
9677
|
};
|
|
9491
9678
|
}
|
|
9492
9679
|
}
|
|
@@ -9497,8 +9684,13 @@ function getContentAssist(fullSql, cursorOffset) {
|
|
|
9497
9684
|
const isMidWord = !WORD_BOUNDARY_CHARS.has(lastChar);
|
|
9498
9685
|
const tokensForAssist = isMidWord && tokens.length > 0 ? tokens.slice(0, -1) : tokens;
|
|
9499
9686
|
let nextTokenTypes = [];
|
|
9687
|
+
let suggestColumns = false;
|
|
9688
|
+
let suggestTables = false;
|
|
9500
9689
|
try {
|
|
9501
|
-
|
|
9690
|
+
const computed = computeSuggestions(tokensForAssist);
|
|
9691
|
+
nextTokenTypes = computed.nextTokenTypes;
|
|
9692
|
+
suggestColumns = computed.suggestColumns;
|
|
9693
|
+
suggestTables = computed.suggestTables;
|
|
9502
9694
|
} catch (e) {
|
|
9503
9695
|
}
|
|
9504
9696
|
const { tables: tablesInScope, cteColumns } = extractTables(
|
|
@@ -9533,6 +9725,15 @@ function getContentAssist(fullSql, cursorOffset) {
|
|
|
9533
9725
|
if (tablesInScope.length === 0 && qualifiedRef) {
|
|
9534
9726
|
tablesInScope.push(qualifiedRef);
|
|
9535
9727
|
}
|
|
9728
|
+
const tableAndAliasSet = /* @__PURE__ */ new Set();
|
|
9729
|
+
for (const t of tablesInScope) {
|
|
9730
|
+
tableAndAliasSet.add(t.table.toLowerCase());
|
|
9731
|
+
if (t.alias) tableAndAliasSet.add(t.alias.toLowerCase());
|
|
9732
|
+
}
|
|
9733
|
+
const referencedColumns = extractReferencedColumns(
|
|
9734
|
+
tokensForAssist,
|
|
9735
|
+
tableAndAliasSet
|
|
9736
|
+
);
|
|
9536
9737
|
return {
|
|
9537
9738
|
nextTokenTypes,
|
|
9538
9739
|
tablesInScope,
|
|
@@ -9540,13 +9741,18 @@ function getContentAssist(fullSql, cursorOffset) {
|
|
|
9540
9741
|
tokensBefore: tokens,
|
|
9541
9742
|
isMidWord,
|
|
9542
9743
|
lexErrors: lexResult.errors,
|
|
9543
|
-
qualifiedTableRef: qualifiedRef?.table
|
|
9744
|
+
qualifiedTableRef: qualifiedRef?.table,
|
|
9745
|
+
suggestColumns,
|
|
9746
|
+
suggestTables,
|
|
9747
|
+
referencedColumns
|
|
9544
9748
|
};
|
|
9545
9749
|
}
|
|
9546
9750
|
function getNextValidTokens(sql) {
|
|
9547
9751
|
const lexResult = QuestDBLexer.tokenize(sql);
|
|
9548
9752
|
try {
|
|
9549
|
-
return computeSuggestions(lexResult.tokens).map(
|
|
9753
|
+
return computeSuggestions(lexResult.tokens).nextTokenTypes.map(
|
|
9754
|
+
(t) => t.name
|
|
9755
|
+
);
|
|
9550
9756
|
} catch (e) {
|
|
9551
9757
|
return [];
|
|
9552
9758
|
}
|
|
@@ -10118,6 +10324,35 @@ var TABLE_NAME_TOKENS = /* @__PURE__ */ new Set([
|
|
|
10118
10324
|
"Table",
|
|
10119
10325
|
"View"
|
|
10120
10326
|
]);
|
|
10327
|
+
function buildColumnIndex(schema) {
|
|
10328
|
+
const index = /* @__PURE__ */ new Map();
|
|
10329
|
+
for (const table of schema.tables) {
|
|
10330
|
+
const key = table.name.toLowerCase();
|
|
10331
|
+
const cols = schema.columns[key];
|
|
10332
|
+
if (cols) {
|
|
10333
|
+
index.set(key, new Set(cols.map((c) => c.name.toLowerCase())));
|
|
10334
|
+
}
|
|
10335
|
+
}
|
|
10336
|
+
return index;
|
|
10337
|
+
}
|
|
10338
|
+
function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
|
|
10339
|
+
if (referencedColumns.size === 0) return;
|
|
10340
|
+
const scores = /* @__PURE__ */ new Map();
|
|
10341
|
+
for (const [tableName, colNames] of columnIndex) {
|
|
10342
|
+
let count = 0;
|
|
10343
|
+
for (const ref of referencedColumns) {
|
|
10344
|
+
if (colNames.has(ref)) count++;
|
|
10345
|
+
}
|
|
10346
|
+
if (count > 0) scores.set(tableName, count);
|
|
10347
|
+
}
|
|
10348
|
+
if (scores.size === 0) return;
|
|
10349
|
+
for (const s of suggestions) {
|
|
10350
|
+
if (s.kind !== "table" /* Table */) continue;
|
|
10351
|
+
const score = scores.get(s.label.toLowerCase());
|
|
10352
|
+
if (score === void 0) continue;
|
|
10353
|
+
s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
|
|
10354
|
+
}
|
|
10355
|
+
}
|
|
10121
10356
|
function getLastSignificantTokens(tokens) {
|
|
10122
10357
|
const result = [];
|
|
10123
10358
|
for (let i = tokens.length - 1; i >= 0; i--) {
|
|
@@ -10131,45 +10366,6 @@ function getLastSignificantTokens(tokens) {
|
|
|
10131
10366
|
}
|
|
10132
10367
|
return result;
|
|
10133
10368
|
}
|
|
10134
|
-
var EXPRESSION_END_TOKENS = /* @__PURE__ */ new Set([
|
|
10135
|
-
"Identifier",
|
|
10136
|
-
"QuotedIdentifier",
|
|
10137
|
-
"RParen",
|
|
10138
|
-
"NumberLiteral",
|
|
10139
|
-
"LongLiteral",
|
|
10140
|
-
"DecimalLiteral",
|
|
10141
|
-
"StringLiteral"
|
|
10142
|
-
]);
|
|
10143
|
-
function isExpressionEnd(tokenName) {
|
|
10144
|
-
return EXPRESSION_END_TOKENS.has(tokenName) || IDENTIFIER_KEYWORD_TOKENS.has(tokenName);
|
|
10145
|
-
}
|
|
10146
|
-
function getIdentifierSuggestionScope(lastTokenName, prevTokenName, rawLastTokenName, rawPrevTokenName) {
|
|
10147
|
-
if (rawLastTokenName && isExpressionEnd(rawLastTokenName)) {
|
|
10148
|
-
return { includeColumns: false, includeTables: false };
|
|
10149
|
-
}
|
|
10150
|
-
if (rawLastTokenName === "Star") {
|
|
10151
|
-
if (rawPrevTokenName && isExpressionEnd(rawPrevTokenName)) {
|
|
10152
|
-
return { includeColumns: true, includeTables: true };
|
|
10153
|
-
}
|
|
10154
|
-
return { includeColumns: false, includeTables: false };
|
|
10155
|
-
}
|
|
10156
|
-
if (lastTokenName === "As") {
|
|
10157
|
-
if (rawLastTokenName === "LParen") {
|
|
10158
|
-
return { includeColumns: false, includeTables: true };
|
|
10159
|
-
}
|
|
10160
|
-
return { includeColumns: false, includeTables: false };
|
|
10161
|
-
}
|
|
10162
|
-
if (prevTokenName && TABLE_NAME_TOKENS.has(prevTokenName)) {
|
|
10163
|
-
return { includeColumns: false, includeTables: true };
|
|
10164
|
-
}
|
|
10165
|
-
if (lastTokenName && TABLE_NAME_TOKENS.has(lastTokenName)) {
|
|
10166
|
-
return { includeColumns: false, includeTables: true };
|
|
10167
|
-
}
|
|
10168
|
-
if (!lastTokenName) {
|
|
10169
|
-
return { includeColumns: false, includeTables: true };
|
|
10170
|
-
}
|
|
10171
|
-
return { includeColumns: true, includeTables: true };
|
|
10172
|
-
}
|
|
10173
10369
|
function createAutocompleteProvider(schema) {
|
|
10174
10370
|
const normalizedSchema = {
|
|
10175
10371
|
tables: schema.tables,
|
|
@@ -10180,6 +10376,7 @@ function createAutocompleteProvider(schema) {
|
|
|
10180
10376
|
])
|
|
10181
10377
|
)
|
|
10182
10378
|
};
|
|
10379
|
+
const columnIndex = buildColumnIndex(normalizedSchema);
|
|
10183
10380
|
return {
|
|
10184
10381
|
getSuggestions(query, cursorOffset) {
|
|
10185
10382
|
const {
|
|
@@ -10188,7 +10385,10 @@ function createAutocompleteProvider(schema) {
|
|
|
10188
10385
|
cteColumns,
|
|
10189
10386
|
tokensBefore,
|
|
10190
10387
|
isMidWord,
|
|
10191
|
-
qualifiedTableRef
|
|
10388
|
+
qualifiedTableRef,
|
|
10389
|
+
suggestColumns,
|
|
10390
|
+
suggestTables,
|
|
10391
|
+
referencedColumns
|
|
10192
10392
|
} = getContentAssist(query, cursorOffset);
|
|
10193
10393
|
const effectiveSchema = Object.keys(cteColumns).length > 0 ? {
|
|
10194
10394
|
...normalizedSchema,
|
|
@@ -10216,22 +10416,20 @@ function createAutocompleteProvider(schema) {
|
|
|
10216
10416
|
}
|
|
10217
10417
|
}
|
|
10218
10418
|
if (nextTokenTypes.length > 0) {
|
|
10219
|
-
const
|
|
10220
|
-
const [lastTokenName, prevTokenName] = getLastSignificantTokens(tokensForScope);
|
|
10221
|
-
const rawLastTokenName = tokensForScope.length > 0 ? tokensForScope[tokensForScope.length - 1]?.tokenType?.name : void 0;
|
|
10222
|
-
const rawPrevTokenName = tokensForScope.length > 1 ? tokensForScope[tokensForScope.length - 2]?.tokenType?.name : void 0;
|
|
10223
|
-
const scope = getIdentifierSuggestionScope(
|
|
10224
|
-
lastTokenName,
|
|
10225
|
-
prevTokenName,
|
|
10226
|
-
rawLastTokenName,
|
|
10227
|
-
rawPrevTokenName
|
|
10228
|
-
);
|
|
10229
|
-
return buildSuggestions(
|
|
10419
|
+
const suggestions = buildSuggestions(
|
|
10230
10420
|
nextTokenTypes,
|
|
10231
10421
|
effectiveSchema,
|
|
10232
10422
|
effectiveTablesInScope,
|
|
10233
|
-
{
|
|
10423
|
+
{
|
|
10424
|
+
includeColumns: suggestColumns,
|
|
10425
|
+
includeTables: suggestTables,
|
|
10426
|
+
isMidWord
|
|
10427
|
+
}
|
|
10234
10428
|
);
|
|
10429
|
+
if (suggestTables) {
|
|
10430
|
+
rankTableSuggestions(suggestions, referencedColumns, columnIndex);
|
|
10431
|
+
}
|
|
10432
|
+
return suggestions;
|
|
10235
10433
|
}
|
|
10236
10434
|
const fallbackTokens = isMidWord && tokensBefore.length > 0 ? tokensBefore.slice(0, -1) : tokensBefore;
|
|
10237
10435
|
const [lastFallback] = getLastSignificantTokens(fallbackTokens);
|
|
@@ -10260,6 +10458,7 @@ function createAutocompleteProvider(schema) {
|
|
|
10260
10458
|
});
|
|
10261
10459
|
}
|
|
10262
10460
|
}
|
|
10461
|
+
rankTableSuggestions(suggestions, referencedColumns, columnIndex);
|
|
10263
10462
|
return suggestions;
|
|
10264
10463
|
}
|
|
10265
10464
|
return [];
|