@questdb/sql-parser 0.1.1 → 0.1.3

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,8 +1,17 @@
1
1
  # Changelog
2
2
 
3
3
 
4
- ## 0.1.1 - 2026.02.23
4
+ ## 0.1.3 - 2026.03.04
5
+ ### Added
6
+ - horizon join support [#9](https://github.com/questdb/sql-parser/pull/9)
7
+
8
+
9
+ ## 0.1.2 - 2026.02.25
10
+ ### Fixed
11
+ - Prioritize tables with mentioned columns in the suggestions [#6](https://github.com/questdb/sql-parser/pull/6)
12
+
5
13
 
14
+ ## 0.1.1 - 2026.02.23
6
15
  ### Fixed
7
16
  - grammar-level table/column classification, join-specific suggestions [#2](https://github.com/questdb/sql-parser/pull/2)
8
17
 
@@ -37,7 +37,30 @@ export interface ContentAssistResult {
37
37
  suggestColumns: boolean;
38
38
  /** Whether the grammar context expects table names (tableName positions, or expression context) */
39
39
  suggestTables: boolean;
40
+ /**
41
+ * Bare column names (lowercase) referenced before the cursor in expression
42
+ * context. Used by the provider to boost tables containing all these columns.
43
+ */
44
+ referencedColumns: Set<string>;
40
45
  }
46
+ /**
47
+ * Extract bare column names referenced in expression context from a token list.
48
+ *
49
+ * Scans the tokens and collects identifier names that are likely column
50
+ * references, excluding:
51
+ * - Qualified identifiers (followed by a Dot token — table/alias qualifiers)
52
+ * - Middle segments of multi-part names (preceded AND followed by a Dot)
53
+ * - Known table names and aliases (matched against tableAndAliasSet)
54
+ * - Function calls (followed by a left-parenthesis token)
55
+ *
56
+ * @param tokens - Tokens to scan
57
+ * @param tableAndAliasSet - Lowercase table names and aliases already in scope
58
+ * (built from tablesInScope by the caller). Identifiers matching any of these
59
+ * are excluded because they are table/alias references, not column names.
60
+ *
61
+ * Returns a Set of lowercase column names for efficient lookup.
62
+ */
63
+ export declare function extractReferencedColumns(tokens: IToken[], tableAndAliasSet: Set<string>): Set<string>;
41
64
  /**
42
65
  * Get content assist suggestions for a SQL string at a given cursor position
43
66
  *
@@ -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");
@@ -1533,6 +1534,7 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1533
1534
  { ALT: () => this.SUBRULE(this.asofLtJoin) },
1534
1535
  { ALT: () => this.SUBRULE(this.spliceJoin) },
1535
1536
  { ALT: () => this.SUBRULE(this.windowJoin) },
1537
+ { ALT: () => this.SUBRULE(this.horizonJoin) },
1536
1538
  { ALT: () => this.SUBRULE(this.standardJoin) }
1537
1539
  ]);
1538
1540
  });
@@ -1590,6 +1592,69 @@ var QuestDBParser = class extends import_chevrotain3.CstParser {
1590
1592
  this.CONSUME1(Prevailing);
1591
1593
  });
1592
1594
  });
1595
+ // HORIZON JOIN: tableName alias [ON expr] (RANGE FROM/TO/STEP | LIST (...)) AS alias
1596
+ // Uses tableName + custom alias instead of tableRef to avoid ambiguity
1597
+ // between implicit keyword aliases and RANGE/LIST/ON keywords.
1598
+ this.horizonJoin = this.RULE("horizonJoin", () => {
1599
+ this.CONSUME(Horizon);
1600
+ this.CONSUME(Join);
1601
+ this.SUBRULE(this.tableName);
1602
+ this.OR1([
1603
+ {
1604
+ ALT: () => {
1605
+ this.CONSUME(As);
1606
+ this.SUBRULE(this.identifier);
1607
+ }
1608
+ },
1609
+ {
1610
+ // Implicit alias: only base Identifier, never keywords like RANGE/LIST
1611
+ ALT: () => this.CONSUME(Identifier)
1612
+ }
1613
+ ]);
1614
+ this.OPTION(() => {
1615
+ this.CONSUME(On);
1616
+ this.SUBRULE(this.expression);
1617
+ });
1618
+ this.OR2([
1619
+ {
1620
+ // RANGE FROM <offset> TO <offset> STEP <offset> AS <alias>
1621
+ ALT: () => {
1622
+ this.CONSUME(Range);
1623
+ this.CONSUME(From);
1624
+ this.SUBRULE(this.horizonOffset);
1625
+ this.CONSUME(To);
1626
+ this.SUBRULE1(this.horizonOffset);
1627
+ this.CONSUME(Step);
1628
+ this.SUBRULE2(this.horizonOffset);
1629
+ this.CONSUME1(As);
1630
+ this.SUBRULE1(this.identifier);
1631
+ }
1632
+ },
1633
+ {
1634
+ // LIST (<offset>, ...) AS <alias>
1635
+ ALT: () => {
1636
+ this.CONSUME(List);
1637
+ this.CONSUME(LParen);
1638
+ this.SUBRULE3(this.horizonOffset);
1639
+ this.MANY(() => {
1640
+ this.CONSUME(Comma);
1641
+ this.SUBRULE4(this.horizonOffset);
1642
+ });
1643
+ this.CONSUME(RParen);
1644
+ this.CONSUME2(As);
1645
+ this.SUBRULE2(this.identifier);
1646
+ }
1647
+ }
1648
+ ]);
1649
+ });
1650
+ // Horizon offset value: optional minus sign + DurationLiteral | NumberLiteral
1651
+ this.horizonOffset = this.RULE("horizonOffset", () => {
1652
+ this.OPTION(() => this.CONSUME(Minus));
1653
+ this.OR([
1654
+ { ALT: () => this.CONSUME(DurationLiteral) },
1655
+ { ALT: () => this.CONSUME(NumberLiteral) }
1656
+ ]);
1657
+ });
1593
1658
  // Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
1594
1659
  this.standardJoin = this.RULE("standardJoin", () => {
1595
1660
  this.OPTION(() => {
@@ -4996,6 +5061,7 @@ var QuestDBVisitor = class extends BaseVisitor {
4996
5061
  if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
4997
5062
  if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
4998
5063
  if (ctx.windowJoin) return this.visit(ctx.windowJoin);
5064
+ if (ctx.horizonJoin) return this.visit(ctx.horizonJoin);
4999
5065
  return this.visit(ctx.standardJoin);
5000
5066
  }
5001
5067
  asofLtJoin(ctx) {
@@ -5044,6 +5110,49 @@ var QuestDBVisitor = class extends BaseVisitor {
5044
5110
  }
5045
5111
  return result;
5046
5112
  }
5113
+ horizonJoin(ctx) {
5114
+ const tableRef = {
5115
+ type: "tableRef",
5116
+ table: this.visit(ctx.tableName)
5117
+ };
5118
+ if (ctx.Identifier) {
5119
+ tableRef.alias = ctx.Identifier[0].image;
5120
+ } else if (ctx.identifier && ctx.identifier.length > 1) {
5121
+ tableRef.alias = this.visit(ctx.identifier[0]).parts[0];
5122
+ }
5123
+ const result = {
5124
+ type: "join",
5125
+ joinType: "horizon",
5126
+ table: tableRef
5127
+ };
5128
+ if (ctx.expression) {
5129
+ result.on = this.visit(ctx.expression);
5130
+ }
5131
+ if (ctx.Range) {
5132
+ const offsets = ctx.horizonOffset;
5133
+ result.horizonRange = {
5134
+ from: this.visit(offsets[0]),
5135
+ to: this.visit(offsets[1]),
5136
+ step: this.visit(offsets[2])
5137
+ };
5138
+ } else if (ctx.List) {
5139
+ result.horizonList = ctx.horizonOffset.map(
5140
+ (o) => this.visit(o)
5141
+ );
5142
+ }
5143
+ if (ctx.identifier) {
5144
+ const lastId = ctx.identifier[ctx.identifier.length - 1];
5145
+ result.horizonAlias = this.visit(lastId).parts[0];
5146
+ }
5147
+ return result;
5148
+ }
5149
+ horizonOffset(ctx) {
5150
+ const sign = ctx.Minus ? "-" : "";
5151
+ if (ctx.DurationLiteral) {
5152
+ return sign + ctx.DurationLiteral[0].image;
5153
+ }
5154
+ return sign + ctx.NumberLiteral[0].image;
5155
+ }
5047
5156
  standardJoin(ctx) {
5048
5157
  const result = {
5049
5158
  type: "join",
@@ -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) {
@@ -9630,6 +9754,32 @@ function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
9630
9754
  const table = tableToken.tokenType.name === "QuotedIdentifier" ? tableToken.image.slice(1, -1) : tableToken.image;
9631
9755
  return { table };
9632
9756
  }
9757
+ function extractReferencedColumns(tokens, tableAndAliasSet) {
9758
+ const result = /* @__PURE__ */ new Set();
9759
+ for (let i = 0; i < tokens.length; i++) {
9760
+ const token = tokens[i];
9761
+ const name = token.tokenType.name;
9762
+ if (name !== "Identifier" && name !== "QuotedIdentifier" && !IDENTIFIER_KEYWORD_TOKENS.has(name)) {
9763
+ continue;
9764
+ }
9765
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9766
+ continue;
9767
+ }
9768
+ if (i > 0 && tokens[i - 1].tokenType.name === "Dot" && i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9769
+ continue;
9770
+ }
9771
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "LParen") {
9772
+ continue;
9773
+ }
9774
+ const image = name === "QuotedIdentifier" ? token.image.slice(1, -1) : token.image;
9775
+ const lower = image.toLowerCase();
9776
+ if (tableAndAliasSet.has(lower)) {
9777
+ continue;
9778
+ }
9779
+ result.add(lower);
9780
+ }
9781
+ return result;
9782
+ }
9633
9783
  function getContentAssist(fullSql, cursorOffset) {
9634
9784
  const fullTokens = QuestDBLexer.tokenize(fullSql).tokens;
9635
9785
  for (const token of fullTokens) {
@@ -9646,7 +9796,8 @@ function getContentAssist(fullSql, cursorOffset) {
9646
9796
  isMidWord: true,
9647
9797
  lexErrors: [],
9648
9798
  suggestColumns: false,
9649
- suggestTables: false
9799
+ suggestTables: false,
9800
+ referencedColumns: /* @__PURE__ */ new Set()
9650
9801
  };
9651
9802
  }
9652
9803
  }
