@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/dist/index.js CHANGED
@@ -1418,7 +1418,7 @@ var QuestDBParser = class extends CstParser {
1418
1418
  ALT: () => this.CONSUME(VariableReference)
1419
1419
  },
1420
1420
  { ALT: () => this.CONSUME(StringLiteral) },
1421
- { ALT: () => this.SUBRULE(this.qualifiedName) }
1421
+ { ALT: () => this.SUBRULE(this.tableName) }
1422
1422
  ]);
1423
1423
  this.OPTION2(() => {
1424
1424
  this.CONSUME(Timestamp);
@@ -1466,47 +1466,95 @@ var QuestDBParser = class extends CstParser {
1466
1466
  this.tableFunctionName = this.RULE("tableFunctionName", () => {
1467
1467
  this.SUBRULE(this.identifier);
1468
1468
  });
1469
+ // ---- Join clause: dispatches to type-specific sub-rules so that each
1470
+ // join type only offers its own valid postamble tokens.
1469
1471
  this.joinClause = this.RULE("joinClause", () => {
1470
- this.OPTION(() => {
1471
- this.OR([
1472
- { ALT: () => this.CONSUME(Inner) },
1473
- { ALT: () => this.CONSUME(Left) },
1474
- { ALT: () => this.CONSUME(Right) },
1475
- { ALT: () => this.CONSUME(Full) },
1476
- { ALT: () => this.CONSUME(Cross) },
1477
- { ALT: () => this.CONSUME(Asof) },
1478
- { ALT: () => this.CONSUME(Lt) },
1479
- { ALT: () => this.CONSUME(Splice) },
1480
- { ALT: () => this.CONSUME(Window) },
1481
- { ALT: () => this.CONSUME(Prevailing) }
1482
- ]);
1483
- this.OPTION1(() => this.CONSUME(Outer));
1484
- });
1472
+ this.OR([
1473
+ { ALT: () => this.SUBRULE(this.asofLtJoin) },
1474
+ { ALT: () => this.SUBRULE(this.spliceJoin) },
1475
+ { ALT: () => this.SUBRULE(this.windowJoin) },
1476
+ { ALT: () => this.SUBRULE(this.standardJoin) }
1477
+ ]);
1478
+ });
1479
+ // ASOF/LT JOIN: ON + TOLERANCE
1480
+ this.asofLtJoin = this.RULE("asofLtJoin", () => {
1481
+ this.OR([
1482
+ { ALT: () => this.CONSUME(Asof) },
1483
+ { ALT: () => this.CONSUME(Lt) }
1484
+ ]);
1485
1485
  this.CONSUME(Join);
1486
1486
  this.SUBRULE(this.tableRef);
1487
- this.OPTION2(() => {
1487
+ this.OPTION(() => {
1488
1488
  this.CONSUME(On);
1489
1489
  this.SUBRULE(this.expression);
1490
1490
  });
1491
- this.OPTION3(() => {
1491
+ this.OPTION1(() => {
1492
1492
  this.CONSUME(Tolerance);
1493
1493
  this.CONSUME(DurationLiteral);
1494
1494
  });
1495
- this.OPTION4(() => {
1495
+ });
1496
+ // SPLICE JOIN: ON only
1497
+ this.spliceJoin = this.RULE("spliceJoin", () => {
1498
+ this.CONSUME(Splice);
1499
+ this.CONSUME(Join);
1500
+ this.SUBRULE(this.tableRef);
1501
+ this.OPTION(() => {
1502
+ this.CONSUME(On);
1503
+ this.SUBRULE(this.expression);
1504
+ });
1505
+ });
1506
+ // WINDOW/PREVAILING JOIN: ON + RANGE BETWEEN + INCLUDE/EXCLUDE PREVAILING
1507
+ this.windowJoin = this.RULE("windowJoin", () => {
1508
+ this.OR([
1509
+ { ALT: () => this.CONSUME(Window) },
1510
+ { ALT: () => this.CONSUME(Prevailing) }
1511
+ ]);
1512
+ this.CONSUME(Join);
1513
+ this.SUBRULE(this.tableRef);
1514
+ this.OPTION(() => {
1515
+ this.CONSUME(On);
1516
+ this.SUBRULE(this.expression);
1517
+ });
1518
+ this.OPTION1(() => {
1496
1519
  this.CONSUME(Range);
1497
1520
  this.CONSUME(Between);
1498
1521
  this.SUBRULE(this.windowJoinBound);
1499
1522
  this.CONSUME(And);
1500
1523
  this.SUBRULE1(this.windowJoinBound);
1501
1524
  });
1502
- this.OPTION5(() => {
1503
- this.OR3([
1525
+ this.OPTION2(() => {
1526
+ this.OR1([
1504
1527
  { ALT: () => this.CONSUME(Include) },
1505
1528
  { ALT: () => this.CONSUME(Exclude) }
1506
1529
  ]);
1507
1530
  this.CONSUME1(Prevailing);
1508
1531
  });
1509
1532
  });
1533
+ // Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
1534
+ this.standardJoin = this.RULE("standardJoin", () => {
1535
+ this.OPTION(() => {
1536
+ this.OR([
1537
+ {
1538
+ ALT: () => {
1539
+ this.OR1([
1540
+ { ALT: () => this.CONSUME(Left) },
1541
+ { ALT: () => this.CONSUME(Right) },
1542
+ { ALT: () => this.CONSUME(Full) }
1543
+ ]);
1544
+ this.OPTION1(() => this.CONSUME(Outer));
1545
+ }
1546
+ },
1547
+ { ALT: () => this.CONSUME(Inner) },
1548
+ { ALT: () => this.CONSUME(Cross) }
1549
+ ]);
1550
+ });
1551
+ this.CONSUME(Join);
1552
+ this.SUBRULE(this.tableRef);
1553
+ this.OPTION2(() => {
1554
+ this.CONSUME(On);
1555
+ this.SUBRULE(this.expression);
1556
+ });
1557
+ });
1510
1558
  // Window join bound: <number> <timeUnit> PRECEDING/FOLLOWING | CURRENT ROW [PRECEDING/FOLLOWING] | DurationLiteral PRECEDING/FOLLOWING
1511
1559
  this.windowJoinBound = this.RULE("windowJoinBound", () => {
1512
1560
  this.OR([
@@ -1720,7 +1768,7 @@ var QuestDBParser = class extends CstParser {
1720
1768
  ]);
1721
1769
  });
1722
1770
  this.CONSUME(Into);
1723
- this.SUBRULE(this.stringOrQualifiedName);
1771
+ this.SUBRULE(this.tableNameOrString);
1724
1772
  this.OPTION2(() => this.SUBRULE1(this.batchClause));
1725
1773
  this.OPTION3(() => {
1726
1774
  this.CONSUME(LParen);
@@ -1758,7 +1806,7 @@ var QuestDBParser = class extends CstParser {
1758
1806
  // ==========================================================================
1759
1807
  this.updateStatement = this.RULE("updateStatement", () => {
1760
1808
  this.CONSUME(Update);
1761
- this.SUBRULE(this.qualifiedName);
1809
+ this.SUBRULE(this.tableName);
1762
1810
  this.OPTION2(() => this.SUBRULE(this.identifier));
1763
1811
  this.CONSUME(Set2);
1764
1812
  this.SUBRULE(this.setClause);
@@ -1909,7 +1957,7 @@ var QuestDBParser = class extends CstParser {
1909
1957
  ALT: () => {
1910
1958
  this.CONSUME2(LParen);
1911
1959
  this.CONSUME(Like);
1912
- this.SUBRULE2(this.qualifiedName);
1960
+ this.SUBRULE(this.tableName);
1913
1961
  this.CONSUME2(RParen);
1914
1962
  }
1915
1963
  }
@@ -2477,10 +2525,7 @@ var QuestDBParser = class extends CstParser {
2477
2525
  });
2478
2526
  this.alterTableStatement = this.RULE("alterTableStatement", () => {
2479
2527
  this.CONSUME(Table);
2480
- this.OR([
2481
- { ALT: () => this.SUBRULE(this.qualifiedName) },
2482
- { ALT: () => this.CONSUME(StringLiteral) }
2483
- ]);
2528
+ this.SUBRULE(this.tableNameOrString);
2484
2529
  this.SUBRULE(this.alterTableAction);
2485
2530
  });
2486
2531
  this.alterTableAction = this.RULE("alterTableAction", () => {
@@ -2511,10 +2556,10 @@ var QuestDBParser = class extends CstParser {
2511
2556
  {
2512
2557
  ALT: () => {
2513
2558
  this.CONSUME1(Column);
2514
- this.SUBRULE(this.identifier);
2559
+ this.SUBRULE(this.columnRef);
2515
2560
  this.MANY1(() => {
2516
2561
  this.CONSUME1(Comma);
2517
- this.SUBRULE1(this.identifier);
2562
+ this.SUBRULE1(this.columnRef);
2518
2563
  });
2519
2564
  }
2520
2565
  },
@@ -2550,7 +2595,7 @@ var QuestDBParser = class extends CstParser {
2550
2595
  ALT: () => {
2551
2596
  this.CONSUME(Rename);
2552
2597
  this.CONSUME2(Column);
2553
- this.SUBRULE2(this.identifier);
2598
+ this.SUBRULE2(this.columnRef);
2554
2599
  this.CONSUME(To);
2555
2600
  this.SUBRULE3(this.identifier);
2556
2601
  }
@@ -2560,7 +2605,7 @@ var QuestDBParser = class extends CstParser {
2560
2605
  ALT: () => {
2561
2606
  this.CONSUME1(Alter);
2562
2607
  this.CONSUME3(Column);
2563
- this.SUBRULE4(this.identifier);
2608
+ this.SUBRULE3(this.columnRef);
2564
2609
  this.OR9([
2565
2610
  {
2566
2611
  ALT: () => {
@@ -2779,7 +2824,7 @@ var QuestDBParser = class extends CstParser {
2779
2824
  () => {
2780
2825
  this.CONSUME(Materialized);
2781
2826
  this.CONSUME(View);
2782
- this.SUBRULE(this.qualifiedName);
2827
+ this.SUBRULE(this.tableName);
2783
2828
  this.SUBRULE(this.alterMaterializedViewAction);
2784
2829
  }
2785
2830
  );
@@ -2791,7 +2836,7 @@ var QuestDBParser = class extends CstParser {
2791
2836
  ALT: () => {
2792
2837
  this.CONSUME(Alter);
2793
2838
  this.CONSUME(Column);
2794
- this.SUBRULE(this.identifier);
2839
+ this.SUBRULE(this.columnRef);
2795
2840
  this.OR1([
2796
2841
  {
2797
2842
  ALT: () => {
@@ -2938,7 +2983,7 @@ var QuestDBParser = class extends CstParser {
2938
2983
  this.CONSUME(If);
2939
2984
  this.CONSUME(Exists);
2940
2985
  });
2941
- this.SUBRULE(this.qualifiedName);
2986
+ this.SUBRULE(this.tableName);
2942
2987
  }
2943
2988
  }
2944
2989
  ]);
@@ -2994,10 +3039,10 @@ var QuestDBParser = class extends CstParser {
2994
3039
  this.CONSUME(Exists);
2995
3040
  });
2996
3041
  this.OPTION1(() => this.CONSUME(Only));
2997
- this.SUBRULE(this.qualifiedName);
3042
+ this.SUBRULE(this.tableName);
2998
3043
  this.MANY(() => {
2999
3044
  this.CONSUME(Comma);
3000
- this.SUBRULE1(this.qualifiedName);
3045
+ this.SUBRULE1(this.tableName);
3001
3046
  });
3002
3047
  this.OPTION2(() => {
3003
3048
  this.CONSUME(Keep);
@@ -3011,9 +3056,9 @@ var QuestDBParser = class extends CstParser {
3011
3056
  this.renameTableStatement = this.RULE("renameTableStatement", () => {
3012
3057
  this.CONSUME(Rename);
3013
3058
  this.CONSUME(Table);
3014
- this.SUBRULE(this.stringOrQualifiedName);
3059
+ this.SUBRULE(this.tableNameOrString);
3015
3060
  this.CONSUME(To);
3016
- this.SUBRULE1(this.stringOrQualifiedName);
3061
+ this.SUBRULE1(this.tableNameOrString);
3017
3062
  });
3018
3063
  this.addUserStatement = this.RULE("addUserStatement", () => {
3019
3064
  this.CONSUME(Add);
@@ -3224,7 +3269,7 @@ var QuestDBParser = class extends CstParser {
3224
3269
  this.CONSUME(Cancel);
3225
3270
  });
3226
3271
  this.copyFrom = this.RULE("copyFrom", () => {
3227
- this.SUBRULE(this.qualifiedName);
3272
+ this.SUBRULE(this.tableName);
3228
3273
  this.CONSUME(From);
3229
3274
  this.SUBRULE(this.stringOrIdentifier);
3230
3275
  this.OPTION(() => this.SUBRULE(this.copyOptions));
@@ -3238,7 +3283,7 @@ var QuestDBParser = class extends CstParser {
3238
3283
  this.CONSUME(RParen);
3239
3284
  }
3240
3285
  },
3241
- { ALT: () => this.SUBRULE(this.qualifiedName) }
3286
+ { ALT: () => this.SUBRULE(this.tableName) }
3242
3287
  ]);
3243
3288
  this.CONSUME(To);
3244
3289
  this.SUBRULE1(this.stringOrIdentifier);
@@ -3389,7 +3434,7 @@ var QuestDBParser = class extends CstParser {
3389
3434
  {
3390
3435
  ALT: () => {
3391
3436
  this.CONSUME(Table);
3392
- this.SUBRULE(this.qualifiedName);
3437
+ this.SUBRULE(this.tableName);
3393
3438
  }
3394
3439
  },
3395
3440
  { ALT: () => this.CONSUME(Abort) }
@@ -3401,7 +3446,7 @@ var QuestDBParser = class extends CstParser {
3401
3446
  this.compileViewStatement = this.RULE("compileViewStatement", () => {
3402
3447
  this.CONSUME(Compile);
3403
3448
  this.CONSUME(View);
3404
- this.SUBRULE(this.qualifiedName);
3449
+ this.SUBRULE(this.tableName);
3405
3450
  });
3406
3451
  // ==========================================================================
3407
3452
  // GRANT / REVOKE Statements
@@ -3517,7 +3562,7 @@ var QuestDBParser = class extends CstParser {
3517
3562
  });
3518
3563
  });
3519
3564
  this.grantTableTarget = this.RULE("grantTableTarget", () => {
3520
- this.SUBRULE(this.qualifiedName);
3565
+ this.SUBRULE(this.tableName);
3521
3566
  this.OPTION(() => {
3522
3567
  this.CONSUME(LParen);
3523
3568
  this.SUBRULE(this.identifier);
@@ -3563,7 +3608,7 @@ var QuestDBParser = class extends CstParser {
3563
3608
  this.vacuumTableStatement = this.RULE("vacuumTableStatement", () => {
3564
3609
  this.CONSUME(Vacuum);
3565
3610
  this.CONSUME(Table);
3566
- this.SUBRULE(this.qualifiedName);
3611
+ this.SUBRULE(this.tableName);
3567
3612
  });
3568
3613
  this.resumeWalStatement = this.RULE("resumeWalStatement", () => {
3569
3614
  this.CONSUME(Resume);
@@ -3589,7 +3634,7 @@ var QuestDBParser = class extends CstParser {
3589
3634
  this.reindexTableStatement = this.RULE("reindexTableStatement", () => {
3590
3635
  this.CONSUME(Reindex);
3591
3636
  this.CONSUME(Table);
3592
- this.SUBRULE(this.qualifiedName);
3637
+ this.SUBRULE(this.tableName);
3593
3638
  this.OPTION(() => {
3594
3639
  this.CONSUME(Column);
3595
3640
  this.SUBRULE(this.identifier);
@@ -3620,7 +3665,7 @@ var QuestDBParser = class extends CstParser {
3620
3665
  this.CONSUME(Refresh);
3621
3666
  this.CONSUME(Materialized);
3622
3667
  this.CONSUME(View);
3623
- this.SUBRULE(this.qualifiedName);
3668
+ this.SUBRULE(this.tableName);
3624
3669
  this.OPTION(() => {
3625
3670
  this.OR([
3626
3671
  { ALT: () => this.CONSUME(Full) },
@@ -3650,7 +3695,7 @@ var QuestDBParser = class extends CstParser {
3650
3695
  this.CONSUME1(RParen);
3651
3696
  }
3652
3697
  },
3653
- { ALT: () => this.SUBRULE(this.qualifiedName) }
3698
+ { ALT: () => this.SUBRULE(this.tableName) }
3654
3699
  ]);
3655
3700
  this.OPTION(() => this.SUBRULE(this.whereClause));
3656
3701
  this.CONSUME(Pivot);
@@ -4403,6 +4448,20 @@ var QuestDBParser = class extends CstParser {
4403
4448
  this.columnRef = this.RULE("columnRef", () => {
4404
4449
  this.SUBRULE(this.qualifiedName);
4405
4450
  });
4451
+ // Wrapper for qualifiedName in table/view name positions.
4452
+ // Mirrors columnRef but for table references, so computeContentAssist
4453
+ // ruleStack includes "tableName" → autocomplete suggests existing tables.
4454
+ this.tableName = this.RULE("tableName", () => {
4455
+ this.SUBRULE(this.qualifiedName);
4456
+ });
4457
+ // Accepts StringLiteral or tableName. Used for table references that
4458
+ // can be quoted (INSERT INTO, RENAME TABLE, ALTER TABLE).
4459
+ this.tableNameOrString = this.RULE("tableNameOrString", () => {
4460
+ this.OR([
4461
+ { ALT: () => this.CONSUME(StringLiteral) },
4462
+ { ALT: () => this.SUBRULE(this.tableName) }
4463
+ ]);
4464
+ });
4406
4465
  this.qualifiedName = this.RULE("qualifiedName", () => {
4407
4466
  this.SUBRULE(this.identifier);
4408
4467
  this.MANY(() => {
@@ -4830,7 +4889,7 @@ var QuestDBVisitor = class extends BaseVisitor {
4830
4889
  parts: [ctx.StringLiteral[0].image.slice(1, -1)]
4831
4890
  };
4832
4891
  } else {
4833
- table = this.visit(ctx.qualifiedName);
4892
+ table = this.visit(ctx.tableName);
4834
4893
  }
4835
4894
  const result = {
4836
4895
  type: "tableRef",
@@ -4874,39 +4933,73 @@ var QuestDBVisitor = class extends BaseVisitor {
4874
4933
  return void 0;
4875
4934
  }
4876
4935
  joinClause(ctx) {
4936
+ if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
4937
+ if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
4938
+ if (ctx.windowJoin) return this.visit(ctx.windowJoin);
4939
+ return this.visit(ctx.standardJoin);
4940
+ }
4941
+ asofLtJoin(ctx) {
4877
4942
  const result = {
4878
4943
  type: "join",
4879
4944
  table: this.visit(ctx.tableRef)
4880
4945
  };
4881
- if (ctx.Inner) result.joinType = "inner";
4882
- else if (ctx.Left) result.joinType = "left";
4883
- else if (ctx.Right) result.joinType = "right";
4884
- else if (ctx.Full) result.joinType = "full";
4885
- else if (ctx.Cross) result.joinType = "cross";
4886
- else if (ctx.Asof) result.joinType = "asof";
4946
+ if (ctx.Asof) result.joinType = "asof";
4887
4947
  else if (ctx.Lt) result.joinType = "lt";
4888
- else if (ctx.Splice) result.joinType = "splice";
4889
- else if (ctx.Window) result.joinType = "window";
4890
- if (ctx.Outer) {
4891
- result.outer = true;
4892
- }
4893
4948
  if (ctx.expression) {
4894
4949
  result.on = this.visit(ctx.expression);
4895
4950
  }
4896
4951
  if (ctx.DurationLiteral) {
4897
4952
  result.tolerance = ctx.DurationLiteral[0].image;
4898
4953
  }
4954
+ return result;
4955
+ }
4956
+ spliceJoin(ctx) {
4957
+ const result = {
4958
+ type: "join",
4959
+ joinType: "splice",
4960
+ table: this.visit(ctx.tableRef)
4961
+ };
4962
+ if (ctx.expression) {
4963
+ result.on = this.visit(ctx.expression);
4964
+ }
4965
+ return result;
4966
+ }
4967
+ windowJoin(ctx) {
4968
+ const result = {
4969
+ type: "join",
4970
+ table: this.visit(ctx.tableRef)
4971
+ };
4972
+ if (ctx.Window) result.joinType = "window";
4973
+ if (ctx.expression) {
4974
+ result.on = this.visit(ctx.expression);
4975
+ }
4899
4976
  if (ctx.windowJoinBound && ctx.windowJoinBound.length >= 2) {
4900
4977
  result.range = {
4901
4978
  start: this.visit(ctx.windowJoinBound[0]),
4902
4979
  end: this.visit(ctx.windowJoinBound[1])
4903
4980
  };
4904
4981
  }
4905
- if (ctx.Prevailing) {
4982
+ if (ctx.Include || ctx.Exclude) {
4906
4983
  result.prevailing = ctx.Include ? "include" : "exclude";
4907
4984
  }
4908
4985
  return result;
4909
4986
  }
4987
+ standardJoin(ctx) {
4988
+ const result = {
4989
+ type: "join",
4990
+ table: this.visit(ctx.tableRef)
4991
+ };
4992
+ if (ctx.Inner) result.joinType = "inner";
4993
+ else if (ctx.Left) result.joinType = "left";
4994
+ else if (ctx.Right) result.joinType = "right";
4995
+ else if (ctx.Full) result.joinType = "full";
4996
+ else if (ctx.Cross) result.joinType = "cross";
4997
+ if (ctx.Outer) result.outer = true;
4998
+ if (ctx.expression) {
4999
+ result.on = this.visit(ctx.expression);
5000
+ }
5001
+ return result;
5002
+ }
4910
5003
  windowJoinBound(ctx) {
4911
5004
  const result = {
4912
5005
  type: "windowJoinBound",
@@ -5044,7 +5137,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5044
5137
  insertStatement(ctx) {
5045
5138
  const result = {
5046
5139
  type: "insert",
5047
- table: this.visit(ctx.stringOrQualifiedName)
5140
+ table: this.visit(ctx.tableNameOrString)
5048
5141
  };
5049
5142
  if (ctx.Atomic) {
5050
5143
  result.atomic = true;
@@ -5085,7 +5178,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5085
5178
  updateStatement(ctx) {
5086
5179
  const result = {
5087
5180
  type: "update",
5088
- table: this.visit(ctx.qualifiedName),
5181
+ table: this.visit(ctx.tableName),
5089
5182
  set: ctx.setClause.map((s) => this.visit(s))
5090
5183
  };
5091
5184
  if (ctx.identifier) {
@@ -5186,8 +5279,8 @@ var QuestDBVisitor = class extends BaseVisitor {
5186
5279
  (c) => this.visit(c)
5187
5280
  );
5188
5281
  }
5189
- if (ctx.Like && ctx.qualifiedName) {
5190
- result.like = this.visit(ctx.qualifiedName[0]);
5282
+ if (ctx.Like && ctx.tableName) {
5283
+ result.like = this.visit(ctx.tableName[0]);
5191
5284
  }
5192
5285
  if (ctx.selectStatement) {
5193
5286
  result.asSelect = this.visit(
@@ -5570,10 +5663,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5570
5663
  };
5571
5664
  }
5572
5665
  alterTableStatement(ctx) {
5573
- const table = ctx.qualifiedName ? this.visit(ctx.qualifiedName) : {
5574
- type: "qualifiedName",
5575
- parts: [ctx.StringLiteral[0].image.slice(1, -1)]
5576
- };
5666
+ const table = this.visit(ctx.tableNameOrString);
5577
5667
  return {
5578
5668
  type: "alterTable",
5579
5669
  table,
@@ -5583,7 +5673,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5583
5673
  alterMaterializedViewStatement(ctx) {
5584
5674
  return {
5585
5675
  type: "alterMaterializedView",
5586
- view: this.visit(ctx.qualifiedName),
5676
+ view: this.visit(ctx.tableName),
5587
5677
  action: this.visit(
5588
5678
  ctx.alterMaterializedViewAction
5589
5679
  )
@@ -5591,9 +5681,10 @@ var QuestDBVisitor = class extends BaseVisitor {
5591
5681
  }
5592
5682
  alterMaterializedViewAction(ctx) {
5593
5683
  if (ctx.Add && ctx.Index) {
5684
+ const colRef = this.visit(ctx.columnRef[0]);
5594
5685
  const result = {
5595
5686
  actionType: "addIndex",
5596
- column: this.extractIdentifierName(ctx.identifier[0].children)
5687
+ column: colRef.name.parts[colRef.name.parts.length - 1]
5597
5688
  };
5598
5689
  if (ctx.Capacity && ctx.NumberLiteral) {
5599
5690
  result.capacity = parseInt(ctx.NumberLiteral[0].image, 10);
@@ -5601,9 +5692,10 @@ var QuestDBVisitor = class extends BaseVisitor {
5601
5692
  return result;
5602
5693
  }
5603
5694
  if (ctx.Symbol && ctx.Capacity) {
5695
+ const colRef = this.visit(ctx.columnRef[0]);
5604
5696
  return {
5605
5697
  actionType: "symbolCapacity",
5606
- column: this.extractIdentifierName(ctx.identifier[0].children),
5698
+ column: colRef.name.parts[colRef.name.parts.length - 1],
5607
5699
  capacity: parseInt(ctx.NumberLiteral[0].image, 10)
5608
5700
  };
5609
5701
  }
@@ -5620,9 +5712,10 @@ var QuestDBVisitor = class extends BaseVisitor {
5620
5712
  };
5621
5713
  }
5622
5714
  if (ctx.Alter && ctx.Drop && ctx.Index) {
5715
+ const colRef = this.visit(ctx.columnRef[0]);
5623
5716
  return {
5624
5717
  actionType: "dropIndex",
5625
- column: this.extractIdentifierName(ctx.identifier[0].children)
5718
+ column: colRef.name.parts[colRef.name.parts.length - 1]
5626
5719
  };
5627
5720
  }
5628
5721
  if (ctx.Resume) {
@@ -5712,26 +5805,28 @@ var QuestDBVisitor = class extends BaseVisitor {
5712
5805
  }
5713
5806
  return result;
5714
5807
  }
5715
- if (ctx.Drop && ctx.identifier && !ctx.Partition && !ctx.Alter) {
5808
+ if (ctx.Drop && ctx.columnRef && !ctx.Partition && !ctx.Alter) {
5716
5809
  return {
5717
5810
  actionType: "dropColumn",
5718
- columns: ctx.identifier.map(
5719
- (id) => this.extractIdentifierName(id.children)
5720
- )
5811
+ columns: ctx.columnRef.map((c) => {
5812
+ const ref = this.visit(c);
5813
+ return ref.name.parts[ref.name.parts.length - 1];
5814
+ })
5721
5815
  };
5722
5816
  }
5723
5817
  if (ctx.Rename) {
5724
- const identifiers = ctx.identifier.map(
5725
- (id) => this.extractIdentifierName(id.children)
5726
- );
5818
+ const oldRef = this.visit(ctx.columnRef[0]);
5819
+ const oldName = oldRef.name.parts[oldRef.name.parts.length - 1];
5820
+ const newName = this.extractIdentifierName(ctx.identifier[0].children);
5727
5821
  return {
5728
5822
  actionType: "renameColumn",
5729
- oldName: identifiers[0],
5730
- newName: identifiers[1]
5823
+ oldName,
5824
+ newName
5731
5825
  };
5732
5826
  }
5733
- if (ctx.Alter && ctx.identifier) {
5734
- const column = this.extractIdentifierName(ctx.identifier[0].children);
5827
+ if (ctx.Alter && ctx.columnRef) {
5828
+ const colRef = this.visit(ctx.columnRef[0]);
5829
+ const column = colRef.name.parts[colRef.name.parts.length - 1];
5735
5830
  let alterType = "type";
5736
5831
  let newType;
5737
5832
  let capacity;
@@ -5915,7 +6010,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5915
6010
  if (ctx.All) {
5916
6011
  result.allTables = true;
5917
6012
  } else {
5918
- result.table = this.visit(ctx.qualifiedName);
6013
+ result.table = this.visit(ctx.tableName);
5919
6014
  if (ctx.If) {
5920
6015
  result.ifExists = true;
5921
6016
  }
@@ -5961,7 +6056,7 @@ var QuestDBVisitor = class extends BaseVisitor {
5961
6056
  // TRUNCATE TABLE Statement
5962
6057
  // ==========================================================================
5963
6058
  truncateTableStatement(ctx) {
5964
- const tables = ctx.qualifiedName.map(
6059
+ const tables = ctx.tableName.map(
5965
6060
  (qn) => this.visit(qn)
5966
6061
  );
5967
6062
  const result = {
@@ -5985,8 +6080,8 @@ var QuestDBVisitor = class extends BaseVisitor {
5985
6080
  renameTableStatement(ctx) {
5986
6081
  return {
5987
6082
  type: "renameTable",
5988
- from: this.visit(ctx.stringOrQualifiedName[0]),
5989
- to: this.visit(ctx.stringOrQualifiedName[1])
6083
+ from: this.visit(ctx.tableNameOrString[0]),
6084
+ to: this.visit(ctx.tableNameOrString[1])
5990
6085
  };
5991
6086
  }
5992
6087
  addUserStatement(ctx) {
@@ -6194,7 +6289,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6194
6289
  copyFrom(ctx) {
6195
6290
  const result = {
6196
6291
  type: "copyFrom",
6197
- table: this.visit(ctx.qualifiedName),
6292
+ table: this.visit(ctx.tableName),
6198
6293
  file: this.extractMaybeString(ctx.stringOrIdentifier[0])
6199
6294
  };
6200
6295
  if (ctx.copyOptions) {
@@ -6203,7 +6298,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6203
6298
  return result;
6204
6299
  }
6205
6300
  copyTo(ctx) {
6206
- const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.qualifiedName);
6301
+ const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.tableName);
6207
6302
  const result = {
6208
6303
  type: "copyTo",
6209
6304
  source,
@@ -6285,13 +6380,13 @@ var QuestDBVisitor = class extends BaseVisitor {
6285
6380
  return {
6286
6381
  type: "backup",
6287
6382
  action: "table",
6288
- table: this.visit(ctx.qualifiedName)
6383
+ table: this.visit(ctx.tableName)
6289
6384
  };
6290
6385
  }
6291
6386
  compileViewStatement(ctx) {
6292
6387
  return {
6293
6388
  type: "compileView",
6294
- view: this.visit(ctx.qualifiedName)
6389
+ view: this.visit(ctx.tableName)
6295
6390
  };
6296
6391
  }
6297
6392
  convertPartitionTarget(ctx) {
@@ -6390,7 +6485,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6390
6485
  grantTableTarget(ctx) {
6391
6486
  const result = {
6392
6487
  type: "grantTableTarget",
6393
- table: this.visit(ctx.qualifiedName)
6488
+ table: this.visit(ctx.tableName)
6394
6489
  };
6395
6490
  if (ctx.identifier && ctx.identifier.length > 0) {
6396
6491
  result.columns = ctx.identifier.map(
@@ -6420,7 +6515,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6420
6515
  vacuumTableStatement(ctx) {
6421
6516
  return {
6422
6517
  type: "vacuumTable",
6423
- table: this.visit(ctx.qualifiedName)
6518
+ table: this.visit(ctx.tableName)
6424
6519
  };
6425
6520
  }
6426
6521
  resumeWalStatement(ctx) {
@@ -6445,7 +6540,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6445
6540
  reindexTableStatement(ctx) {
6446
6541
  const result = {
6447
6542
  type: "reindexTable",
6448
- table: this.visit(ctx.qualifiedName)
6543
+ table: this.visit(ctx.tableName)
6449
6544
  };
6450
6545
  if (ctx.Column && ctx.identifier) {
6451
6546
  result.columns = ctx.identifier.map(
@@ -6465,7 +6560,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6465
6560
  refreshMaterializedViewStatement(ctx) {
6466
6561
  const result = {
6467
6562
  type: "refreshMaterializedView",
6468
- view: this.visit(ctx.qualifiedName)
6563
+ view: this.visit(ctx.tableName)
6469
6564
  };
6470
6565
  if (ctx.Full) result.mode = "full";
6471
6566
  if (ctx.Incremental) result.mode = "incremental";
@@ -6482,7 +6577,7 @@ var QuestDBVisitor = class extends BaseVisitor {
6482
6577
  // PIVOT Statement
6483
6578
  // ==========================================================================
6484
6579
  pivotStatement(ctx) {
6485
- const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.qualifiedName);
6580
+ const source = ctx.selectStatement ? this.visit(ctx.selectStatement[0]) : this.visit(ctx.tableName);
6486
6581
  const body = ctx.pivotBody ? this.visit(ctx.pivotBody) : {};
6487
6582
  const result = {
6488
6583
  type: "pivot",
@@ -7337,6 +7432,19 @@ var QuestDBVisitor = class extends BaseVisitor {
7337
7432
  name: this.visit(ctx.qualifiedName)
7338
7433
  };
7339
7434
  }
7435
+ tableName(ctx) {
7436
+ return this.visit(ctx.qualifiedName);
7437
+ }
7438
+ tableNameOrString(ctx) {
7439
+ if (ctx.StringLiteral) {
7440
+ return {
7441
+ type: "qualifiedName",
7442
+ parts: [ctx.StringLiteral[0].image.slice(1, -1)]
7443
+ };
7444
+ }
7445
+ if (ctx.tableName) return this.visit(ctx.tableName);
7446
+ return { type: "qualifiedName", parts: [] };
7447
+ }
7340
7448
  qualifiedName(ctx) {
7341
7449
  const parts = ctx.identifier.map((id) => {
7342
7450
  return this.extractIdentifierName(id.children);
@@ -9162,6 +9270,18 @@ function extractTablesFromAst(ast) {
9162
9270
  tables.push({ table: tableName });
9163
9271
  }
9164
9272
  }
9273
+ if ((n.type === "alterTable" || n.type === "alterMaterializedView") && n.table) {
9274
+ const tableName = normalizeTableName(n.table);
9275
+ if (tableName) {
9276
+ tables.push({ table: tableName });
9277
+ }
9278
+ }
9279
+ if (n.type === "alterMaterializedView" && n.view) {
9280
+ const viewName = normalizeTableName(n.view);
9281
+ if (viewName) {
9282
+ tables.push({ table: viewName });
9283
+ }
9284
+ }
9165
9285
  for (const key of Object.keys(n)) {
9166
9286
  const child = n[key];
9167
9287
  if (Array.isArray(child)) {
@@ -9313,23 +9433,34 @@ function extractTables(fullSql, tokens) {
9313
9433
  fullSql,
9314
9434
  tokens
9315
9435
  );
9436
+ const DDL_TABLE_PREFIXES = /* @__PURE__ */ new Set(["Alter", "Truncate", "Drop"]);
9316
9437
  for (let i = outerQueryStart; i < tokens.length; i++) {
9317
- if (!TABLE_PREFIX_TOKENS.has(tokens[i].tokenType.name)) continue;
9318
- const tableNameResult = readQualifiedName(i + 1);
9319
- if (!tableNameResult) continue;
9320
- let alias;
9321
- let aliasStart = tableNameResult.nextIndex;
9322
- if (tokens[aliasStart]?.tokenType.name === "As") {
9323
- aliasStart++;
9438
+ const tokenName = tokens[i].tokenType.name;
9439
+ if (TABLE_PREFIX_TOKENS.has(tokenName)) {
9440
+ const tableNameResult = readQualifiedName(i + 1);
9441
+ if (!tableNameResult) continue;
9442
+ let alias;
9443
+ let aliasStart = tableNameResult.nextIndex;
9444
+ if (tokens[aliasStart]?.tokenType.name === "As") {
9445
+ aliasStart++;
9446
+ }
9447
+ if (isIdentifierLike(tokens[aliasStart])) {
9448
+ alias = tokenToNamePart(tokens[aliasStart]);
9449
+ }
9450
+ tables.push({
9451
+ table: tableNameResult.name,
9452
+ alias
9453
+ });
9454
+ i = alias ? aliasStart : tableNameResult.nextIndex - 1;
9455
+ continue;
9324
9456
  }
9325
- if (isIdentifierLike(tokens[aliasStart])) {
9326
- alias = tokenToNamePart(tokens[aliasStart]);
9457
+ if (DDL_TABLE_PREFIXES.has(tokenName) && tokens[i + 1]?.tokenType.name === "Table") {
9458
+ const tableNameResult = readQualifiedName(i + 2);
9459
+ if (tableNameResult) {
9460
+ tables.push({ table: tableNameResult.name });
9461
+ i = tableNameResult.nextIndex - 1;
9462
+ }
9327
9463
  }
9328
- tables.push({
9329
- table: tableNameResult.name,
9330
- alias
9331
- });
9332
- i = alias ? aliasStart : tableNameResult.nextIndex - 1;
9333
9464
  }
9334
9465
  for (const name of cteNames) {
9335
9466
  tables.push({ table: name });
@@ -9365,6 +9496,13 @@ function collapseTrailingQualifiedRef(tokens) {
9365
9496
  if (start >= i) return null;
9366
9497
  return [...tokens.slice(0, start), lastToken];
9367
9498
  }
9499
+ function classifyIdentifierPath(ruleStack) {
9500
+ if (ruleStack.includes("valuesClause")) return "newName";
9501
+ if (ruleStack.includes("identifierExpression") || ruleStack.includes("columnRef") || ruleStack.includes("qualifiedStar"))
9502
+ return "column";
9503
+ if (ruleStack.includes("tableName")) return "table";
9504
+ return "newName";
9505
+ }
9368
9506
  function computeSuggestions(tokens) {
9369
9507
  const ruleName = tokens.some((t) => t.tokenType.name === "Semicolon") ? "statements" : "statement";
9370
9508
  const suggestions = parser.computeContentAssist(ruleName, tokens);
@@ -9376,10 +9514,21 @@ function computeSuggestions(tokens) {
9376
9514
  const specific = suggestions.filter(
9377
9515
  (s) => !isImplicitStatementPath(s.ruleStack, IMPLICIT_RULES)
9378
9516
  );
9379
- const result = (specific.length > 0 ? specific : suggestions).map(
9380
- (s) => s.nextTokenType
9381
- );
9382
9517
  const effectiveSuggestions = specific.length > 0 ? specific : suggestions;
9518
+ const result = effectiveSuggestions.map((s) => s.nextTokenType);
9519
+ let suggestColumns = false;
9520
+ let suggestTables = false;
9521
+ for (const s of effectiveSuggestions) {
9522
+ if (s.nextTokenType.name === "IdentifierKeyword") {
9523
+ const cls = classifyIdentifierPath(s.ruleStack);
9524
+ if (cls === "column") {
9525
+ suggestColumns = true;
9526
+ suggestTables = true;
9527
+ } else if (cls === "table") {
9528
+ suggestTables = true;
9529
+ }
9530
+ }
9531
+ }
9383
9532
  if (effectiveSuggestions.length > 0 && effectiveSuggestions.every((s) => s.ruleStack.includes("qualifiedStar"))) {
9384
9533
  const collapsed = collapseTrailingQualifiedRef(tokens);
9385
9534
  if (collapsed) {
@@ -9388,19 +9537,28 @@ function computeSuggestions(tokens) {
9388
9537
  const filteredExtra = extra.filter(
9389
9538
  (s) => !isImplicitStatementPath(s.ruleStack, IMPLICIT_RULES)
9390
9539
  );
9391
- const extraResult = (filteredExtra.length > 0 ? filteredExtra : extra).map((s) => s.nextTokenType);
9540
+ const extraEffective = filteredExtra.length > 0 ? filteredExtra : extra;
9392
9541
  const seen = new Set(result.map((t) => t.name));
9393
- for (const t of extraResult) {
9394
- if (!seen.has(t.name)) {
9395
- seen.add(t.name);
9396
- result.push(t);
9542
+ for (const s of extraEffective) {
9543
+ if (!seen.has(s.nextTokenType.name)) {
9544
+ seen.add(s.nextTokenType.name);
9545
+ result.push(s.nextTokenType);
9546
+ }
9547
+ if (s.nextTokenType.name === "IdentifierKeyword") {
9548
+ const cls = classifyIdentifierPath(s.ruleStack);
9549
+ if (cls === "column") {
9550
+ suggestColumns = true;
9551
+ suggestTables = true;
9552
+ } else if (cls === "table") {
9553
+ suggestTables = true;
9554
+ }
9397
9555
  }
9398
9556
  }
9399
9557
  } catch (e) {
9400
9558
  }
9401
9559
  }
9402
9560
  }
9403
- return result;
9561
+ return { nextTokenTypes: result, suggestColumns, suggestTables };
9404
9562
  }
9405
9563
  function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
9406
9564
  const effective = isMidWord ? tokensBefore.slice(0, -1) : tokensBefore;
@@ -9412,6 +9570,32 @@ function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
9412
9570
  const table = tableToken.tokenType.name === "QuotedIdentifier" ? tableToken.image.slice(1, -1) : tableToken.image;
9413
9571
  return { table };
9414
9572
  }
9573
+ function extractReferencedColumns(tokens, tableAndAliasSet) {
9574
+ const result = /* @__PURE__ */ new Set();
9575
+ for (let i = 0; i < tokens.length; i++) {
9576
+ const token = tokens[i];
9577
+ const name = token.tokenType.name;
9578
+ if (name !== "Identifier" && name !== "QuotedIdentifier" && !IDENTIFIER_KEYWORD_TOKENS.has(name)) {
9579
+ continue;
9580
+ }
9581
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9582
+ continue;
9583
+ }
9584
+ if (i > 0 && tokens[i - 1].tokenType.name === "Dot" && i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9585
+ continue;
9586
+ }
9587
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "LParen") {
9588
+ continue;
9589
+ }
9590
+ const image = name === "QuotedIdentifier" ? token.image.slice(1, -1) : token.image;
9591
+ const lower = image.toLowerCase();
9592
+ if (tableAndAliasSet.has(lower)) {
9593
+ continue;
9594
+ }
9595
+ result.add(lower);
9596
+ }
9597
+ return result;
9598
+ }
9415
9599
  function getContentAssist(fullSql, cursorOffset) {
9416
9600
  const fullTokens = QuestDBLexer.tokenize(fullSql).tokens;
9417
9601
  for (const token of fullTokens) {
@@ -9426,7 +9610,10 @@ function getContentAssist(fullSql, cursorOffset) {
9426
9610
  cteColumns: {},
9427
9611
  tokensBefore: [],
9428
9612
  isMidWord: true,
9429
- lexErrors: []
9613
+ lexErrors: [],
9614
+ suggestColumns: false,
9615
+ suggestTables: false,
9616
+ referencedColumns: /* @__PURE__ */ new Set()
9430
9617
  };
9431
9618
  }
9432
9619
  }
@@ -9437,8 +9624,13 @@ function getContentAssist(fullSql, cursorOffset) {
9437
9624
  const isMidWord = !WORD_BOUNDARY_CHARS.has(lastChar);
9438
9625
  const tokensForAssist = isMidWord && tokens.length > 0 ? tokens.slice(0, -1) : tokens;
9439
9626
  let nextTokenTypes = [];
9627
+ let suggestColumns = false;
9628
+ let suggestTables = false;
9440
9629
  try {
9441
- nextTokenTypes = computeSuggestions(tokensForAssist);
9630
+ const computed = computeSuggestions(tokensForAssist);
9631
+ nextTokenTypes = computed.nextTokenTypes;
9632
+ suggestColumns = computed.suggestColumns;
9633
+ suggestTables = computed.suggestTables;
9442
9634
  } catch (e) {
9443
9635
  }
9444
9636
  const { tables: tablesInScope, cteColumns } = extractTables(
@@ -9473,6 +9665,15 @@ function getContentAssist(fullSql, cursorOffset) {
9473
9665
  if (tablesInScope.length === 0 && qualifiedRef) {
9474
9666
  tablesInScope.push(qualifiedRef);
9475
9667
  }
9668
+ const tableAndAliasSet = /* @__PURE__ */ new Set();
9669
+ for (const t of tablesInScope) {
9670
+ tableAndAliasSet.add(t.table.toLowerCase());
9671
+ if (t.alias) tableAndAliasSet.add(t.alias.toLowerCase());
9672
+ }
9673
+ const referencedColumns = extractReferencedColumns(
9674
+ tokensForAssist,
9675
+ tableAndAliasSet
9676
+ );
9476
9677
  return {
9477
9678
  nextTokenTypes,
9478
9679
  tablesInScope,
@@ -9480,13 +9681,18 @@ function getContentAssist(fullSql, cursorOffset) {
9480
9681
  tokensBefore: tokens,
9481
9682
  isMidWord,
9482
9683
  lexErrors: lexResult.errors,
9483
- qualifiedTableRef: qualifiedRef?.table
9684
+ qualifiedTableRef: qualifiedRef?.table,
9685
+ suggestColumns,
9686
+ suggestTables,
9687
+ referencedColumns
9484
9688
  };
9485
9689
  }
9486
9690
  function getNextValidTokens(sql) {
9487
9691
  const lexResult = QuestDBLexer.tokenize(sql);
9488
9692
  try {
9489
- return computeSuggestions(lexResult.tokens).map((t) => t.name);
9693
+ return computeSuggestions(lexResult.tokens).nextTokenTypes.map(
9694
+ (t) => t.name
9695
+ );
9490
9696
  } catch (e) {
9491
9697
  return [];
9492
9698
  }
@@ -10058,6 +10264,35 @@ var TABLE_NAME_TOKENS = /* @__PURE__ */ new Set([
10058
10264
  "Table",
10059
10265
  "View"
10060
10266
  ]);
10267
+ function buildColumnIndex(schema) {
10268
+ const index = /* @__PURE__ */ new Map();
10269
+ for (const table of schema.tables) {
10270
+ const key = table.name.toLowerCase();
10271
+ const cols = schema.columns[key];
10272
+ if (cols) {
10273
+ index.set(key, new Set(cols.map((c) => c.name.toLowerCase())));
10274
+ }
10275
+ }
10276
+ return index;
10277
+ }
10278
+ function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
10279
+ if (referencedColumns.size === 0) return;
10280
+ const scores = /* @__PURE__ */ new Map();
10281
+ for (const [tableName, colNames] of columnIndex) {
10282
+ let count = 0;
10283
+ for (const ref of referencedColumns) {
10284
+ if (colNames.has(ref)) count++;
10285
+ }
10286
+ if (count > 0) scores.set(tableName, count);
10287
+ }
10288
+ if (scores.size === 0) return;
10289
+ for (const s of suggestions) {
10290
+ if (s.kind !== "table" /* Table */) continue;
10291
+ const score = scores.get(s.label.toLowerCase());
10292
+ if (score === void 0) continue;
10293
+ s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
10294
+ }
10295
+ }
10061
10296
  function getLastSignificantTokens(tokens) {
10062
10297
  const result = [];
10063
10298
  for (let i = tokens.length - 1; i >= 0; i--) {
@@ -10071,45 +10306,6 @@ function getLastSignificantTokens(tokens) {
10071
10306
  }
10072
10307
  return result;
10073
10308
  }
10074
- var EXPRESSION_END_TOKENS = /* @__PURE__ */ new Set([
10075
- "Identifier",
10076
- "QuotedIdentifier",
10077
- "RParen",
10078
- "NumberLiteral",
10079
- "LongLiteral",
10080
- "DecimalLiteral",
10081
- "StringLiteral"
10082
- ]);
10083
- function isExpressionEnd(tokenName) {
10084
- return EXPRESSION_END_TOKENS.has(tokenName) || IDENTIFIER_KEYWORD_TOKENS.has(tokenName);
10085
- }
10086
- function getIdentifierSuggestionScope(lastTokenName, prevTokenName, rawLastTokenName, rawPrevTokenName) {
10087
- if (rawLastTokenName && isExpressionEnd(rawLastTokenName)) {
10088
- return { includeColumns: false, includeTables: false };
10089
- }
10090
- if (rawLastTokenName === "Star") {
10091
- if (rawPrevTokenName && isExpressionEnd(rawPrevTokenName)) {
10092
- return { includeColumns: true, includeTables: true };
10093
- }
10094
- return { includeColumns: false, includeTables: false };
10095
- }
10096
- if (lastTokenName === "As") {
10097
- if (rawLastTokenName === "LParen") {
10098
- return { includeColumns: false, includeTables: true };
10099
- }
10100
- return { includeColumns: false, includeTables: false };
10101
- }
10102
- if (prevTokenName && TABLE_NAME_TOKENS.has(prevTokenName)) {
10103
- return { includeColumns: false, includeTables: true };
10104
- }
10105
- if (lastTokenName && TABLE_NAME_TOKENS.has(lastTokenName)) {
10106
- return { includeColumns: false, includeTables: true };
10107
- }
10108
- if (!lastTokenName) {
10109
- return { includeColumns: false, includeTables: true };
10110
- }
10111
- return { includeColumns: true, includeTables: true };
10112
- }
10113
10309
  function createAutocompleteProvider(schema) {
10114
10310
  const normalizedSchema = {
10115
10311
  tables: schema.tables,
@@ -10120,6 +10316,7 @@ function createAutocompleteProvider(schema) {
10120
10316
  ])
10121
10317
  )
10122
10318
  };
10319
+ const columnIndex = buildColumnIndex(normalizedSchema);
10123
10320
  return {
10124
10321
  getSuggestions(query, cursorOffset) {
10125
10322
  const {
@@ -10128,7 +10325,10 @@ function createAutocompleteProvider(schema) {
10128
10325
  cteColumns,
10129
10326
  tokensBefore,
10130
10327
  isMidWord,
10131
- qualifiedTableRef
10328
+ qualifiedTableRef,
10329
+ suggestColumns,
10330
+ suggestTables,
10331
+ referencedColumns
10132
10332
  } = getContentAssist(query, cursorOffset);
10133
10333
  const effectiveSchema = Object.keys(cteColumns).length > 0 ? {
10134
10334
  ...normalizedSchema,
@@ -10156,22 +10356,20 @@ function createAutocompleteProvider(schema) {
10156
10356
  }
10157
10357
  }
10158
10358
  if (nextTokenTypes.length > 0) {
10159
- const tokensForScope = isMidWord && tokensBefore.length > 0 ? tokensBefore.slice(0, -1) : tokensBefore;
10160
- const [lastTokenName, prevTokenName] = getLastSignificantTokens(tokensForScope);
10161
- const rawLastTokenName = tokensForScope.length > 0 ? tokensForScope[tokensForScope.length - 1]?.tokenType?.name : void 0;
10162
- const rawPrevTokenName = tokensForScope.length > 1 ? tokensForScope[tokensForScope.length - 2]?.tokenType?.name : void 0;
10163
- const scope = getIdentifierSuggestionScope(
10164
- lastTokenName,
10165
- prevTokenName,
10166
- rawLastTokenName,
10167
- rawPrevTokenName
10168
- );
10169
- return buildSuggestions(
10359
+ const suggestions = buildSuggestions(
10170
10360
  nextTokenTypes,
10171
10361
  effectiveSchema,
10172
10362
  effectiveTablesInScope,
10173
- { ...scope, isMidWord }
10363
+ {
10364
+ includeColumns: suggestColumns,
10365
+ includeTables: suggestTables,
10366
+ isMidWord
10367
+ }
10174
10368
  );
10369
+ if (suggestTables) {
10370
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10371
+ }
10372
+ return suggestions;
10175
10373
  }
10176
10374
  const fallbackTokens = isMidWord && tokensBefore.length > 0 ? tokensBefore.slice(0, -1) : tokensBefore;
10177
10375
  const [lastFallback] = getLastSignificantTokens(fallbackTokens);
@@ -10200,6 +10398,7 @@ function createAutocompleteProvider(schema) {
10200
10398
  });
10201
10399
  }
10202
10400
  }
10401
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10203
10402
  return suggestions;
10204
10403
  }
10205
10404
  return [];