@questdb/sql-parser 0.1.2 → 0.1.4

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 CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## 0.1.4 - 2026.03.17
5
+ ### Added
6
+ - Compound JOIN suggestions: suggest "LEFT JOIN", "ASOF JOIN" etc. as single completions instead of bare keywords [#13](https://github.com/questdb/sql-parser/pull/13)
7
+ - CTE grammar: extract `selectBody` rule so DECLARE/WITH are not suggested after WITH clause [#13](https://github.com/questdb/sql-parser/pull/13)
8
+
9
+ ### Fixed
10
+ - Table suggestion ranking: tables no longer interleave with columns in autocomplete [#13](https://github.com/questdb/sql-parser/pull/13)
11
+
12
+
13
+ ## 0.1.3 - 2026.03.04
14
+ ### Added
15
+ - horizon join support [#9](https://github.com/questdb/sql-parser/pull/9)
16
+
17
+
4
18
  ## 0.1.2 - 2026.02.25
5
19
  ### Fixed
6
20
  - Prioritize tables with mentioned columns in the suggestions [#6](https://github.com/questdb/sql-parser/pull/6)
@@ -349,12 +349,16 @@ var functions = [
349
349
  "approx_percentile",
350
350
  "arg_max",
351
351
  "arg_min",
352
+ "array_agg",
352
353
  "array_avg",
354
+ "array_build",
353
355
  "array_count",
354
356
  "array_cum_sum",
355
357
  "array_max",
356
358
  "array_min",
357
359
  "array_position",
360
+ "array_reverse",
361
+ "array_sort",
358
362
  "array_stddev",
359
363
  "array_stddev_pop",
360
364
  "array_stddev_samp",
@@ -319,12 +319,16 @@ var functions = [
319
319
  "approx_percentile",
320
320
  "arg_max",
321
321
  "arg_min",
322
+ "array_agg",
322
323
  "array_avg",
324
+ "array_build",
323
325
  "array_count",
324
326
  "array_cum_sum",
325
327
  "array_max",
326
328
  "array_min",
327
329
  "array_position",
330
+ "array_reverse",
331
+ "array_sort",
328
332
  "array_stddev",
329
333
  "array_stddev_pop",
330
334
  "array_stddev_samp",
package/dist/index.cjs CHANGED
@@ -529,9 +529,9 @@ var IDENTIFIER_KEYWORD_NAMES = new globalThis.Set([
529
529
  "Capacity",
530
530
  "Cancel",
531
531
  "Prevailing",
532
+ "Range",
532
533
  "Writer",
533
534
  "Materialized",
534
- "Range",
535
535
  "Snapshot",
536
536
  "Unlock",
537
537
  "Refresh",
@@ -650,7 +650,6 @@ var IDENTIFIER_KEYWORD_NAMES = new globalThis.Set([
650
650
  "Every",
651
651
  "Prev",
652
652
  "Linear",
653
- "Horizon",
654
653
  "Step"
655
654
  ]);
656
655
  for (const name of IDENTIFIER_KEYWORD_NAMES) {
@@ -755,6 +754,7 @@ var Grant = getToken("Grant");
755
754
  var Group = getToken("Group");
756
755
  var Groups = getToken("Groups");
757
756
  var Header = getToken("Header");
757
+ var Horizon = getToken("Horizon");
758
758
  var Http = getToken("Http");
759
759
  var If = getToken("If");
760
760
  var Ignore = getToken("Ignore");
@@ -855,6 +855,7 @@ var Snapshot = getToken("Snapshot");
855
855
  var Splice = getToken("Splice");
856
856
  var Squash = getToken("Squash");
857
857
  var StandardConformingStrings = getToken("StandardConformingStrings");
858
+ var Step = getToken("Step");
858
859
  var Start = getToken("Start");
859
860
  var StatisticsEnabled = getToken("StatisticsEnabled");
860
861
  var Suspend = getToken("Suspend");
@@ -1274,9 +1275,8 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1274
1275
  ALT: () => this.SUBRULE(this.updateStatement)
1275
1276
  },
1276
1277
  {
1277
- // SELECT: delegate to selectStatement (its optional declareClause/
1278
- // withClause simply won't match since WITH was already consumed)
1279
- ALT: () => this.SUBRULE(this.selectStatement)
1278
+ // SELECT after WITH: no DECLARE/WITH prefixes allowed here
1279
+ ALT: () => this.SUBRULE(this.selectBody)
1280
1280
  }
1281
1281
  ]);
1282
1282
  });
@@ -1286,6 +1286,9 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1286
1286
  this.selectStatement = this.RULE("selectStatement", () => {
1287
1287
  this.OPTION(() => this.SUBRULE(this.declareClause));
1288
1288
  this.OPTION2(() => this.SUBRULE(this.withClause));
1289
+ this.SUBRULE(this.selectBody);
1290
+ });
1291
+ this.selectBody = this.RULE("selectBody", () => {
1289
1292
  this.SUBRULE(this.simpleSelect);
1290
1293
  this.MANY(() => {
1291
1294
  this.SUBRULE(this.setOperation);
@@ -1533,6 +1536,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1533
1536
  { ALT: () => this.SUBRULE(this.asofLtJoin) },
1534
1537
  { ALT: () => this.SUBRULE(this.spliceJoin) },
1535
1538
  { ALT: () => this.SUBRULE(this.windowJoin) },
1539
+ { ALT: () => this.SUBRULE(this.horizonJoin) },
1536
1540
  { ALT: () => this.SUBRULE(this.standardJoin) }
1537
1541
  ]);
1538
1542
  });
@@ -1590,17 +1594,76 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1590
1594
  this.CONSUME1(Prevailing);
1591
1595
  });
1592
1596
  });
1593
- // Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
1597
+ // HORIZON JOIN: tableName alias [ON expr] (RANGE FROM/TO/STEP | LIST (...)) AS alias
1598
+ // Uses tableName + custom alias instead of tableRef to avoid ambiguity
1599
+ // between implicit keyword aliases and RANGE/LIST/ON keywords.
1600
+ this.horizonJoin = this.RULE("horizonJoin", () => {
1601
+ this.CONSUME(Horizon);
1602
+ this.CONSUME(Join);
1603
+ this.SUBRULE(this.tableName);
1604
+ this.OR1([
1605
+ {
1606
+ ALT: () => {
1607
+ this.CONSUME(As);
1608
+ this.SUBRULE(this.identifier);
1609
+ }
1610
+ },
1611
+ {
1612
+ // Implicit alias: only base Identifier, never keywords like RANGE/LIST
1613
+ ALT: () => this.CONSUME(Identifier)
1614
+ }
1615
+ ]);
1616
+ this.OPTION(() => {
1617
+ this.CONSUME(On);
1618
+ this.SUBRULE(this.expression);
1619
+ });
1620
+ this.OR2([
1621
+ {
1622
+ // RANGE FROM <offset> TO <offset> STEP <offset> AS <alias>
1623
+ ALT: () => {
1624
+ this.CONSUME(Range);
1625
+ this.CONSUME(From);
1626
+ this.SUBRULE(this.horizonOffset);
1627
+ this.CONSUME(To);
1628
+ this.SUBRULE1(this.horizonOffset);
1629
+ this.CONSUME(Step);
1630
+ this.SUBRULE2(this.horizonOffset);
1631
+ this.CONSUME1(As);
1632
+ this.SUBRULE1(this.identifier);
1633
+ }
1634
+ },
1635
+ {
1636
+ // LIST (<offset>, ...) AS <alias>
1637
+ ALT: () => {
1638
+ this.CONSUME(List);
1639
+ this.CONSUME(LParen);
1640
+ this.SUBRULE3(this.horizonOffset);
1641
+ this.MANY(() => {
1642
+ this.CONSUME(Comma);
1643
+ this.SUBRULE4(this.horizonOffset);
1644
+ });
1645
+ this.CONSUME(RParen);
1646
+ this.CONSUME2(As);
1647
+ this.SUBRULE2(this.identifier);
1648
+ }
1649
+ }
1650
+ ]);
1651
+ });
1652
+ // Horizon offset value: optional minus sign + DurationLiteral | NumberLiteral
1653
+ this.horizonOffset = this.RULE("horizonOffset", () => {
1654
+ this.OPTION(() => this.CONSUME(Minus));
1655
+ this.OR([
1656
+ { ALT: () => this.CONSUME(DurationLiteral) },
1657
+ { ALT: () => this.CONSUME(NumberLiteral) }
1658
+ ]);
1659
+ });
1660
+ // Standard joins: (INNER | LEFT [OUTER] | CROSS)? JOIN + ON
1594
1661
  this.standardJoin = this.RULE("standardJoin", () => {
1595
1662
  this.OPTION(() => {
1596
1663
  this.OR([
1597
1664
  {
1598
1665
  ALT: () => {
1599
- this.OR1([
1600
- { ALT: () => this.CONSUME(Left) },
1601
- { ALT: () => this.CONSUME(Right) },
1602
- { ALT: () => this.CONSUME(Full) }
1603
- ]);
1666
+ this.CONSUME(Left);
1604
1667
  this.OPTION1(() => this.CONSUME(Outer));
1605
1668
  }
1606
1669
  },
@@ -4731,8 +4794,8 @@ var QuestDBVisitor = class extends BaseVisitor {
4731
4794
  inner = this.visit(ctx.insertStatement);
4732
4795
  } else if (ctx.updateStatement) {
4733
4796
  inner = this.visit(ctx.updateStatement);
4734
- } else if (ctx.selectStatement) {
4735
- inner = this.visit(ctx.selectStatement);
4797
+ } else if (ctx.selectBody) {
4798
+ inner = this.visit(ctx.selectBody);
4736
4799
  } else {
4737
4800
  throw new Error("withStatement: expected insert, update, or select");
4738
4801
  }
@@ -4743,13 +4806,17 @@ var QuestDBVisitor = class extends BaseVisitor {
4743
4806
  // SELECT Statement
4744
4807
  // ==========================================================================
4745
4808
  selectStatement(ctx) {
4746
- const result = this.visit(ctx.simpleSelect);
4809
+ const result = this.visit(ctx.selectBody);
4747
4810
  if (ctx.declareClause) {
4748
4811
  result.declare = this.visit(ctx.declareClause);
4749
4812
  }
4750
4813
  if (ctx.withClause) {
4751
4814
  result.with = this.visit(ctx.withClause);
4752
4815
  }
4816
+ return result;
4817
+ }
4818
+ selectBody(ctx) {
4819
+ const result = this.visit(ctx.simpleSelect);
4753
4820
  if (ctx.setOperation && ctx.setOperation.length > 0) {
4754
4821
  result.setOperations = ctx.setOperation.map(
4755
4822
  (op) => this.visit(op)
@@ -4996,6 +5063,7 @@ var QuestDBVisitor = class extends BaseVisitor {
4996
5063
  if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
4997
5064
  if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
4998
5065
  if (ctx.windowJoin) return this.visit(ctx.windowJoin);
5066
+ if (ctx.horizonJoin) return this.visit(ctx.horizonJoin);
4999
5067
  return this.visit(ctx.standardJoin);
5000
5068
  }
5001
5069
  asofLtJoin(ctx) {
@@ -5044,6 +5112,49 @@ var QuestDBVisitor = class extends BaseVisitor {
5044
5112
  }
5045
5113
  return result;
5046
5114
  }
5115
+ horizonJoin(ctx) {
5116
+ const tableRef = {
5117
+ type: "tableRef",
5118
+ table: this.visit(ctx.tableName)
5119
+ };
5120
+ if (ctx.Identifier) {
5121
+ tableRef.alias = ctx.Identifier[0].image;
5122
+ } else if (ctx.identifier && ctx.identifier.length > 1) {
5123
+ tableRef.alias = this.visit(ctx.identifier[0]).parts[0];
5124
+ }
5125
+ const result = {
5126
+ type: "join",
5127
+ joinType: "horizon",
5128
+ table: tableRef
5129
+ };
5130
+ if (ctx.expression) {
5131
+ result.on = this.visit(ctx.expression);
5132
+ }
5133
+ if (ctx.Range) {
5134
+ const offsets = ctx.horizonOffset;
5135
+ result.horizonRange = {
5136
+ from: this.visit(offsets[0]),
5137
+ to: this.visit(offsets[1]),
5138
+ step: this.visit(offsets[2])
5139
+ };
5140
+ } else if (ctx.List) {
5141
+ result.horizonList = ctx.horizonOffset.map(
5142
+ (o) => this.visit(o)
5143
+ );
5144
+ }
5145
+ if (ctx.identifier) {
5146
+ const lastId = ctx.identifier[ctx.identifier.length - 1];
5147
+ result.horizonAlias = this.visit(lastId).parts[0];
5148
+ }
5149
+ return result;
5150
+ }
5151
+ horizonOffset(ctx) {
5152
+ const sign = ctx.Minus ? "-" : "";
5153
+ if (ctx.DurationLiteral) {
5154
+ return sign + ctx.DurationLiteral[0].image;
5155
+ }
5156
+ return sign + ctx.NumberLiteral[0].image;
5157
+ }
5047
5158
  standardJoin(ctx) {
5048
5159
  const result = {
5049
5160
  type: "join",
@@ -5051,8 +5162,6 @@ var QuestDBVisitor = class extends BaseVisitor {
5051
5162
  };
5052
5163
  if (ctx.Inner) result.joinType = "inner";
5053
5164
  else if (ctx.Left) result.joinType = "left";
5054
- else if (ctx.Right) result.joinType = "right";
5055
- else if (ctx.Full) result.joinType = "full";
5056
5165
  else if (ctx.Cross) result.joinType = "cross";
5057
5166
  if (ctx.Outer) result.outer = true;
5058
5167
  if (ctx.expression) {
@@ -7919,6 +8028,21 @@ function joinToSql(join) {
7919
8028
  join.prevailing === "include" ? "INCLUDE PREVAILING" : "EXCLUDE PREVAILING"
7920
8029
  );
7921
8030
  }
8031
+ if (join.horizonRange) {
8032
+ parts.push("RANGE FROM");
8033
+ parts.push(join.horizonRange.from);
8034
+ parts.push("TO");
8035
+ parts.push(join.horizonRange.to);
8036
+ parts.push("STEP");
8037
+ parts.push(join.horizonRange.step);
8038
+ }
8039
+ if (join.horizonList) {
8040
+ parts.push("LIST (" + join.horizonList.join(", ") + ")");
8041
+ }
8042
+ if (join.horizonAlias) {
8043
+ parts.push("AS");
8044
+ parts.push(escapeIdentifier(join.horizonAlias));
8045
+ }
7922
8046
  return parts.join(" ");
7923
8047
  }
7924
8048
  function windowJoinBoundToSql(bound) {
@@ -9792,12 +9916,16 @@ var functions = [
9792
9916
  "approx_percentile",
9793
9917
  "arg_max",
9794
9918
  "arg_min",
9919
+ "array_agg",
9795
9920
  "array_avg",
9921
+ "array_build",
9796
9922
  "array_count",
9797
9923
  "array_cum_sum",
9798
9924
  "array_max",
9799
9925
  "array_min",
9800
9926
  "array_position",
9927
+ "array_reverse",
9928
+ "array_sort",
9801
9929
  "array_stddev",
9802
9930
  "array_stddev_pop",
9803
9931
  "array_stddev_samp",
@@ -10171,6 +10299,17 @@ function getAllColumns(schema) {
10171
10299
  }
10172
10300
  return columns;
10173
10301
  }
10302
+ var JOIN_COMPOUND_MAP = /* @__PURE__ */ new Map([
10303
+ ["Left", "LEFT JOIN"],
10304
+ ["Inner", "INNER JOIN"],
10305
+ ["Cross", "CROSS JOIN"],
10306
+ ["Asof", "ASOF JOIN"],
10307
+ ["Lt", "LT JOIN"],
10308
+ ["Splice", "SPLICE JOIN"],
10309
+ ["Window", "WINDOW JOIN"],
10310
+ ["Horizon", "HORIZON JOIN"],
10311
+ ["Outer", "OUTER JOIN"]
10312
+ ]);
10174
10313
  function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10175
10314
  const suggestions = [];
10176
10315
  const seenKeywords = /* @__PURE__ */ new Set();
@@ -10178,6 +10317,7 @@ function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10178
10317
  const includeColumns = options?.includeColumns ?? true;
10179
10318
  const includeTables = options?.includeTables ?? true;
10180
10319
  const isMidWord = options?.isMidWord ?? false;
10320
+ const isJoinContext = tokenTypes.some((t) => t.name === "Join");
10181
10321
  for (const tokenType of tokenTypes) {
10182
10322
  const name = tokenType.name;
10183
10323
  if (SKIP_TOKENS.has(name)) {
@@ -10190,6 +10330,19 @@ function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10190
10330
  if (name === "Identifier" || name === "QuotedIdentifier") {
10191
10331
  continue;
10192
10332
  }
10333
+ if (isJoinContext && JOIN_COMPOUND_MAP.has(name)) {
10334
+ const compound = JOIN_COMPOUND_MAP.get(name);
10335
+ if (seenKeywords.has(compound)) continue;
10336
+ seenKeywords.add(compound);
10337
+ suggestions.push({
10338
+ label: compound,
10339
+ kind: "keyword" /* Keyword */,
10340
+ insertText: compound,
10341
+ filterText: compound.toLowerCase(),
10342
+ priority: 2 /* Medium */
10343
+ });
10344
+ continue;
10345
+ }
10193
10346
  const keyword = tokenNameToKeyword(name);
10194
10347
  if (seenKeywords.has(keyword)) {
10195
10348
  continue;
@@ -10350,7 +10503,7 @@ function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
10350
10503
  if (s.kind !== "table" /* Table */) continue;
10351
10504
  const score = scores.get(s.label.toLowerCase());
10352
10505
  if (score === void 0) continue;
10353
- s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
10506
+ s.priority = score === referencedColumns.size ? 2 /* Medium */ : 3 /* MediumLow */;
10354
10507
  }
10355
10508
  }
10356
10509
  function getLastSignificantTokens(tokens) {
package/dist/index.js CHANGED
@@ -469,9 +469,9 @@ var IDENTIFIER_KEYWORD_NAMES = new globalThis.Set([
469
469
  "Capacity",
470
470
  "Cancel",
471
471
  "Prevailing",
472
+ "Range",
472
473
  "Writer",
473
474
  "Materialized",
474
- "Range",
475
475
  "Snapshot",
476
476
  "Unlock",
477
477
  "Refresh",
@@ -590,7 +590,6 @@ var IDENTIFIER_KEYWORD_NAMES = new globalThis.Set([
590
590
  "Every",
591
591
  "Prev",
592
592
  "Linear",
593
- "Horizon",
594
593
  "Step"
595
594
  ]);
596
595
  for (const name of IDENTIFIER_KEYWORD_NAMES) {
@@ -695,6 +694,7 @@ var Grant = getToken("Grant");
695
694
  var Group = getToken("Group");
696
695
  var Groups = getToken("Groups");
697
696
  var Header = getToken("Header");
697
+ var Horizon = getToken("Horizon");
698
698
  var Http = getToken("Http");
699
699
  var If = getToken("If");
700
700
  var Ignore = getToken("Ignore");
@@ -795,6 +795,7 @@ var Snapshot = getToken("Snapshot");
795
795
  var Splice = getToken("Splice");
796
796
  var Squash = getToken("Squash");
797
797
  var StandardConformingStrings = getToken("StandardConformingStrings");
798
+ var Step = getToken("Step");
798
799
  var Start = getToken("Start");
799
800
  var StatisticsEnabled = getToken("StatisticsEnabled");
800
801
  var Suspend = getToken("Suspend");
@@ -1214,9 +1215,8 @@ var QuestDBParser = class extends CstParser {
1214
1215
  ALT: () => this.SUBRULE(this.updateStatement)
1215
1216
  },
1216
1217
  {
1217
- // SELECT: delegate to selectStatement (its optional declareClause/
1218
- // withClause simply won't match since WITH was already consumed)
1219
- ALT: () => this.SUBRULE(this.selectStatement)
1218
+ // SELECT after WITH: no DECLARE/WITH prefixes allowed here
1219
+ ALT: () => this.SUBRULE(this.selectBody)
1220
1220
  }
1221
1221
  ]);
1222
1222
  });
@@ -1226,6 +1226,9 @@ var QuestDBParser = class extends CstParser {
1226
1226
  this.selectStatement = this.RULE("selectStatement", () => {
1227
1227
  this.OPTION(() => this.SUBRULE(this.declareClause));
1228
1228
  this.OPTION2(() => this.SUBRULE(this.withClause));
1229
+ this.SUBRULE(this.selectBody);
1230
+ });
1231
+ this.selectBody = this.RULE("selectBody", () => {
1229
1232
  this.SUBRULE(this.simpleSelect);
1230
1233
  this.MANY(() => {
1231
1234
  this.SUBRULE(this.setOperation);
@@ -1473,6 +1476,7 @@ var QuestDBParser = class extends CstParser {
1473
1476
  { ALT: () => this.SUBRULE(this.asofLtJoin) },
1474
1477
  { ALT: () => this.SUBRULE(this.spliceJoin) },
1475
1478
  { ALT: () => this.SUBRULE(this.windowJoin) },
1479
+ { ALT: () => this.SUBRULE(this.horizonJoin) },
1476
1480
  { ALT: () => this.SUBRULE(this.standardJoin) }
1477
1481
  ]);
1478
1482
  });
@@ -1530,17 +1534,76 @@ var QuestDBParser = class extends CstParser {
1530
1534
  this.CONSUME1(Prevailing);
1531
1535
  });
1532
1536
  });
1533
- // Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
1537
+ // HORIZON JOIN: tableName alias [ON expr] (RANGE FROM/TO/STEP | LIST (...)) AS alias
1538
+ // Uses tableName + custom alias instead of tableRef to avoid ambiguity
1539
+ // between implicit keyword aliases and RANGE/LIST/ON keywords.
1540
+ this.horizonJoin = this.RULE("horizonJoin", () => {
1541
+ this.CONSUME(Horizon);
1542
+ this.CONSUME(Join);
1543
+ this.SUBRULE(this.tableName);
1544
+ this.OR1([
1545
+ {
1546
+ ALT: () => {
1547
+ this.CONSUME(As);
1548
+ this.SUBRULE(this.identifier);
1549
+ }
1550
+ },
1551
+ {
1552
+ // Implicit alias: only base Identifier, never keywords like RANGE/LIST
1553
+ ALT: () => this.CONSUME(Identifier)
1554
+ }
1555
+ ]);
1556
+ this.OPTION(() => {
1557
+ this.CONSUME(On);
1558
+ this.SUBRULE(this.expression);
1559
+ });
1560
+ this.OR2([
1561
+ {
1562
+ // RANGE FROM <offset> TO <offset> STEP <offset> AS <alias>
1563
+ ALT: () => {
1564
+ this.CONSUME(Range);
1565
+ this.CONSUME(From);
1566
+ this.SUBRULE(this.horizonOffset);
1567
+ this.CONSUME(To);
1568
+ this.SUBRULE1(this.horizonOffset);
1569
+ this.CONSUME(Step);
1570
+ this.SUBRULE2(this.horizonOffset);
1571
+ this.CONSUME1(As);
1572
+ this.SUBRULE1(this.identifier);
1573
+ }
1574
+ },
1575
+ {
1576
+ // LIST (<offset>, ...) AS <alias>
1577
+ ALT: () => {
1578
+ this.CONSUME(List);
1579
+ this.CONSUME(LParen);
1580
+ this.SUBRULE3(this.horizonOffset);
1581
+ this.MANY(() => {
1582
+ this.CONSUME(Comma);
1583
+ this.SUBRULE4(this.horizonOffset);
1584
+ });
1585
+ this.CONSUME(RParen);
1586
+ this.CONSUME2(As);
1587
+ this.SUBRULE2(this.identifier);
1588
+ }
1589
+ }
1590
+ ]);
1591
+ });
1592
+ // Horizon offset value: optional minus sign + DurationLiteral | NumberLiteral
1593
+ this.horizonOffset = this.RULE("horizonOffset", () => {
1594
+ this.OPTION(() => this.CONSUME(Minus));
1595
+ this.OR([
1596
+ { ALT: () => this.CONSUME(DurationLiteral) },
1597
+ { ALT: () => this.CONSUME(NumberLiteral) }
1598
+ ]);
1599
+ });
1600
+ // Standard joins: (INNER | LEFT [OUTER] | CROSS)? JOIN + ON
1534
1601
  this.standardJoin = this.RULE("standardJoin", () => {
1535
1602
  this.OPTION(() => {
1536
1603
  this.OR([
1537
1604
  {
1538
1605
  ALT: () => {
1539
- this.OR1([
1540
- { ALT: () => this.CONSUME(Left) },
1541
- { ALT: () => this.CONSUME(Right) },
1542
- { ALT: () => this.CONSUME(Full) }
1543
- ]);
1606
+ this.CONSUME(Left);
1544
1607
  this.OPTION1(() => this.CONSUME(Outer));
1545
1608
  }
1546
1609
  },
@@ -4671,8 +4734,8 @@ var QuestDBVisitor = class extends BaseVisitor {
4671
4734
  inner = this.visit(ctx.insertStatement);
4672
4735
  } else if (ctx.updateStatement) {
4673
4736
  inner = this.visit(ctx.updateStatement);
4674
- } else if (ctx.selectStatement) {
4675
- inner = this.visit(ctx.selectStatement);
4737
+ } else if (ctx.selectBody) {
4738
+ inner = this.visit(ctx.selectBody);
4676
4739
  } else {
4677
4740
  throw new Error("withStatement: expected insert, update, or select");
4678
4741
  }
@@ -4683,13 +4746,17 @@ var QuestDBVisitor = class extends BaseVisitor {
4683
4746
  // SELECT Statement
4684
4747
  // ==========================================================================
4685
4748
  selectStatement(ctx) {
4686
- const result = this.visit(ctx.simpleSelect);
4749
+ const result = this.visit(ctx.selectBody);
4687
4750
  if (ctx.declareClause) {
4688
4751
  result.declare = this.visit(ctx.declareClause);
4689
4752
  }
4690
4753
  if (ctx.withClause) {
4691
4754
  result.with = this.visit(ctx.withClause);
4692
4755
  }
4756
+ return result;
4757
+ }
4758
+ selectBody(ctx) {
4759
+ const result = this.visit(ctx.simpleSelect);
4693
4760
  if (ctx.setOperation && ctx.setOperation.length > 0) {
4694
4761
  result.setOperations = ctx.setOperation.map(
4695
4762
  (op) => this.visit(op)
@@ -4936,6 +5003,7 @@ var QuestDBVisitor = class extends BaseVisitor {
4936
5003
  if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
4937
5004
  if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
4938
5005
  if (ctx.windowJoin) return this.visit(ctx.windowJoin);
5006
+ if (ctx.horizonJoin) return this.visit(ctx.horizonJoin);
4939
5007
  return this.visit(ctx.standardJoin);
4940
5008
  }
4941
5009
  asofLtJoin(ctx) {
@@ -4984,6 +5052,49 @@ var QuestDBVisitor = class extends BaseVisitor {
4984
5052
  }
4985
5053
  return result;
4986
5054
  }
5055
+ horizonJoin(ctx) {
5056
+ const tableRef = {
5057
+ type: "tableRef",
5058
+ table: this.visit(ctx.tableName)
5059
+ };
5060
+ if (ctx.Identifier) {
5061
+ tableRef.alias = ctx.Identifier[0].image;
5062
+ } else if (ctx.identifier && ctx.identifier.length > 1) {
5063
+ tableRef.alias = this.visit(ctx.identifier[0]).parts[0];
5064
+ }
5065
+ const result = {
5066
+ type: "join",
5067
+ joinType: "horizon",
5068
+ table: tableRef
5069
+ };
5070
+ if (ctx.expression) {
5071
+ result.on = this.visit(ctx.expression);
5072
+ }
5073
+ if (ctx.Range) {
5074
+ const offsets = ctx.horizonOffset;
5075
+ result.horizonRange = {
5076
+ from: this.visit(offsets[0]),
5077
+ to: this.visit(offsets[1]),
5078
+ step: this.visit(offsets[2])
5079
+ };
5080
+ } else if (ctx.List) {
5081
+ result.horizonList = ctx.horizonOffset.map(
5082
+ (o) => this.visit(o)
5083
+ );
5084
+ }
5085
+ if (ctx.identifier) {
5086
+ const lastId = ctx.identifier[ctx.identifier.length - 1];
5087
+ result.horizonAlias = this.visit(lastId).parts[0];
5088
+ }
5089
+ return result;
5090
+ }
5091
+ horizonOffset(ctx) {
5092
+ const sign = ctx.Minus ? "-" : "";
5093
+ if (ctx.DurationLiteral) {
5094
+ return sign + ctx.DurationLiteral[0].image;
5095
+ }
5096
+ return sign + ctx.NumberLiteral[0].image;
5097
+ }
4987
5098
  standardJoin(ctx) {
4988
5099
  const result = {
4989
5100
  type: "join",
@@ -4991,8 +5102,6 @@ var QuestDBVisitor = class extends BaseVisitor {
4991
5102
  };
4992
5103
  if (ctx.Inner) result.joinType = "inner";
4993
5104
  else if (ctx.Left) result.joinType = "left";
4994
- else if (ctx.Right) result.joinType = "right";
4995
- else if (ctx.Full) result.joinType = "full";
4996
5105
  else if (ctx.Cross) result.joinType = "cross";
4997
5106
  if (ctx.Outer) result.outer = true;
4998
5107
  if (ctx.expression) {
@@ -7859,6 +7968,21 @@ function joinToSql(join) {
7859
7968
  join.prevailing === "include" ? "INCLUDE PREVAILING" : "EXCLUDE PREVAILING"
7860
7969
  );
7861
7970
  }
7971
+ if (join.horizonRange) {
7972
+ parts.push("RANGE FROM");
7973
+ parts.push(join.horizonRange.from);
7974
+ parts.push("TO");
7975
+ parts.push(join.horizonRange.to);
7976
+ parts.push("STEP");
7977
+ parts.push(join.horizonRange.step);
7978
+ }
7979
+ if (join.horizonList) {
7980
+ parts.push("LIST (" + join.horizonList.join(", ") + ")");
7981
+ }
7982
+ if (join.horizonAlias) {
7983
+ parts.push("AS");
7984
+ parts.push(escapeIdentifier(join.horizonAlias));
7985
+ }
7862
7986
  return parts.join(" ");
7863
7987
  }
7864
7988
  function windowJoinBoundToSql(bound) {
@@ -9732,12 +9856,16 @@ var functions = [
9732
9856
  "approx_percentile",
9733
9857
  "arg_max",
9734
9858
  "arg_min",
9859
+ "array_agg",
9735
9860
  "array_avg",
9861
+ "array_build",
9736
9862
  "array_count",
9737
9863
  "array_cum_sum",
9738
9864
  "array_max",
9739
9865
  "array_min",
9740
9866
  "array_position",
9867
+ "array_reverse",
9868
+ "array_sort",
9741
9869
  "array_stddev",
9742
9870
  "array_stddev_pop",
9743
9871
  "array_stddev_samp",
@@ -10111,6 +10239,17 @@ function getAllColumns(schema) {
10111
10239
  }
10112
10240
  return columns;
10113
10241
  }
10242
+ var JOIN_COMPOUND_MAP = /* @__PURE__ */ new Map([
10243
+ ["Left", "LEFT JOIN"],
10244
+ ["Inner", "INNER JOIN"],
10245
+ ["Cross", "CROSS JOIN"],
10246
+ ["Asof", "ASOF JOIN"],
10247
+ ["Lt", "LT JOIN"],
10248
+ ["Splice", "SPLICE JOIN"],
10249
+ ["Window", "WINDOW JOIN"],
10250
+ ["Horizon", "HORIZON JOIN"],
10251
+ ["Outer", "OUTER JOIN"]
10252
+ ]);
10114
10253
  function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10115
10254
  const suggestions = [];
10116
10255
  const seenKeywords = /* @__PURE__ */ new Set();
@@ -10118,6 +10257,7 @@ function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10118
10257
  const includeColumns = options?.includeColumns ?? true;
10119
10258
  const includeTables = options?.includeTables ?? true;
10120
10259
  const isMidWord = options?.isMidWord ?? false;
10260
+ const isJoinContext = tokenTypes.some((t) => t.name === "Join");
10121
10261
  for (const tokenType of tokenTypes) {
10122
10262
  const name = tokenType.name;
10123
10263
  if (SKIP_TOKENS.has(name)) {
@@ -10130,6 +10270,19 @@ function buildSuggestions(tokenTypes, schema, tablesInScope, options) {
10130
10270
  if (name === "Identifier" || name === "QuotedIdentifier") {
10131
10271
  continue;
10132
10272
  }
10273
+ if (isJoinContext && JOIN_COMPOUND_MAP.has(name)) {
10274
+ const compound = JOIN_COMPOUND_MAP.get(name);
10275
+ if (seenKeywords.has(compound)) continue;
10276
+ seenKeywords.add(compound);
10277
+ suggestions.push({
10278
+ label: compound,
10279
+ kind: "keyword" /* Keyword */,
10280
+ insertText: compound,
10281
+ filterText: compound.toLowerCase(),
10282
+ priority: 2 /* Medium */
10283
+ });
10284
+ continue;
10285
+ }
10133
10286
  const keyword = tokenNameToKeyword(name);
10134
10287
  if (seenKeywords.has(keyword)) {
10135
10288
  continue;
@@ -10290,7 +10443,7 @@ function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
10290
10443
  if (s.kind !== "table" /* Table */) continue;
10291
10444
  const score = scores.get(s.label.toLowerCase());
10292
10445
  if (score === void 0) continue;
10293
- s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
10446
+ s.priority = score === referencedColumns.size ? 2 /* Medium */ : 3 /* MediumLow */;
10294
10447
  }
10295
10448
  }
10296
10449
  function getLastSignificantTokens(tokens) {
@@ -603,7 +603,7 @@ export interface TableRef extends AstNode {
603
603
  }
604
604
  export interface JoinClause extends AstNode {
605
605
  type: "join";
606
- joinType?: "inner" | "left" | "right" | "full" | "cross" | "asof" | "lt" | "splice" | "window";
606
+ joinType?: "inner" | "left" | "cross" | "asof" | "lt" | "splice" | "window" | "horizon";
607
607
  outer?: boolean;
608
608
  table: TableRef;
609
609
  on?: Expression;
@@ -616,6 +616,16 @@ export interface JoinClause extends AstNode {
616
616
  };
617
617
  /** INCLUDE/EXCLUDE PREVAILING clause for WINDOW JOIN */
618
618
  prevailing?: "include" | "exclude";
619
+ /** RANGE FROM/TO/STEP for HORIZON JOIN */
620
+ horizonRange?: {
621
+ from: string;
622
+ to: string;
623
+ step: string;
624
+ };
625
+ /** LIST offsets for HORIZON JOIN */
626
+ horizonList?: string[];
627
+ /** Alias for the horizon pseudo-table */
628
+ horizonAlias?: string;
619
629
  }
620
630
  export interface WindowJoinBound extends AstNode {
621
631
  type: "windowJoinBound";
@@ -1,7 +1,7 @@
1
1
  import { Lexer, TokenType } from "chevrotain";
2
- import { IdentifierKeyword, Abort, Account, Accounts, Add, Alias, Align, All, Alter, And, Any, As, Asc, Asof, Assume, Attach, Atomic, Backup, Base, Batch, Between, Binary, Boolean, By, Bypass, Byte, Cache, Calendar, Cancel, Capacity, Cascade, Case, Cast, Char, Checkpoint, Column, Columns, Compile, Complete, CompressionCodec, CompressionLevel, CommitLag, Convert, Copy, Create, Cross, Cumulative, Current, Database, DataPageSize, Datestyle, Date, Day, Days, Decimal, Declare, Dedup, Default, DefaultTransactionReadOnly, Deferred, Delay, Delete, Delimiter, Desc, Detach, Details, Disable, Distinct, Double, Drop, Else, Enable, End, Error, Every, Except, Exclude, Exclusive, Exists, Exit, Explain, External, False, Fill, First, Float, Following, For, Foreign, Format, From, Full, Geohash, Grant, Group, Groups, Header, Hour, Hours, Http, If, Ignore, Ilike, Immediate, In, Include, Index, Inner, Insert, Incremental, Int, Integer, Intersect, Interval, Into, Ipv4, Is, Isolation, Jwk, Join, Keep, Key, Keys, Latest, Left, Length, Level, Like, Limit, Linear, List, Lock, Long, Long128, Long256, Lt, Manual, Maps, Materialized, MaxIdentifierLength, MaxUncommittedRows, Microsecond, Microseconds, Millennium, Millisecond, Milliseconds, Minute, Minutes, Month, Months, NaN, Nanosecond, Nanoseconds, No, Nocache, None, Not, Null, Nulls, O3MaxLag, Observation, Offset, On, Only, Option, Or, Order, Others, Outer, Over, Overridable, Owned, Param, Parameters, Parquet, ParquetVersion, PartitionBy, Partition, Partitions, Password, Period, Permissions, Pivot, Prepare, Preceding, Prev, Prevailing, Primary, Public, Query, Range, References, Refresh, Release, Reindex, Remove, Rename, Repair, Replace, Rest, Respect, Resume, Revoke, Right, Row, RowGroupSize, Rows, Sample, SearchPath, Second, Seconds, Select, ServerVersion, ServerVersionNum, Service, Set, Short, Show, Skip, SkipColumn, SkipRow, Snapshot, Splice, Squash, StandardConformingStrings, Start, StatisticsEnabled, String, Suspend, Symbol, System, Table, Tables, Then, Time, Timestamp, TimestampNs, To, Token, Tolerance, Transaction, TransactionIsolation, Transient, True, Truncate, Ttl, Txn, Type, Unbounded, Union, Unlock, Unpivot, Update, Upsert, User, Users, Uuid, Vacuum, Values, Varchar, Verification, View, Volume, Wal, Week, Weeks, When, Where, Window, With, Within, Writer, Year, Years, Zone, RawArrayEncoding, Uncompressed, Snappy, Gzip, Lz4, Zstd, Lz4Raw, Brotli, Lzo } from "./tokens";
2
+ import { IdentifierKeyword, Abort, Account, Accounts, Add, Alias, Align, All, Alter, And, Any, As, Asc, Asof, Assume, Attach, Atomic, Backup, Base, Batch, Between, Binary, Boolean, By, Bypass, Byte, Cache, Calendar, Cancel, Capacity, Cascade, Case, Cast, Char, Checkpoint, Column, Columns, Compile, Complete, CompressionCodec, CompressionLevel, CommitLag, Convert, Copy, Create, Cross, Cumulative, Current, Database, DataPageSize, Datestyle, Date, Day, Days, Decimal, Declare, Dedup, Default, DefaultTransactionReadOnly, Deferred, Delay, Delete, Delimiter, Desc, Detach, Details, Disable, Distinct, Double, Drop, Else, Enable, End, Error, Every, Except, Exclude, Exclusive, Exists, Exit, Explain, External, False, Fill, First, Float, Following, For, Foreign, Format, From, Full, Geohash, Grant, Group, Groups, Header, Horizon, Hour, Hours, Http, If, Ignore, Ilike, Immediate, In, Include, Index, Inner, Insert, Incremental, Int, Integer, Intersect, Interval, Into, Ipv4, Is, Isolation, Jwk, Join, Keep, Key, Keys, Latest, Left, Length, Level, Like, Limit, Linear, List, Lock, Long, Long128, Long256, Lt, Manual, Maps, Materialized, MaxIdentifierLength, MaxUncommittedRows, Microsecond, Microseconds, Millennium, Millisecond, Milliseconds, Minute, Minutes, Month, Months, NaN, Nanosecond, Nanoseconds, No, Nocache, None, Not, Null, Nulls, O3MaxLag, Observation, Offset, On, Only, Option, Or, Order, Others, Outer, Over, Overridable, Owned, Param, Parameters, Parquet, ParquetVersion, PartitionBy, Partition, Partitions, Password, Period, Permissions, Pivot, Prepare, Preceding, Prev, Prevailing, Primary, Public, Query, Range, References, Refresh, Release, Reindex, Remove, Rename, Repair, Replace, Rest, Respect, Resume, Revoke, Right, Row, RowGroupSize, Rows, Sample, SearchPath, Second, Seconds, Select, ServerVersion, ServerVersionNum, Service, Set, Short, Show, Skip, SkipColumn, SkipRow, Snapshot, Splice, Squash, StandardConformingStrings, Step, Start, StatisticsEnabled, String, Suspend, Symbol, System, Table, Tables, Then, Time, Timestamp, TimestampNs, To, Token, Tolerance, Transaction, TransactionIsolation, Transient, True, Truncate, Ttl, Txn, Type, Unbounded, Union, Unlock, Unpivot, Update, Upsert, User, Users, Uuid, Vacuum, Values, Varchar, Verification, View, Volume, Wal, Week, Weeks, When, Where, Window, With, Within, Writer, Year, Years, Zone, RawArrayEncoding, Uncompressed, Snappy, Gzip, Lz4, Zstd, Lz4Raw, Brotli, Lzo } from "./tokens";
3
3
  export { IdentifierKeyword };
4
- export { Abort, Account, Accounts, Add, Alias, Align, All, Alter, And, Any, As, Asc, Asof, Assume, Attach, Atomic, Backup, Base, Batch, Between, Binary, Boolean, By, Bypass, Byte, Cache, Calendar, Cancel, Capacity, Cascade, Case, Cast, Char, Checkpoint, Column, Columns, Compile, Complete, CompressionCodec, CompressionLevel, CommitLag, Convert, Copy, Create, Cross, Cumulative, Current, Database, DataPageSize, Datestyle, Date, Day, Days, Decimal, Declare, Dedup, Default, DefaultTransactionReadOnly, Deferred, Delay, Delete, Delimiter, Desc, Detach, Details, Disable, Distinct, Double, Drop, Else, Enable, End, Error, Every, Except, Exclude, Exclusive, Exists, Exit, Explain, External, False, Fill, First, Float, Following, For, Foreign, Format, From, Full, Geohash, Grant, Group, Groups, Header, Hour, Hours, Http, If, Ignore, Ilike, Immediate, In, Include, Index, Inner, Insert, Incremental, Int, Integer, Intersect, Interval, Into, Ipv4, Is, Isolation, Jwk, Join, Keep, Key, Keys, Latest, Left, Length, Level, Like, Limit, Linear, List, Lock, Long, Long128, Long256, Lt, Manual, Maps, Materialized, MaxIdentifierLength, MaxUncommittedRows, Microsecond, Microseconds, Millennium, Millisecond, Milliseconds, Minute, Minutes, Month, Months, NaN, Nanosecond, Nanoseconds, No, Nocache, None, Not, Null, Nulls, O3MaxLag, Observation, Offset, On, Only, Option, Or, Order, Others, Outer, Over, Overridable, Owned, Param, Parameters, Parquet, ParquetVersion, PartitionBy, Partition, Partitions, Password, Period, Permissions, Pivot, Prepare, Preceding, Prev, Prevailing, Primary, Public, Query, Range, References, Refresh, Release, Reindex, Remove, Rename, Repair, Replace, Rest, Respect, Resume, Revoke, Right, Row, RowGroupSize, Rows, Sample, SearchPath, Second, Seconds, Select, ServerVersion, ServerVersionNum, Service, Set, Short, Show, Skip, SkipColumn, SkipRow, Snapshot, Splice, Squash, StandardConformingStrings, Start, StatisticsEnabled, String, Suspend, Symbol, System, Table, Tables, Then, Time, Timestamp, TimestampNs, To, Token, Tolerance, Transaction, TransactionIsolation, Transient, True, Truncate, Ttl, Txn, Type, Unbounded, Union, Unlock, Unpivot, Update, Upsert, User, Users, Uuid, Vacuum, Values, Varchar, Verification, View, Volume, Wal, Week, Weeks, When, Where, Window, With, Within, Writer, Year, Years, Zone, RawArrayEncoding, Uncompressed, Snappy, Gzip, Lz4, Zstd, Lz4Raw, Brotli, Lzo, };
4
+ export { Abort, Account, Accounts, Add, Alias, Align, All, Alter, And, Any, As, Asc, Asof, Assume, Attach, Atomic, Backup, Base, Batch, Between, Binary, Boolean, By, Bypass, Byte, Cache, Calendar, Cancel, Capacity, Cascade, Case, Cast, Char, Checkpoint, Column, Columns, Compile, Complete, CompressionCodec, CompressionLevel, CommitLag, Convert, Copy, Create, Cross, Cumulative, Current, Database, DataPageSize, Datestyle, Date, Day, Days, Decimal, Declare, Dedup, Default, DefaultTransactionReadOnly, Deferred, Delay, Delete, Delimiter, Desc, Detach, Details, Disable, Distinct, Double, Drop, Else, Enable, End, Error, Every, Except, Exclude, Exclusive, Exists, Exit, Explain, External, False, Fill, First, Float, Following, For, Foreign, Format, From, Full, Geohash, Grant, Group, Groups, Header, Horizon, Hour, Hours, Http, If, Ignore, Ilike, Immediate, In, Include, Index, Inner, Insert, Incremental, Int, Integer, Intersect, Interval, Into, Ipv4, Is, Isolation, Jwk, Join, Keep, Key, Keys, Latest, Left, Length, Level, Like, Limit, Linear, List, Lock, Long, Long128, Long256, Lt, Manual, Maps, Materialized, MaxIdentifierLength, MaxUncommittedRows, Microsecond, Microseconds, Millennium, Millisecond, Milliseconds, Minute, Minutes, Month, Months, NaN, Nanosecond, Nanoseconds, No, Nocache, None, Not, Null, Nulls, O3MaxLag, Observation, Offset, On, Only, Option, Or, Order, Others, Outer, Over, Overridable, Owned, Param, Parameters, Parquet, ParquetVersion, PartitionBy, Partition, Partitions, Password, Period, Permissions, Pivot, Prepare, Preceding, Prev, Prevailing, Primary, Public, Query, Range, References, Refresh, Release, Reindex, Remove, Rename, Repair, Replace, Rest, Respect, Resume, Revoke, Right, Row, RowGroupSize, Rows, Sample, SearchPath, Second, Seconds, Select, ServerVersion, ServerVersionNum, Service, Set, Short, Show, Skip, SkipColumn, SkipRow, Snapshot, Splice, Squash, StandardConformingStrings, Step, Start, StatisticsEnabled, String, Suspend, Symbol, System, Table, Tables, Then, Time, Timestamp, TimestampNs, To, Token, Tolerance, Transaction, TransactionIsolation, Transient, True, Truncate, Ttl, Txn, Type, Unbounded, Union, Unlock, Unpivot, Update, Upsert, User, Users, Uuid, Vacuum, Values, Varchar, Verification, View, Volume, Wal, Week, Weeks, When, Where, Window, With, Within, Writer, Year, Years, Zone, RawArrayEncoding, Uncompressed, Snappy, Gzip, Lz4, Zstd, Lz4Raw, Brotli, Lzo, };
5
5
  export declare const Star: TokenType;
6
6
  export declare const Comma: TokenType;
7
7
  export declare const Semicolon: TokenType;
@@ -13,6 +13,7 @@ declare class QuestDBParser extends CstParser {
13
13
  statement: import("chevrotain").ParserMethod<[], import("chevrotain").CstNode>;
14
14
  private withStatement;
15
15
  private selectStatement;
16
+ private selectBody;
16
17
  private withClause;
17
18
  private cteDefinition;
18
19
  private simpleSelect;
@@ -30,6 +31,8 @@ declare class QuestDBParser extends CstParser {
30
31
  private asofLtJoin;
31
32
  private spliceJoin;
32
33
  private windowJoin;
34
+ private horizonJoin;
35
+ private horizonOffset;
33
36
  private standardJoin;
34
37
  private windowJoinBound;
35
38
  private durationExpression;
@@ -100,6 +100,7 @@ export declare const Grant: TokenType;
100
100
  export declare const Group: TokenType;
101
101
  export declare const Groups: TokenType;
102
102
  export declare const Header: TokenType;
103
+ export declare const Horizon: TokenType;
103
104
  export declare const Http: TokenType;
104
105
  export declare const If: TokenType;
105
106
  export declare const Ignore: TokenType;
@@ -200,6 +201,7 @@ export declare const Snapshot: TokenType;
200
201
  export declare const Splice: TokenType;
201
202
  export declare const Squash: TokenType;
202
203
  export declare const StandardConformingStrings: TokenType;
204
+ export declare const Step: TokenType;
203
205
  export declare const Start: TokenType;
204
206
  export declare const StatisticsEnabled: TokenType;
205
207
  export declare const Suspend: TokenType;
@@ -1,5 +1,5 @@
1
1
  import * as AST from "./ast";
2
- import type { AddUserStatementCstChildren, AdditiveExpressionCstChildren, AlignToClauseCstChildren, AlterGroupStatementCstChildren, AlterMaterializedViewActionCstChildren, AlterMaterializedViewStatementCstChildren, AlterServiceAccountStatementCstChildren, AlterStatementCstChildren, AlterTableActionCstChildren, AlterTableStatementCstChildren, AlterUserActionCstChildren, AlterUserStatementCstChildren, AlterViewStatementCstChildren, AndExpressionCstChildren, ArrayBracketBodyCstChildren, ArrayElementCstChildren, ArrayLiteralCstChildren, ArraySubscriptCstChildren, AsofLtJoinCstChildren, AssumeServiceAccountStatementCstChildren, BackupStatementCstChildren, BatchClauseCstChildren, BitAndExpressionCstChildren, BitOrExpressionCstChildren, BitXorExpressionCstChildren, BooleanLiteralCstChildren, CancelQueryStatementCstChildren, CaseExpressionCstChildren, CastDefinitionCstChildren, CastExpressionCstChildren, CheckpointStatementCstChildren, ColumnDefinitionCstChildren, ColumnRefCstChildren, CompileViewStatementCstChildren, ConcatExpressionCstChildren, Ipv4ContainmentExpressionCstChildren, ConvertPartitionTargetCstChildren, CopyCancelCstChildren, CopyFromCstChildren, CopyOptionCstChildren, CopyOptionsCstChildren, CopyStatementCstChildren, CopyToCstChildren, CreateGroupStatementCstChildren, CreateMaterializedViewBodyCstChildren, CreateServiceAccountStatementCstChildren, CreateStatementCstChildren, CreateTableBodyCstChildren, CreateUserStatementCstChildren, CreateViewBodyCstChildren, CteDefinitionCstChildren, DataTypeCstChildren, DeclareAssignmentCstChildren, DeclareClauseCstChildren, DedupClauseCstChildren, DropGroupStatementCstChildren, DropMaterializedViewStatementCstChildren, DropServiceAccountStatementCstChildren, DropStatementCstChildren, DropTableStatementCstChildren, DropUserStatementCstChildren, DropViewStatementCstChildren, DurationExpressionCstChildren, EqualityExpressionCstChildren, ExitServiceAccountStatementCstChildren, ExplainStatementCstChildren, ExpressionCstChildren, FillClauseCstChildren, FillValueCstChildren, FromClauseCstChildren, FromToClauseCstChildren, FunctionCallCstChildren, FunctionNameCstChildren, GrantAssumeServiceAccountStatementCstChildren, GrantStatementCstChildren, GrantTableTargetCstChildren, GroupByClauseCstChildren, IdentifierCstChildren, IdentifierExpressionCstChildren, ImplicitSelectBodyCstChildren, ImplicitSelectStatementCstChildren, IndexDefinitionCstChildren, InsertStatementCstChildren, IntervalValueCstChildren, JoinClauseCstChildren, LatestOnClauseCstChildren, LimitClauseCstChildren, LiteralCstChildren, MaterializedViewPartitionCstChildren, MaterializedViewPeriodCstChildren, MaterializedViewRefreshCstChildren, MultiplicativeExpressionCstChildren, NotExpressionCstChildren, OrExpressionCstChildren, OrderByClauseCstChildren, OrderByItemCstChildren, OverClauseCstChildren, PartitionPeriodCstChildren, PermissionListCstChildren, PermissionTokenCstChildren, PivotAggregationCstChildren, PivotBodyCstChildren, PivotForClauseCstChildren, PivotInValueCstChildren, PivotStatementCstChildren, PrimaryExpressionCstChildren, QualifiedNameCstChildren, QualifiedStarCstChildren, ReindexTableStatementCstChildren, RefreshMaterializedViewStatementCstChildren, RelationalExpressionCstChildren, RemoveUserStatementCstChildren, RenameTableStatementCstChildren, ResumeWalStatementCstChildren, RevokeAssumeServiceAccountStatementCstChildren, RevokeStatementCstChildren, SampleByClauseCstChildren, SelectItemCstChildren, SelectListCstChildren, SelectStatementCstChildren, SetClauseCstChildren, SetExpressionCstChildren, SetOperationCstChildren, SetTypeStatementCstChildren, ShowStatementCstChildren, SimpleSelectCstChildren, SnapshotStatementCstChildren, SpliceJoinCstChildren, StandardJoinCstChildren, StatementCstChildren, StatementsCstChildren, StringOrIdentifierCstChildren, StringOrQualifiedNameCstChildren, TableFunctionCallCstChildren, TableFunctionNameCstChildren, TableNameCstChildren, TableNameOrStringCstChildren, TableParamCstChildren, TableParamNameCstChildren, TableRefCstChildren, TimeUnitCstChildren, TimeZoneValueCstChildren, TruncateTableStatementCstChildren, TypeCastExpressionCstChildren, UnaryExpressionCstChildren, UpdateStatementCstChildren, VacuumTableStatementCstChildren, ValuesClauseCstChildren, ValuesListCstChildren, WhereClauseCstChildren, WindowFrameBoundCstChildren, WindowFrameClauseCstChildren, WindowJoinBoundCstChildren, WindowJoinCstChildren, WindowPartitionByClauseCstChildren, WithClauseCstChildren, WithStatementCstChildren } from "./cst-types";
2
+ import type { AddUserStatementCstChildren, AdditiveExpressionCstChildren, AlignToClauseCstChildren, AlterGroupStatementCstChildren, AlterMaterializedViewActionCstChildren, AlterMaterializedViewStatementCstChildren, AlterServiceAccountStatementCstChildren, AlterStatementCstChildren, AlterTableActionCstChildren, AlterTableStatementCstChildren, AlterUserActionCstChildren, AlterUserStatementCstChildren, AlterViewStatementCstChildren, AndExpressionCstChildren, ArrayBracketBodyCstChildren, ArrayElementCstChildren, ArrayLiteralCstChildren, ArraySubscriptCstChildren, AsofLtJoinCstChildren, AssumeServiceAccountStatementCstChildren, BackupStatementCstChildren, BatchClauseCstChildren, BitAndExpressionCstChildren, BitOrExpressionCstChildren, BitXorExpressionCstChildren, BooleanLiteralCstChildren, CancelQueryStatementCstChildren, CaseExpressionCstChildren, CastDefinitionCstChildren, CastExpressionCstChildren, CheckpointStatementCstChildren, ColumnDefinitionCstChildren, ColumnRefCstChildren, CompileViewStatementCstChildren, ConcatExpressionCstChildren, Ipv4ContainmentExpressionCstChildren, ConvertPartitionTargetCstChildren, CopyCancelCstChildren, CopyFromCstChildren, CopyOptionCstChildren, CopyOptionsCstChildren, CopyStatementCstChildren, CopyToCstChildren, CreateGroupStatementCstChildren, CreateMaterializedViewBodyCstChildren, CreateServiceAccountStatementCstChildren, CreateStatementCstChildren, CreateTableBodyCstChildren, CreateUserStatementCstChildren, CreateViewBodyCstChildren, CteDefinitionCstChildren, DataTypeCstChildren, DeclareAssignmentCstChildren, DeclareClauseCstChildren, DedupClauseCstChildren, DropGroupStatementCstChildren, DropMaterializedViewStatementCstChildren, DropServiceAccountStatementCstChildren, DropStatementCstChildren, DropTableStatementCstChildren, DropUserStatementCstChildren, DropViewStatementCstChildren, DurationExpressionCstChildren, EqualityExpressionCstChildren, ExitServiceAccountStatementCstChildren, ExplainStatementCstChildren, ExpressionCstChildren, FillClauseCstChildren, FillValueCstChildren, FromClauseCstChildren, FromToClauseCstChildren, FunctionCallCstChildren, FunctionNameCstChildren, GrantAssumeServiceAccountStatementCstChildren, GrantStatementCstChildren, GrantTableTargetCstChildren, GroupByClauseCstChildren, IdentifierCstChildren, IdentifierExpressionCstChildren, ImplicitSelectBodyCstChildren, ImplicitSelectStatementCstChildren, IndexDefinitionCstChildren, InsertStatementCstChildren, IntervalValueCstChildren, JoinClauseCstChildren, LatestOnClauseCstChildren, LimitClauseCstChildren, LiteralCstChildren, MaterializedViewPartitionCstChildren, MaterializedViewPeriodCstChildren, MaterializedViewRefreshCstChildren, MultiplicativeExpressionCstChildren, NotExpressionCstChildren, OrExpressionCstChildren, OrderByClauseCstChildren, OrderByItemCstChildren, OverClauseCstChildren, PartitionPeriodCstChildren, PermissionListCstChildren, PermissionTokenCstChildren, PivotAggregationCstChildren, PivotBodyCstChildren, PivotForClauseCstChildren, PivotInValueCstChildren, PivotStatementCstChildren, PrimaryExpressionCstChildren, QualifiedNameCstChildren, QualifiedStarCstChildren, ReindexTableStatementCstChildren, RefreshMaterializedViewStatementCstChildren, RelationalExpressionCstChildren, RemoveUserStatementCstChildren, RenameTableStatementCstChildren, ResumeWalStatementCstChildren, RevokeAssumeServiceAccountStatementCstChildren, RevokeStatementCstChildren, SampleByClauseCstChildren, SelectItemCstChildren, SelectListCstChildren, SelectBodyCstChildren, SelectStatementCstChildren, SetClauseCstChildren, SetExpressionCstChildren, SetOperationCstChildren, SetTypeStatementCstChildren, ShowStatementCstChildren, SimpleSelectCstChildren, SnapshotStatementCstChildren, SpliceJoinCstChildren, HorizonJoinCstChildren, HorizonOffsetCstChildren, StandardJoinCstChildren, StatementCstChildren, StatementsCstChildren, StringOrIdentifierCstChildren, StringOrQualifiedNameCstChildren, TableFunctionCallCstChildren, TableFunctionNameCstChildren, TableNameCstChildren, TableNameOrStringCstChildren, TableParamCstChildren, TableParamNameCstChildren, TableRefCstChildren, TimeUnitCstChildren, TimeZoneValueCstChildren, TruncateTableStatementCstChildren, TypeCastExpressionCstChildren, UnaryExpressionCstChildren, UpdateStatementCstChildren, VacuumTableStatementCstChildren, ValuesClauseCstChildren, ValuesListCstChildren, WhereClauseCstChildren, WindowFrameBoundCstChildren, WindowFrameClauseCstChildren, WindowJoinBoundCstChildren, WindowJoinCstChildren, WindowPartitionByClauseCstChildren, WithClauseCstChildren, WithStatementCstChildren } from "./cst-types";
3
3
  declare const BaseVisitor: new (...args: any[]) => import("chevrotain").ICstVisitor<any, any>;
4
4
  declare class QuestDBVisitor extends BaseVisitor {
5
5
  constructor();
@@ -8,6 +8,7 @@ declare class QuestDBVisitor extends BaseVisitor {
8
8
  statement(ctx: StatementCstChildren): AST.Statement;
9
9
  withStatement(ctx: WithStatementCstChildren): AST.Statement;
10
10
  selectStatement(ctx: SelectStatementCstChildren): AST.SelectStatement;
11
+ selectBody(ctx: SelectBodyCstChildren): AST.SelectStatement;
11
12
  withClause(ctx: WithClauseCstChildren): AST.CTE[];
12
13
  cteDefinition(ctx: CteDefinitionCstChildren): AST.CTE;
13
14
  simpleSelect(ctx: SimpleSelectCstChildren): AST.SelectStatement;
@@ -25,6 +26,8 @@ declare class QuestDBVisitor extends BaseVisitor {
25
26
  asofLtJoin(ctx: AsofLtJoinCstChildren): AST.JoinClause;
26
27
  spliceJoin(ctx: SpliceJoinCstChildren): AST.JoinClause;
27
28
  windowJoin(ctx: WindowJoinCstChildren): AST.JoinClause;
29
+ horizonJoin(ctx: HorizonJoinCstChildren): AST.JoinClause;
30
+ horizonOffset(ctx: HorizonOffsetCstChildren): string;
28
31
  standardJoin(ctx: StandardJoinCstChildren): AST.JoinClause;
29
32
  windowJoinBound(ctx: WindowJoinBoundCstChildren): AST.WindowJoinBound;
30
33
  durationExpression(ctx: DurationExpressionCstChildren): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@questdb/sql-parser",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "SQL parser for QuestDB syntax using Chevrotain",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",