@@ -9698,6 +9849,15 @@ function getContentAssist(fullSql, cursorOffset) {
9698
9849
  if (tablesInScope.length === 0 && qualifiedRef) {
9699
9850
  tablesInScope.push(qualifiedRef);
9700
9851
  }
9852
+ const tableAndAliasSet = /* @__PURE__ */ new Set();
9853
+ for (const t of tablesInScope) {
9854
+ tableAndAliasSet.add(t.table.toLowerCase());
9855
+ if (t.alias) tableAndAliasSet.add(t.alias.toLowerCase());
9856
+ }
9857
+ const referencedColumns = extractReferencedColumns(
9858
+ tokensForAssist,
9859
+ tableAndAliasSet
9860
+ );
9701
9861
  return {
9702
9862
  nextTokenTypes,
9703
9863
  tablesInScope,
@@ -9707,7 +9867,8 @@ function getContentAssist(fullSql, cursorOffset) {
9707
9867
  lexErrors: lexResult.errors,
9708
9868
  qualifiedTableRef: qualifiedRef?.table,
9709
9869
  suggestColumns,
9710
- suggestTables
9870
+ suggestTables,
9871
+ referencedColumns
9711
9872
  };
9712
9873
  }
9713
9874
  function getNextValidTokens(sql) {
@@ -9755,12 +9916,16 @@ var functions = [
9755
9916
  "approx_percentile",
9756
9917
  "arg_max",
9757
9918
  "arg_min",
9919
+ "array_agg",
9758
9920
  "array_avg",
9921
+ "array_build",
9759
9922
  "array_count",
9760
9923
  "array_cum_sum",
9761
9924
  "array_max",
9762
9925
  "array_min",
9763
9926
  "array_position",
9927
+ "array_reverse",
9928
+ "array_sort",
9764
9929
  "array_stddev",
9765
9930
  "array_stddev_pop",
9766
9931
  "array_stddev_samp",
@@ -10287,6 +10452,35 @@ var TABLE_NAME_TOKENS = /* @__PURE__ */ new Set([
10287
10452
  "Table",
10288
10453
  "View"
10289
10454
  ]);
10455
+ function buildColumnIndex(schema) {
10456
+ const index = /* @__PURE__ */ new Map();
10457
+ for (const table of schema.tables) {
10458
+ const key = table.name.toLowerCase();
10459
+ const cols = schema.columns[key];
10460
+ if (cols) {
10461
+ index.set(key, new Set(cols.map((c) => c.name.toLowerCase())));
10462
+ }
10463
+ }
10464
+ return index;
10465
+ }
10466
+ function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
10467
+ if (referencedColumns.size === 0) return;
10468
+ const scores = /* @__PURE__ */ new Map();
10469
+ for (const [tableName, colNames] of columnIndex) {
10470
+ let count = 0;
10471
+ for (const ref of referencedColumns) {
10472
+ if (colNames.has(ref)) count++;
10473
+ }
10474
+ if (count > 0) scores.set(tableName, count);
10475
+ }
10476
+ if (scores.size === 0) return;
10477
+ for (const s of suggestions) {
10478
+ if (s.kind !== "table" /* Table */) continue;
10479
+ const score = scores.get(s.label.toLowerCase());
10480
+ if (score === void 0) continue;
10481
+ s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
10482
+ }
10483
+ }
10290
10484
  function getLastSignificantTokens(tokens) {
10291
10485
  const result = [];
10292
10486
  for (let i = tokens.length - 1; i >= 0; i--) {
@@ -10310,6 +10504,7 @@ function createAutocompleteProvider(schema) {
10310
10504
  ])
10311
10505
  )
10312
10506
  };
10507
+ const columnIndex = buildColumnIndex(normalizedSchema);
10313
10508
  return {
10314
10509
  getSuggestions(query, cursorOffset) {
10315
10510
  const {
@@ -10320,7 +10515,8 @@ function createAutocompleteProvider(schema) {
10320
10515
  isMidWord,
10321
10516
  qualifiedTableRef,
10322
10517
  suggestColumns,
10323
- suggestTables
10518
+ suggestTables,
10519
+ referencedColumns
10324
10520
  } = getContentAssist(query, cursorOffset);
10325
10521
  const effectiveSchema = Object.keys(cteColumns).length > 0 ? {
10326
10522
  ...normalizedSchema,
@@ -10348,7 +10544,7 @@ function createAutocompleteProvider(schema) {
10348
10544
  }
10349
10545
  }
10350
10546
  if (nextTokenTypes.length > 0) {
10351
- return buildSuggestions(
10547
+ const suggestions = buildSuggestions(
10352
10548
  nextTokenTypes,
10353
10549
  effectiveSchema,
10354
10550
  effectiveTablesInScope,
@@ -10358,6 +10554,10 @@ function createAutocompleteProvider(schema) {
10358
10554
  isMidWord
10359
10555
  }
10360
10556
  );
10557
+ if (suggestTables) {
10558
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10559
+ }
10560
+ return suggestions;
10361
10561
  }
10362
10562
  const fallbackTokens = isMidWord && tokensBefore.length > 0 ? tokensBefore.slice(0, -1) : tokensBefore;
10363
10563
  const [lastFallback] = getLastSignificantTokens(fallbackTokens);
@@ -10386,6 +10586,7 @@ function createAutocompleteProvider(schema) {
10386
10586
  });
10387
10587
  }
10388
10588
  }
10589
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10389
10590
  return suggestions;
10390
10591
  }
10391
10592
  return [];
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");
@@ -1473,6 +1474,7 @@ var QuestDBParser = class extends CstParser {
1473
1474
  { ALT: () => this.SUBRULE(this.asofLtJoin) },
1474
1475
  { ALT: () => this.SUBRULE(this.spliceJoin) },
1475
1476
  { ALT: () => this.SUBRULE(this.windowJoin) },
1477
+ { ALT: () => this.SUBRULE(this.horizonJoin) },
1476
1478
  { ALT: () => this.SUBRULE(this.standardJoin) }
1477
1479
  ]);
1478
1480
  });
@@ -1530,6 +1532,69 @@ var QuestDBParser = class extends CstParser {
1530
1532
  this.CONSUME1(Prevailing);
1531
1533
  });
1532
1534
  });
1535
+ // HORIZON JOIN: tableName alias [ON expr] (RANGE FROM/TO/STEP | LIST (...)) AS alias
1536
+ // Uses tableName + custom alias instead of tableRef to avoid ambiguity
1537
+ // between implicit keyword aliases and RANGE/LIST/ON keywords.
1538
+ this.horizonJoin = this.RULE("horizonJoin", () => {
1539
+ this.CONSUME(Horizon);
1540
+ this.CONSUME(Join);
1541
+ this.SUBRULE(this.tableName);
1542
+ this.OR1([
1543
+ {
1544
+ ALT: () => {
1545
+ this.CONSUME(As);
1546
+ this.SUBRULE(this.identifier);
1547
+ }
1548
+ },
1549
+ {
1550
+ // Implicit alias: only base Identifier, never keywords like RANGE/LIST
1551
+ ALT: () => this.CONSUME(Identifier)
1552
+ }
1553
+ ]);
1554
+ this.OPTION(() => {
1555
+ this.CONSUME(On);
1556
+ this.SUBRULE(this.expression);
1557
+ });
1558
+ this.OR2([
1559
+ {
1560
+ // RANGE FROM <offset> TO <offset> STEP <offset> AS <alias>
1561
+ ALT: () => {
1562
+ this.CONSUME(Range);
1563
+ this.CONSUME(From);
1564
+ this.SUBRULE(this.horizonOffset);
1565
+ this.CONSUME(To);
1566
+ this.SUBRULE1(this.horizonOffset);
1567
+ this.CONSUME(Step);
1568
+ this.SUBRULE2(this.horizonOffset);
1569
+ this.CONSUME1(As);
1570
+ this.SUBRULE1(this.identifier);
1571
+ }
1572
+ },
1573
+ {
1574
+ // LIST (<offset>, ...) AS <alias>
1575
+ ALT: () => {
1576
+ this.CONSUME(List);
1577
+ this.CONSUME(LParen);
1578
+ this.SUBRULE3(this.horizonOffset);
1579
+ this.MANY(() => {
1580
+ this.CONSUME(Comma);
1581
+ this.SUBRULE4(this.horizonOffset);
1582
+ });
1583
+ this.CONSUME(RParen);
1584
+ this.CONSUME2(As);
1585
+ this.SUBRULE2(this.identifier);
1586
+ }
1587
+ }
1588
+ ]);
1589
+ });
1590
+ // Horizon offset value: optional minus sign + DurationLiteral | NumberLiteral
1591
+ this.horizonOffset = this.RULE("horizonOffset", () => {
1592
+ this.OPTION(() => this.CONSUME(Minus));
1593
+ this.OR([
1594
+ { ALT: () => this.CONSUME(DurationLiteral) },
1595
+ { ALT: () => this.CONSUME(NumberLiteral) }
1596
+ ]);
1597
+ });
1533
1598
  // Standard joins: (INNER | LEFT [OUTER] | RIGHT [OUTER] | FULL [OUTER] | CROSS)? JOIN + ON
1534
1599
  this.standardJoin = this.RULE("standardJoin", () => {
1535
1600
  this.OPTION(() => {
@@ -4936,6 +5001,7 @@ var QuestDBVisitor = class extends BaseVisitor {
4936
5001
  if (ctx.asofLtJoin) return this.visit(ctx.asofLtJoin);
4937
5002
  if (ctx.spliceJoin) return this.visit(ctx.spliceJoin);
4938
5003
  if (ctx.windowJoin) return this.visit(ctx.windowJoin);
5004
+ if (ctx.horizonJoin) return this.visit(ctx.horizonJoin);
4939
5005
  return this.visit(ctx.standardJoin);
4940
5006
  }
4941
5007
  asofLtJoin(ctx) {
@@ -4984,6 +5050,49 @@ var QuestDBVisitor = class extends BaseVisitor {
4984
5050
  }
4985
5051
  return result;
4986
5052
  }
5053
+ horizonJoin(ctx) {
5054
+ const tableRef = {
5055
+ type: "tableRef",
5056
+ table: this.visit(ctx.tableName)
5057
+ };
5058
+ if (ctx.Identifier) {
5059
+ tableRef.alias = ctx.Identifier[0].image;
5060
+ } else if (ctx.identifier && ctx.identifier.length > 1) {
5061
+ tableRef.alias = this.visit(ctx.identifier[0]).parts[0];
5062
+ }
5063
+ const result = {
5064
+ type: "join",
5065
+ joinType: "horizon",
5066
+ table: tableRef
5067
+ };
5068
+ if (ctx.expression) {
5069
+ result.on = this.visit(ctx.expression);
5070
+ }
5071
+ if (ctx.Range) {
5072
+ const offsets = ctx.horizonOffset;
5073
+ result.horizonRange = {
5074
+ from: this.visit(offsets[0]),
5075
+ to: this.visit(offsets[1]),
5076
+ step: this.visit(offsets[2])
5077
+ };
5078
+ } else if (ctx.List) {
5079
+ result.horizonList = ctx.horizonOffset.map(
5080
+ (o) => this.visit(o)
5081
+ );
5082
+ }
5083
+ if (ctx.identifier) {
5084
+ const lastId = ctx.identifier[ctx.identifier.length - 1];
5085
+ result.horizonAlias = this.visit(lastId).parts[0];
5086
+ }
5087
+ return result;
5088
+ }
5089
+ horizonOffset(ctx) {
5090
+ const sign = ctx.Minus ? "-" : "";
5091
+ if (ctx.DurationLiteral) {
5092
+ return sign + ctx.DurationLiteral[0].image;
5093
+ }
5094
+ return sign + ctx.NumberLiteral[0].image;
5095
+ }
4987
5096
  standardJoin(ctx) {
4988
5097
  const result = {
4989
5098
  type: "join",
@@ -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) {
@@ -9570,6 +9694,32 @@ function inferTableFromQualifiedRef(tokensBefore, isMidWord) {
9570
9694
  const table = tableToken.tokenType.name === "QuotedIdentifier" ? tableToken.image.slice(1, -1) : tableToken.image;
9571
9695
  return { table };
9572
9696
  }
9697
+ function extractReferencedColumns(tokens, tableAndAliasSet) {
9698
+ const result = /* @__PURE__ */ new Set();
9699
+ for (let i = 0; i < tokens.length; i++) {
9700
+ const token = tokens[i];
9701
+ const name = token.tokenType.name;
9702
+ if (name !== "Identifier" && name !== "QuotedIdentifier" && !IDENTIFIER_KEYWORD_TOKENS.has(name)) {
9703
+ continue;
9704
+ }
9705
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9706
+ continue;
9707
+ }
9708
+ if (i > 0 && tokens[i - 1].tokenType.name === "Dot" && i + 1 < tokens.length && tokens[i + 1].tokenType.name === "Dot") {
9709
+ continue;
9710
+ }
9711
+ if (i + 1 < tokens.length && tokens[i + 1].tokenType.name === "LParen") {
9712
+ continue;
9713
+ }
9714
+ const image = name === "QuotedIdentifier" ? token.image.slice(1, -1) : token.image;
9715
+ const lower = image.toLowerCase();
9716
+ if (tableAndAliasSet.has(lower)) {
9717
+ continue;
9718
+ }
9719
+ result.add(lower);
9720
+ }
9721
+ return result;
9722
+ }
9573
9723
  function getContentAssist(fullSql, cursorOffset) {
9574
9724
  const fullTokens = QuestDBLexer.tokenize(fullSql).tokens;
9575
9725
  for (const token of fullTokens) {
@@ -9586,7 +9736,8 @@ function getContentAssist(fullSql, cursorOffset) {
9586
9736
  isMidWord: true,
9587
9737
  lexErrors: [],
9588
9738
  suggestColumns: false,
9589
- suggestTables: false
9739
+ suggestTables: false,
9740
+ referencedColumns: /* @__PURE__ */ new Set()
9590
9741
  };
9591
9742
  }
9592
9743
  }
@@ -9638,6 +9789,15 @@ function getContentAssist(fullSql, cursorOffset) {
9638
9789
  if (tablesInScope.length === 0 && qualifiedRef) {
9639
9790
  tablesInScope.push(qualifiedRef);
9640
9791
  }
9792
+ const tableAndAliasSet = /* @__PURE__ */ new Set();
9793
+ for (const t of tablesInScope) {
9794
+ tableAndAliasSet.add(t.table.toLowerCase());
9795
+ if (t.alias) tableAndAliasSet.add(t.alias.toLowerCase());
9796
+ }
9797
+ const referencedColumns = extractReferencedColumns(
9798
+ tokensForAssist,
9799
+ tableAndAliasSet
9800
+ );
9641
9801
  return {
9642
9802
  nextTokenTypes,
9643
9803
  tablesInScope,
@@ -9647,7 +9807,8 @@ function getContentAssist(fullSql, cursorOffset) {
9647
9807
  lexErrors: lexResult.errors,
9648
9808
  qualifiedTableRef: qualifiedRef?.table,
9649
9809
  suggestColumns,
9650
- suggestTables
9810
+ suggestTables,
9811
+ referencedColumns
9651
9812
  };
9652
9813
  }
9653
9814
  function getNextValidTokens(sql) {
@@ -9695,12 +9856,16 @@ var functions = [
9695
9856
  "approx_percentile",
9696
9857
  "arg_max",
9697
9858
  "arg_min",
9859
+ "array_agg",
9698
9860
  "array_avg",
9861
+ "array_build",
9699
9862
  "array_count",
9700
9863
  "array_cum_sum",
9701
9864
  "array_max",
9702
9865
  "array_min",
9703
9866
  "array_position",
9867
+ "array_reverse",
9868
+ "array_sort",
9704
9869
  "array_stddev",
9705
9870
  "array_stddev_pop",
9706
9871
  "array_stddev_samp",
@@ -10227,6 +10392,35 @@ var TABLE_NAME_TOKENS = /* @__PURE__ */ new Set([
10227
10392
  "Table",
10228
10393
  "View"
10229
10394
  ]);
10395
+ function buildColumnIndex(schema) {
10396
+ const index = /* @__PURE__ */ new Map();
10397
+ for (const table of schema.tables) {
10398
+ const key = table.name.toLowerCase();
10399
+ const cols = schema.columns[key];
10400
+ if (cols) {
10401
+ index.set(key, new Set(cols.map((c) => c.name.toLowerCase())));
10402
+ }
10403
+ }
10404
+ return index;
10405
+ }
10406
+ function rankTableSuggestions(suggestions, referencedColumns, columnIndex) {
10407
+ if (referencedColumns.size === 0) return;
10408
+ const scores = /* @__PURE__ */ new Map();
10409
+ for (const [tableName, colNames] of columnIndex) {
10410
+ let count = 0;
10411
+ for (const ref of referencedColumns) {
10412
+ if (colNames.has(ref)) count++;
10413
+ }
10414
+ if (count > 0) scores.set(tableName, count);
10415
+ }
10416
+ if (scores.size === 0) return;
10417
+ for (const s of suggestions) {
10418
+ if (s.kind !== "table" /* Table */) continue;
10419
+ const score = scores.get(s.label.toLowerCase());
10420
+ if (score === void 0) continue;
10421
+ s.priority = score === referencedColumns.size ? 1 /* High */ : 2 /* Medium */;
10422
+ }
10423
+ }
10230
10424
  function getLastSignificantTokens(tokens) {
10231
10425
  const result = [];
10232
10426
  for (let i = tokens.length - 1; i >= 0; i--) {
@@ -10250,6 +10444,7 @@ function createAutocompleteProvider(schema) {
10250
10444
  ])
10251
10445
  )
10252
10446
  };
10447
+ const columnIndex = buildColumnIndex(normalizedSchema);
10253
10448
  return {
10254
10449
  getSuggestions(query, cursorOffset) {
10255
10450
  const {
@@ -10260,7 +10455,8 @@ function createAutocompleteProvider(schema) {
10260
10455
  isMidWord,
10261
10456
  qualifiedTableRef,
10262
10457
  suggestColumns,
10263
- suggestTables
10458
+ suggestTables,
10459
+ referencedColumns
10264
10460
  } = getContentAssist(query, cursorOffset);
10265
10461
  const effectiveSchema = Object.keys(cteColumns).length > 0 ? {
10266
10462
  ...normalizedSchema,
@@ -10288,7 +10484,7 @@ function createAutocompleteProvider(schema) {
10288
10484
  }
10289
10485
  }
10290
10486
  if (nextTokenTypes.length > 0) {
10291
- return buildSuggestions(
10487
+ const suggestions = buildSuggestions(
10292
10488
  nextTokenTypes,
10293
10489
  effectiveSchema,
10294
10490
  effectiveTablesInScope,
@@ -10298,6 +10494,10 @@ function createAutocompleteProvider(schema) {
10298
10494
  isMidWord
10299
10495
  }
10300
10496
  );
10497
+ if (suggestTables) {
10498
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10499
+ }
10500
+ return suggestions;
10301
10501
  }
10302
10502
  const fallbackTokens = isMidWord && tokensBefore.length > 0 ? tokensBefore.slice(0, -1) : tokensBefore;
10303
10503
  const [lastFallback] = getLastSignificantTokens(fallbackTokens);
@@ -10326,6 +10526,7 @@ function createAutocompleteProvider(schema) {
10326
10526
  });
10327
10527
  }
10328
10528
  }
10529
+ rankTableSuggestions(suggestions, referencedColumns, columnIndex);
10329
10530
  return suggestions;
10330
10531
  }
10331
10532
  return [];
@@ -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" | "right" | "full" | "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;
@@ -30,6 +30,8 @@ declare class QuestDBParser extends CstParser {
30
30
  private asofLtJoin;
31
31
  private spliceJoin;
32
32
  private windowJoin;
33
+ private horizonJoin;
34
+ private horizonOffset;
33
35
  private standardJoin;
34
36
  private windowJoinBound;
35
37
  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, 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();
@@ -25,6 +25,8 @@ declare class QuestDBVisitor extends BaseVisitor {
25
25
  asofLtJoin(ctx: AsofLtJoinCstChildren): AST.JoinClause;
26
26
  spliceJoin(ctx: SpliceJoinCstChildren): AST.JoinClause;
27
27
  windowJoin(ctx: WindowJoinCstChildren): AST.JoinClause;
28
+ horizonJoin(ctx: HorizonJoinCstChildren): AST.JoinClause;
29
+ horizonOffset(ctx: HorizonOffsetCstChildren): string;
28
30
  standardJoin(ctx: StandardJoinCstChildren): AST.JoinClause;
29
31
  windowJoinBound(ctx: WindowJoinBoundCstChildren): AST.WindowJoinBound;
30
32
  durationExpression(ctx: DurationExpressionCstChildren): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@questdb/sql-parser",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "SQL parser for QuestDB syntax using Chevrotain",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",