@pythia-software/query-table-duckdb 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -78,6 +78,10 @@ declare class DuckDBBackend {
78
78
  private validateRequest;
79
79
  execute(request: QueryRequestV3, signal?: AbortSignal): Promise<QueryResultV3>;
80
80
  private metrics;
81
+ /** A temporary (value, bucket) table mapping each distinct non-null value
82
+ * of `config.field` in `population` to the start of its calendar interval,
83
+ * or to its cyclic slot, computed with the core calendar. */
84
+ private calendarMapping;
81
85
  private metric;
82
86
  transport(): Transport<DuckDBRow>;
83
87
  }
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/sql.ts
2
2
  import {
3
+ branchesOf,
3
4
  coerceValue,
4
5
  compileFormula,
5
6
  compileMetric,
@@ -62,10 +63,11 @@ var SQLBuilder = class {
62
63
  throw Error("At most 100 filter terms are allowed.");
63
64
  let count = 0;
64
65
  return terms.length ? terms.map((term) => {
65
- const clauses = "any" in term ? term.any : [term];
66
- if (!clauses.length || (count += clauses.length) > 100)
66
+ const branches = branchesOf(term);
67
+ const size = branches.reduce((n, branch) => n + branch.length, 0);
68
+ if (!branches.length || branches.some((branch) => !branch.length) || (count += size) > 100)
67
69
  throw Error("Invalid filter predicate budget.");
68
- return `(${clauses.map((clause) => {
70
+ const compile = (clause) => {
69
71
  const field = this.definition(clause.field), raw = this.field(field.name), op = clause.op;
70
72
  if (!isFilterable(field) || !opsForField(field).includes(op))
71
73
  throw Error(`Unsupported filter on ${field.name}: ${op}.`);
@@ -96,7 +98,8 @@ var SQLBuilder = class {
96
98
  } else throw Error(`Unsupported DuckDB operator: ${op}.`);
97
99
  }
98
100
  return clause.negated ? `NOT (${sql})` : sql;
99
- }).join(" OR ")})`;
101
+ };
102
+ return `(${branches.map((branch) => branch.length === 1 ? compile(branch[0]) : `(${branch.map(compile).join(" AND ")})`).join(" OR ")})`;
100
103
  }).join(" AND ") : "TRUE";
101
104
  }
102
105
  order(terms, identity = true) {
@@ -258,6 +261,9 @@ import {
258
261
  createGroupingModel,
259
262
  GROUP_ID_FIELD,
260
263
  metricExpression,
264
+ metricMinCount,
265
+ metricMinCountKeeps,
266
+ metricMinCountMeasure,
261
267
  validateMetric,
262
268
  isSelectable as isSelectable2,
263
269
  isFilterable as isFilterable2,
@@ -266,9 +272,14 @@ import {
266
272
  histogramCounts,
267
273
  compareMetricValues,
268
274
  metricDateFloor,
275
+ isMetricCycle,
276
+ metricCycleSlot,
277
+ metricCycleSlots,
269
278
  metricDateTime,
270
279
  metricDateNext,
271
- metricDateRange
280
+ metricDateRange,
281
+ groupKeyFields,
282
+ isCalendarGroupKey
272
283
  } from "@pythia-software/query-table-core";
273
284
  var DUCKDB_PROFILE = "qt-duckdb-v1";
274
285
  function abort(signal) {
@@ -383,12 +394,15 @@ var DuckDBBackend = class {
383
394
  profile: DUCKDB_PROFILE,
384
395
  groupedRows: true,
385
396
  calendarGrouping: true,
397
+ calendarCycles: true,
398
+ calendarGroupKeys: true,
386
399
  computedSourceFilters: definitions.size > 0,
387
400
  regex: true,
388
401
  regexSourceFilters: true,
389
402
  regexAggregateExpressions: false,
390
403
  metricFilters: true,
391
404
  metricMinCount: true,
405
+ metricMinCountMeasures: true,
392
406
  maxRows: positive(options.maxRows, 1e4, 1e4),
393
407
  maxGroups: positive(options.maxGroups, 1e4, 1e4),
394
408
  maxPopulation: positive(options.maxPopulation, 25e4, 1e7)
@@ -594,7 +608,26 @@ var DuckDBBackend = class {
594
608
  let relation = source.name, schema = this.schema;
595
609
  if (request.grouping) {
596
610
  const grouping = request.grouping, model = createGroupingModel(schema), builder = this.builder(schema, request.now);
597
- const keys = grouping.keys.map((name) => builder.field(name, false)), names = grouping.keys.map(quoteIdentifier);
611
+ let from = quoteIdentifier(source.name);
612
+ const keys = [];
613
+ for (const [index, key] of grouping.keys.entries()) {
614
+ if (!isCalendarGroupKey(key)) {
615
+ keys.push(builder.field(key, false));
616
+ continue;
617
+ }
618
+ const mapping = await this.calendarMapping(
619
+ quoteIdentifier(source.name),
620
+ builder,
621
+ schema,
622
+ key,
623
+ tables,
624
+ signal
625
+ );
626
+ const value = quoteIdentifier(`qt_calendar_value${index}`), bucket = quoteIdentifier(`qt_calendar_key${index}`);
627
+ from += ` LEFT JOIN (SELECT value AS ${value}, bucket AS ${bucket} FROM ${quoteIdentifier(mapping)}) AS ${quoteIdentifier(`qt_calendar_map${index}`)} ON ${value} = CAST(${builder.field(key.field, false)} AS TIMESTAMPTZ)`;
628
+ keys.push(bucket);
629
+ }
630
+ const names = groupKeyFields(grouping.keys).map(quoteIdentifier);
598
631
  const representative = builder.order(
599
632
  grouping.representative?.orderBy ?? [
600
633
  { field: schema.idField, dir: "desc" }
@@ -611,7 +644,7 @@ var DuckDBBackend = class {
611
644
  const identity = `CAST(to_json(struct_pack(${keys.map((key, i) => `k${i} := ${key}`).join(", ")})) AS VARCHAR)`;
612
645
  await this.run(
613
646
  builder.statement(
614
- `CREATE TEMP TABLE ${quoteIdentifier(relation)} AS SELECT ${identity} AS ${quoteIdentifier(GROUP_ID_FIELD)}, ${keys.map((key, i) => `${key} AS ${names[i]}`).join(", ")}${summaries.length ? `, ${summaries.join(", ")}` : ""} FROM ${quoteIdentifier(source.name)} GROUP BY ${keys.join(", ")}`
647
+ `CREATE TEMP TABLE ${quoteIdentifier(relation)} AS SELECT ${identity} AS ${quoteIdentifier(GROUP_ID_FIELD)}, ${keys.map((key, i) => `${key} AS ${names[i]}`).join(", ")}${summaries.length ? `, ${summaries.join(", ")}` : ""} FROM ${from} GROUP BY ${keys.join(", ")}`
615
648
  ),
616
649
  signal
617
650
  );
@@ -693,6 +726,47 @@ var DuckDBBackend = class {
693
726
  await this.sql("BEGIN TRANSACTION", [], signal);
694
727
  return output;
695
728
  }
729
+ /** A temporary (value, bucket) table mapping each distinct non-null value
730
+ * of `config.field` in `population` to the start of its calendar interval,
731
+ * or to its cyclic slot, computed with the core calendar. */
732
+ async calendarMapping(population, builder, schema, config, tables, signal) {
733
+ const source = builder.field(config.field, false), cycle = isMetricCycle(config.interval) ? config.interval : void 0;
734
+ const dates = await this.run(
735
+ builder.statement(
736
+ `SELECT DISTINCT CAST(${source} AS VARCHAR) AS value FROM ${population} r WHERE ${source} IS NOT NULL`
737
+ ),
738
+ signal
739
+ );
740
+ const mapping = this.temp(tables);
741
+ await this.sql(
742
+ `CREATE TEMP TABLE ${quoteIdentifier(mapping)} (value TIMESTAMPTZ, bucket ${cycle ? "INTEGER" : "TIMESTAMPTZ"})`,
743
+ [],
744
+ signal
745
+ );
746
+ for (let i = 0; i < dates.length; i += 250) {
747
+ const args = [];
748
+ const values = dates.slice(i, i + 250).map((row) => {
749
+ const value = /^\d{4}-\d{2}-\d{2}$/.test(String(row.value)) ? String(row.value) : this.formatRow({ [config.field]: row.value }, schema)[config.field];
750
+ const floor = metricDateFloor(
751
+ metricDateTime(value, config.timeZone),
752
+ config.interval,
753
+ config.timeZone
754
+ );
755
+ args.push(
756
+ value,
757
+ cycle ? metricCycleSlot(floor, cycle, config.timeZone) : new Date(floor).toISOString()
758
+ );
759
+ return `(CAST($${args.length - 1} AS TIMESTAMPTZ), CAST($${args.length} AS ${cycle ? "INTEGER" : "TIMESTAMPTZ"}))`;
760
+ });
761
+ if (values.length)
762
+ await this.sql(
763
+ `INSERT INTO ${quoteIdentifier(mapping)} VALUES ${values.join(", ")}`,
764
+ args,
765
+ signal
766
+ );
767
+ }
768
+ return mapping;
769
+ }
696
770
  async metric(relation, schema, query, clause, now, tables, signal) {
697
771
  if (clause.distribution && !clause.display)
698
772
  clause = { ...clause, display: { kind: clause.distribution.kind } };
@@ -704,44 +778,16 @@ var DuckDBBackend = class {
704
778
  let population = `(SELECT * FROM ${quoteIdentifier(relation)} WHERE ${where} ${window})`;
705
779
  if (clause.where?.length)
706
780
  population = `(SELECT * FROM ${population} r WHERE ${builder.where(clause.where)})`;
707
- let dateMapping;
708
781
  if (clause.dateGrouping) {
709
- const config = clause.dateGrouping, source = builder.field(config.field, false);
710
- const dates = await this.run(
711
- builder.statement(
712
- `SELECT DISTINCT CAST(${source} AS VARCHAR) AS value FROM ${population} r WHERE ${source} IS NOT NULL`
713
- ),
714
- signal
715
- );
716
- dateMapping = this.temp(tables);
717
- await this.sql(
718
- `CREATE TEMP TABLE ${quoteIdentifier(dateMapping)} (value TIMESTAMPTZ, bucket TIMESTAMPTZ)`,
719
- [],
782
+ const config = clause.dateGrouping;
783
+ const dateMapping = await this.calendarMapping(
784
+ population,
785
+ builder,
786
+ schema,
787
+ config,
788
+ tables,
720
789
  signal
721
790
  );
722
- for (let i = 0; i < dates.length; i += 250) {
723
- const args = [];
724
- const values = dates.slice(i, i + 250).map((row) => {
725
- const value = /^\d{4}-\d{2}-\d{2}$/.test(String(row.value)) ? String(row.value) : this.formatRow({ [config.field]: row.value }, schema)[config.field];
726
- args.push(
727
- value,
728
- new Date(
729
- metricDateFloor(
730
- metricDateTime(value, config.timeZone),
731
- config.interval,
732
- config.timeZone
733
- )
734
- ).toISOString()
735
- );
736
- return `(CAST($${args.length - 1} AS TIMESTAMPTZ), CAST($${args.length} AS TIMESTAMPTZ))`;
737
- });
738
- if (values.length)
739
- await this.sql(
740
- `INSERT INTO ${quoteIdentifier(dateMapping)} VALUES ${values.join(", ")}`,
741
- args,
742
- signal
743
- );
744
- }
745
791
  population = `(SELECT r.* EXCLUDE (${quoteIdentifier(config.field)}), m.bucket AS ${quoteIdentifier(config.field)} FROM ${population} r LEFT JOIN ${quoteIdentifier(dateMapping)} m ON CAST(r.${quoteIdentifier(config.field)} AS TIMESTAMPTZ) = m.value)`;
746
792
  }
747
793
  const keys = clause.groupBy.map((name) => builder.field(name, false)), groups = keys.length ? `GROUP BY ${keys.join(", ")}` : "";
@@ -758,6 +804,11 @@ var DuckDBBackend = class {
758
804
  projections.push(
759
805
  `${builder.expression(clause.expressionY ?? "COUNT()", true).sql} AS y`
760
806
  );
807
+ const minMeasure = metricMinCountMeasure(clause);
808
+ if (minMeasure)
809
+ projections.push(
810
+ `${builder.expression(metricExpression({ id: "", groupBy: [], ...minMeasure }), true).sql} AS min_measure`
811
+ );
761
812
  const rows = await this.run(
762
813
  builder.statement(
763
814
  `SELECT ${projections.join(", ")} FROM ${population} r ${groups} LIMIT ${this.capabilities.maxGroups + 1}`
@@ -776,11 +827,14 @@ var DuckDBBackend = class {
776
827
  rows.flatMap((row) => row.samples ?? []),
777
828
  distribution.bins ?? 10
778
829
  ) : [];
830
+ const measures = /* @__PURE__ */ new Map();
779
831
  const buckets = rows.map((row) => {
780
832
  const samples = row.samples ?? [];
781
- return {
833
+ const bucket = {
782
834
  keys: clause.groupBy.map((name, index) => {
783
835
  const value = row[`g${index}`] ?? null;
836
+ if (index === 0 && isMetricCycle(clause.dateGrouping?.interval))
837
+ return value === null ? null : Number(value);
784
838
  return schema.fields.find((field) => field.name === name)?.type === "datetime" && value !== null ? this.formatRow({ [name]: value }, schema)[name] : value;
785
839
  }),
786
840
  count: row.count,
@@ -799,10 +853,12 @@ var DuckDBBackend = class {
799
853
  }
800
854
  } : {}
801
855
  };
856
+ if (minMeasure) measures.set(bucket, { value: row.min_measure });
857
+ return bucket;
802
858
  });
803
859
  if (clause.dateGrouping?.includeEmpty) {
804
- const config = clause.dateGrouping, observed = buckets.filter((bucket) => bucket.keys[0] !== null).map((bucket) => metricDateTime(bucket.keys[0]));
805
- const range = metricDateRange(
860
+ const config = clause.dateGrouping, cycle = isMetricCycle(config.interval) ? config.interval : void 0, observed = cycle ? [] : buckets.filter((bucket) => bucket.keys[0] !== null).map((bucket) => metricDateTime(bucket.keys[0]));
861
+ const range = cycle ? void 0 : metricDateRange(
806
862
  config,
807
863
  {
808
864
  ...query,
@@ -822,28 +878,31 @@ var DuckDBBackend = class {
822
878
  const existing = new Set(
823
879
  buckets.map((bucket) => JSON.stringify(bucket.keys))
824
880
  );
881
+ const slots = cycle ? metricCycleSlots(cycle) : [];
825
882
  if (range)
826
- for (let time = range[0]; time <= range[1]; time = metricDateNext(time, config.interval, config.timeZone)) {
827
- for (const tuple of series.values()) {
828
- const values = [new Date(time).toISOString(), ...tuple];
829
- if (!existing.has(JSON.stringify(values))) {
830
- if (buckets.length >= this.capabilities.maxGroups)
831
- throw Error("DuckDB calendar group budget exceeded.");
832
- buckets.push({
833
- keys: values,
834
- count: 0,
835
- value: !clause.expression && ["count", "count_distinct", "sum"].includes(clause.op) || /^(COUNT|COUNT_DISTINCT|SUM)\([^)]*\)$/.test(
836
- metricExpression(clause)
837
- ) ? 0 : null
838
- });
839
- }
883
+ for (let time = range[0]; time <= range[1]; time = metricDateNext(time, config.interval, config.timeZone))
884
+ slots.push(new Date(time).toISOString());
885
+ for (const slot of slots)
886
+ for (const tuple of series.values()) {
887
+ const values = [slot, ...tuple];
888
+ if (!existing.has(JSON.stringify(values))) {
889
+ if (buckets.length >= this.capabilities.maxGroups)
890
+ throw Error("DuckDB calendar group budget exceeded.");
891
+ buckets.push({
892
+ keys: values,
893
+ count: 0,
894
+ value: !clause.expression && ["count", "count_distinct", "sum"].includes(clause.op) || /^(COUNT|COUNT_DISTINCT|SUM)\([^)]*\)$/.test(
895
+ metricExpression(clause)
896
+ ) ? 0 : null
897
+ });
840
898
  }
841
899
  }
842
900
  }
843
901
  let hiddenGroups;
844
- if (clause.minCount !== void 0) {
902
+ const min = metricMinCount(clause);
903
+ if (min !== void 0) {
845
904
  const kept = buckets.filter(
846
- (bucket) => bucket.count === 0 || bucket.count >= clause.minCount
905
+ (bucket) => metricMinCountKeeps(min, bucket.count, measures.get(bucket))
847
906
  );
848
907
  hiddenGroups = buckets.length - kept.length;
849
908
  buckets.splice(0, buckets.length, ...kept);
@@ -884,6 +943,7 @@ var DuckDBBackend = class {
884
943
  computedFields: this.computed.size > 0,
885
944
  filters: true,
886
945
  minCount: true,
946
+ minCountMeasures: true,
887
947
  profile: DUCKDB_PROFILE,
888
948
  maxGroups: this.capabilities.maxGroups
889
949
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/sql.ts","../src/backend.ts","../src/wasm.ts","../src/schema.ts"],"sourcesContent":["import {\n coerceValue,\n compileFormula,\n compileMetric,\n isFilterable,\n isSortable,\n isSelectable,\n opsForField,\n type FieldDef,\n type FieldSchema,\n type FormulaNode,\n type FormulaPlan,\n type WhereTerm,\n type OrderByClause,\n type ServerQuery,\n} from \"@pythia-software/query-table-core\";\n\nexport interface DuckDBStatement {\n sql: string;\n args: unknown[];\n}\n/** Identifiers come only from the host catalogue, and are always quoted. */\nexport function quoteIdentifier(value: string): string {\n if (!value || value.includes(\"\\0\")) throw Error(\"Invalid DuckDB identifier.\");\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n}\nexport function quoteRelation(value: string): string {\n return value.split(\".\").map(quoteIdentifier).join(\".\");\n}\nconst aggregates = new Set([\n \"COUNT\",\n \"COUNT_DISTINCT\",\n \"SUM\",\n \"AVG\",\n \"MIN\",\n \"MAX\",\n \"MEDIAN\",\n]);\nconst safeNumber = (value: string) =>\n `(CASE WHEN ${value} IS NULL OR (isfinite(${value}) AND abs(${value}) <= 9007199254740991) THEN ${value} ELSE error('Query Table numeric precision exceeded') END)`;\n\nexport class SQLBuilder {\n readonly args: unknown[] = [];\n constructor(\n readonly schema: FieldSchema,\n readonly now = Date.now(),\n readonly bindings: Record<string, string> = {},\n ) {}\n bind(value: unknown): string {\n this.args.push(value);\n return `$${this.args.length}`;\n }\n statement(sql: string): DuckDBStatement {\n if (sql.length > 262144 || this.args.length > 10000)\n throw Error(\"DuckDB statement budget exceeded.\");\n return { sql, args: [...this.args] };\n }\n definition(name: string): FieldDef {\n const field = this.schema.fields.find((field) => field.name === name);\n if (!field || field.source.kind !== \"backend\")\n throw Error(`Unavailable DuckDB field: ${name}.`);\n return field;\n }\n field(name: string, normalize = true): string {\n const field = this.definition(name),\n value =\n (Object.prototype.hasOwnProperty.call(this.bindings, name)\n ? this.bindings[name]\n : undefined) ??\n quoteIdentifier(\n field.source.kind === \"backend\" ? (field.source.path ?? name) : name,\n );\n if (!normalize) return value;\n if (field.type === \"text\" || field.type === \"enum\")\n return `NULLIF(CAST(${value} AS VARCHAR), '')`;\n if (field.type === \"datetime\") return `CAST(${value} AS TIMESTAMPTZ)`;\n return value;\n }\n where(terms: WhereTerm[]): string {\n if (terms.length > 100)\n throw Error(\"At most 100 filter terms are allowed.\");\n let count = 0;\n return terms.length\n ? terms\n .map((term) => {\n const clauses = \"any\" in term ? term.any : [term];\n if (!clauses.length || (count += clauses.length) > 100)\n throw Error(\"Invalid filter predicate budget.\");\n return `(${clauses\n .map((clause) => {\n const field = this.definition(clause.field),\n raw = this.field(field.name),\n op = clause.op;\n if (!isFilterable(field) || !opsForField(field).includes(op))\n throw Error(`Unsupported filter on ${field.name}: ${op}.`);\n const value =\n field.type === \"textarray\"\n ? `CASE WHEN len(${raw}) > 0 THEN ${raw} END`\n : raw;\n let sql: string;\n if (op === \"is_null\" || op === \"is_not_null\")\n sql = `${value} IS ${op === \"is_null\" ? \"\" : \"NOT \"}NULL`;\n else {\n const typed = coerceValue(field.type, clause.value, this.now);\n if (typeof typed === \"number\" && !Number.isFinite(typed))\n throw Error(\"Filter operands must be finite.\");\n const param = this.bind(\n field.type === \"datetime\"\n ? new Date(typed as number).toISOString()\n : typed,\n );\n const rhs =\n field.type === \"datetime\"\n ? `CAST(${param} AS TIMESTAMPTZ)`\n : param;\n if ([\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\"].includes(op))\n sql = `${value} ${op} ${rhs}`;\n else if (\n [\"contains\", \"starts_with\", \"ends_with\"].includes(op)\n )\n sql = `${op}(lower(${value}), lower(${param}))`;\n else if (op === \"includes\")\n sql = field.filter?.arrayCaseSensitive\n ? `list_contains(${value}, ${param})`\n : `list_contains(list_transform(${value}, x -> lower(x)), lower(${param}))`;\n else if (op.startsWith(\"length_\"))\n sql = `length(${value}) ${op === \"length_gt\" ? \">\" : op === \"length_lt\" ? \"<\" : \"=\"} CAST(${param} AS DOUBLE)`;\n else if (\n op === \"matches_regex\" ||\n op === \"not_matches_regex\"\n ) {\n if (clause.value.length > 2000)\n throw Error(\"Regex exceeds 2,000 characters.\");\n sql = `${op === \"not_matches_regex\" ? \"NOT \" : \"\"}regexp_matches(${value}, ${param})`;\n } else throw Error(`Unsupported DuckDB operator: ${op}.`);\n }\n return clause.negated ? `NOT (${sql})` : sql;\n })\n .join(\" OR \")})`;\n })\n .join(\" AND \")\n : \"TRUE\";\n }\n order(terms: OrderByClause[], identity = true): string {\n if (terms.length > 20) throw Error(\"At most 20 sort fields are allowed.\");\n const output = terms.map((term) => {\n const field = this.definition(term.field);\n if (!isSortable(field) && field.name !== this.schema.idField)\n throw Error(`Field ${field.name} is not sortable.`);\n if (\n ![\"asc\", \"desc\"].includes(term.dir) ||\n (term.nulls && ![\"first\", \"last\"].includes(term.nulls))\n )\n throw Error(\"Invalid ordering.\");\n let value = this.field(field.name);\n if (term.extract) {\n if (field.type !== \"text\" || term.extract.regex.length > 2000)\n throw Error(\"Invalid regex extraction.\");\n const pattern = this.bind(term.extract.regex);\n // DuckDB/RE2 extraction uses the first capture, or the full match.\n const capture = /(^|[^\\\\])\\((?!\\?)/.test(term.extract.regex) ? 1 : 0;\n value = `CASE WHEN regexp_matches(${value}, ${pattern}) THEN regexp_extract(${value}, ${pattern}, ${capture}) END`;\n }\n return `${value} ${term.dir.toUpperCase()} NULLS ${(term.nulls ?? \"last\").toUpperCase()}`;\n });\n if (identity && !terms.some((term) => term.field === this.schema.idField))\n output.push(`${this.field(this.schema.idField)} ASC NULLS LAST`);\n return output.length ? `ORDER BY ${output.join(\", \")}` : \"\";\n }\n expression(\n source: string,\n aggregate = false,\n ): { sql: string; plan: FormulaPlan } {\n const plan = aggregate\n ? compileMetric(source, this.schema)\n : compileFormula(source, this.schema.fields);\n return { sql: this.node(plan.ast), plan };\n }\n node(node: FormulaNode): string {\n const sql = this.nodeSQL(node);\n if (sql.length > 131072)\n throw Error(\"DuckDB expression SQL budget exceeded.\");\n return sql;\n }\n private nodeSQL(node: FormulaNode): string {\n if (node.kind === \"literal\")\n return node.value === null ? \"NULL\" : this.bind(node.value);\n if (node.kind === \"field\") return this.field(node.name, false);\n const name = node.name,\n vs = node.args.map((arg) => this.node(arg)),\n a = vs[0]!,\n b = vs[1]!,\n c = vs[2]!;\n if (aggregates.has(name)) {\n if (name === \"COUNT\") return `CAST(COUNT(${a ?? \"*\"}) AS DOUBLE)`;\n if (name === \"COUNT_DISTINCT\")\n return `CAST(COUNT(DISTINCT ${a}) AS DOUBLE)`;\n const sql = `${name}(${a})`;\n return [\"SUM\", \"AVG\", \"MEDIAN\"].includes(name)\n ? safeNumber(\n `CAST(${name === \"SUM\" ? `COALESCE(${sql}, 0)` : sql} AS DOUBLE)`,\n )\n : sql;\n }\n if (name.startsWith(\"op:\")) {\n const op = name.slice(3);\n if (op === \"IN\") return `(${a} IN (${vs.slice(1).join(\", \")}))`;\n if (op === \"BETWEEN\") return `(${a} BETWEEN ${b} AND ${c})`;\n if ([\"/\", \"%\"].includes(op))\n return safeNumber(\n `(CASE WHEN ${b} = 0 THEN error('Division by zero') ELSE ${a} ${op} ${b} END)`,\n );\n return [\"+\", \"-\", \"*\"].includes(op)\n ? safeNumber(`(${a} ${op} ${b})`)\n : `(${a} ${op} ${b})`;\n }\n if (name.startsWith(\"unary:\")) return `(${name.slice(6)} ${a})`;\n if (name === \"IF\") return `CASE WHEN ${a} THEN ${b} ELSE ${c} END`;\n if (name === \"IFS\")\n return `CASE ${vs\n .slice(0, -1)\n .filter((_, i) => i % 2 === 0)\n .map((v, i) => `WHEN ${v} THEN ${vs[2 * i + 1]}`)\n .join(\" \")} ELSE ${vs[vs.length - 1]} END`;\n if (name === \"SWITCH\")\n return `CASE ${vs\n .slice(1, -1)\n .filter((_, i) => i % 2 === 0)\n .map(\n (v, i) => `WHEN ${a} IS NOT DISTINCT FROM ${v} THEN ${vs[2 * i + 2]}`,\n )\n .join(\" \")} ELSE ${vs[vs.length - 1]} END`;\n if (name === \"IS_NULL\") return `(${a} IS NULL)`;\n if (name === \"IS_EMPTY\") {\n const input = node.args[0]!;\n const array =\n (input.kind === \"field\" && input.valueType === \"textarray\") ||\n (input.kind === \"call\" &&\n [\"SPLIT\", \"ARRAY_UNIQUE\", \"ARRAY_SORT\"].includes(input.name));\n return `(${a} IS NULL OR len(${array ? a : `CAST(${a} AS VARCHAR)`}) = 0)`;\n }\n if (name === \"COALESCE\" || name === \"NULLIF\")\n return `${name}(${vs.join(\", \")})`;\n if (name === \"IFERROR\")\n throw Error(\"IFERROR is not available in the qt-duckdb-v1 SQL profile.\");\n if (name === \"ROUND\") {\n const scale = `power(10, ${b ?? \"0\"})`;\n return safeNumber(`(floor(${a} * ${scale} + 0.5) / ${scale})`);\n }\n if (name === \"CLAMP\")\n return `CASE WHEN ${a} IS NULL OR ${b} IS NULL OR ${c} IS NULL THEN NULL ELSE greatest(${b}, least(${c}, ${a})) END`;\n if (name === \"LEAST\" || name === \"GREATEST\" || name === \"CONCAT\")\n return `CASE WHEN ${vs.map((v) => `${v} IS NULL`).join(\" OR \")} THEN NULL ELSE ${name}(${vs.join(\", \")}) END`;\n if (name === \"CONCAT_WS\")\n return `CASE WHEN ${a} IS NULL THEN NULL ELSE concat_ws(${vs.join(\", \")}) END`;\n if ([\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].includes(name))\n return `${name.toLowerCase()}(CASE WHEN ${c ?? \"FALSE\"} THEN lower(${a}) ELSE ${a} END, CASE WHEN ${c ?? \"FALSE\"} THEN lower(${b}) ELSE ${b} END)`;\n if (name === \"TO_NUMBER\") return safeNumber(`CAST(${a} AS DOUBLE)`);\n if (name === \"TO_TEXT\") return `CAST(${a} AS VARCHAR)`;\n if (name === \"URL_ENCODE\") return `url_encode(${a})`;\n if (name === \"TO_BOOLEAN\") return `CAST(${a} AS BOOLEAN)`;\n if (name === \"TO_DATETIME\") return `CAST(${a} AS TIMESTAMPTZ)`;\n if (name === \"SPLIT\") return `string_split(${a}, ${b})`;\n if (name === \"JOIN\") return `array_to_string(${a}, ${b})`;\n if (name === \"ARRAY_LENGTH\") return `len(${a})`;\n if (name === \"ARRAY_CONTAINS\") return `list_contains(${a}, ${b})`;\n if (name === \"ARRAY_GET\")\n return `CASE WHEN ${b} < 0 THEN error('Array index must be nonnegative') ELSE list_extract(${a}, CAST(${b} + 1 AS BIGINT)) END`;\n if (name === \"ARRAY_SORT\") return `list_sort(${a})`;\n if (name === \"ARRAY_UNIQUE\")\n return `list_filter(${a}, (x, i) -> list_position(${a}, x) = i)`;\n if (name === \"WEEKDAY\")\n return `extract(isodow FROM CAST(${a} AS TIMESTAMPTZ))`;\n if ([\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\"].includes(name))\n return `extract(${name.toLowerCase()} FROM CAST(${a} AS TIMESTAMPTZ))`;\n if (name === \"DATE_TRUNC\")\n return `date_trunc(${a}, CAST(${b} AS TIMESTAMPTZ))`;\n if (\n name === \"DATE_DIFF\" ||\n name === \"DATE_ADD\" ||\n name === \"FORMAT_DATE\" ||\n name.startsWith(\"REGEX_\")\n )\n throw Error(`${name} is not available in the qt-duckdb-v1 SQL profile.`);\n if (\n [\"LEFT\", \"RIGHT\", \"SUBSTRING\", \"LPAD\", \"RPAD\", \"SPLIT_PART\"].includes(\n name,\n )\n ) {\n const args = [...vs];\n const indices =\n name === \"SUBSTRING\" ? [1, 2] : name === \"SPLIT_PART\" ? [2] : [1];\n for (const index of indices)\n if (args[index] !== undefined)\n args[index] = `CAST(${args[index]} AS BIGINT)`;\n return `${name}(${args.join(\", \")})`;\n }\n if (\n [\n \"LENGTH\",\n \"LOWER\",\n \"UPPER\",\n \"TRIM\",\n \"LTRIM\",\n \"RTRIM\",\n \"REPLACE\",\n \"ABS\",\n \"FLOOR\",\n \"CEIL\",\n \"TRUNC\",\n \"POWER\",\n \"SQRT\",\n ].includes(name)\n )\n return `${name}(${vs.join(\", \")})`;\n throw Error(`Unsupported DuckDB function: ${name}.`);\n }\n}\n\nexport function compileDuckDBRows(\n query: ServerQuery,\n schema: FieldSchema,\n relation: string,\n now = Date.now(),\n): DuckDBStatement {\n const sql = new SQLBuilder(schema, now);\n if (\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1 ||\n query.limit > 10000 ||\n !Number.isSafeInteger(query.offset) ||\n query.offset < 0\n )\n throw Error(\"Invalid result window.\");\n const select = [...new Set([schema.idField, ...query.select])].map((name) => {\n const field = sql.definition(name);\n if (!isSelectable(field) && name !== schema.idField)\n throw Error(`Field ${name} is not selectable.`);\n return `${sql.field(name, false)} AS ${quoteIdentifier(name)}`;\n });\n const where = sql.where(query.where),\n order = sql.order(query.orderBy);\n return sql.statement(\n `SELECT ${select.join(\", \")} FROM ${quoteRelation(relation)} WHERE ${where} ${order} LIMIT ${sql.bind(query.limit)} OFFSET ${sql.bind(query.offset)}`,\n );\n}\n","import {\n compileFormula,\n createGroupingModel,\n GROUP_ID_FIELD,\n metricExpression,\n validateMetric,\n isSelectable,\n isFilterable,\n boxSummary,\n histogramEdges,\n histogramCounts,\n compareMetricValues,\n metricDateFloor,\n metricDateTime,\n metricDateNext,\n metricDateRange,\n type AggregationClause,\n type AggregationResult,\n type AggregationResultEntry,\n type ComputedColumn,\n type ComputedExecution,\n type FieldSchema,\n type FormulaPlan,\n type MetricQuery,\n type QueryCapabilitiesV3,\n type QueryRequestV3,\n type QueryResultV3,\n type ServerQuery,\n type Transport,\n type MetricSort,\n type MetricValue,\n type QueryState,\n} from \"@pythia-software/query-table-core\";\nimport {\n SQLBuilder,\n quoteIdentifier as id,\n quoteRelation,\n type DuckDBStatement,\n} from \"./sql\";\n\nexport const DUCKDB_PROFILE = \"qt-duckdb-v1\";\nexport type DuckDBRow = Record<string, unknown>;\n/** One exclusive connection, with bound parameters; no driver runtime dependency. */\nexport interface DuckDBConnection {\n query(sql: string, args: unknown[]): Promise<DuckDBRow[]>;\n interrupt?(): void | Promise<void>;\n}\nexport interface DuckDBOptions {\n connection: DuckDBConnection;\n schema: FieldSchema;\n relation: string;\n /** Trusted SQL expressions, keyed by the host's field names. Never request SQL. */\n bindings?: Record<string, string>;\n computedColumns?: readonly ComputedColumn[];\n snapshot?: string;\n maxRows?: number;\n maxGroups?: number;\n maxPopulation?: number;\n maxSamples?: number;\n maxStagingBytes?: number;\n}\nfunction abort(signal?: AbortSignal): void {\n if (signal?.aborted)\n throw new DOMException(\"DuckDB query cancelled.\", \"AbortError\");\n}\n/** Normalize both Arrow and Node values at the transport boundary. */\nexport function normalizeDuckDBValue(value: unknown): unknown {\n if (typeof value === \"bigint\") {\n const numeric = Number(value);\n if (!Number.isSafeInteger(numeric))\n throw Error(\"DuckDB integer exceeds JavaScript safe precision.\");\n return numeric;\n }\n if (value instanceof Date) return value.toISOString();\n if (\n typeof value === \"number\" &&\n (!Number.isFinite(value) || Math.abs(value) > Number.MAX_SAFE_INTEGER)\n )\n throw Error(\"DuckDB number exceeds finite safe precision.\");\n if (Array.isArray(value)) return value.map(normalizeDuckDBValue);\n if (value && typeof value === \"object\") {\n // Arrow vectors expose toArray(); StructRow exposes toJSON().\n if (\"toArray\" in value && typeof value.toArray === \"function\")\n return Array.from(value.toArray()).map(normalizeDuckDBValue);\n if (\"toJSON\" in value && typeof value.toJSON === \"function\")\n return normalizeDuckDBValue(value.toJSON());\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [\n key,\n normalizeDuckDBValue(item),\n ]),\n );\n }\n return value;\n}\nfunction positive(\n value: number | undefined,\n fallback: number,\n maximum: number,\n): number {\n const out = value ?? fallback;\n if (!Number.isSafeInteger(out) || out < 1 || out > maximum)\n throw Error(\"Invalid DuckDB resource budget.\");\n return out;\n}\n\nexport class DuckDBBackend {\n readonly schema: FieldSchema;\n readonly execution: ComputedExecution;\n readonly capabilities: QueryCapabilitiesV3;\n readonly maxSamples: number;\n readonly maxStagingBytes: number;\n private queue: Promise<unknown> = Promise.resolve();\n private sequence = 0;\n private readonly computed = new Map<string, FormulaPlan>();\n constructor(readonly options: DuckDBOptions) {\n const fields = options.schema.fields\n .filter((field) => field.source.kind === \"backend\")\n .map((field) => ({\n ...field,\n source: { ...field.source, kind: \"backend\" as const, path: field.name },\n }));\n if (\n !fields.some((field) => field.name === options.schema.idField) ||\n new Set(fields.map((field) => field.name)).size !== fields.length\n )\n throw Error(\n \"DuckDB needs a unique field catalogue and a bound identity.\",\n );\n quoteRelation(options.relation);\n this.schema = { ...options.schema, fields };\n const definitions = new Map(\n (options.computedColumns ?? []).map((column) => [\n `@computed/${column.id}`,\n column,\n ]),\n );\n const visiting = new Set<string>();\n const resolve = (name: string): FormulaPlan | undefined => {\n if (this.computed.has(name)) return this.computed.get(name);\n const definition = definitions.get(name);\n if (!definition) return undefined;\n if (visiting.has(name)) throw Error(\"Computed definition cycle.\");\n visiting.add(name);\n const plan = compileFormula(\n definition.expression.source,\n fields,\n resolve,\n );\n // Reject unsupported SQL at negotiation, before advertising capabilities.\n new SQLBuilder(this.schema).node(plan.ast);\n visiting.delete(name);\n this.computed.set(name, plan);\n return plan;\n };\n for (const name of definitions.keys()) {\n const plan = resolve(name)!;\n fields.push({\n name,\n label: definitions.get(name)!.label,\n type: plan.type === \"null\" ? \"text\" : plan.type,\n source: { kind: \"backend\", path: name },\n filter: { enabled: true },\n sort: { enabled: true },\n aggregate: { measure: true, groupable: plan.type !== \"textarray\" },\n });\n }\n this.execution = {\n profile: DUCKDB_PROFILE,\n planToken: `duckdb:${JSON.stringify([...definitions.values()].map((column) => [column.id, column.revision]))}`,\n resolvedRevisions: Object.fromEntries(\n [...definitions.values()].map((column) => [column.id, column.revision]),\n ),\n fields: Object.fromEntries(\n fields\n .filter((field) => definitions.has(field.name))\n .map((field) => [\n field.name,\n {\n type: field.type,\n select: true,\n filter: true,\n sort: true,\n measure: true,\n group: field.type !== \"textarray\",\n },\n ]),\n ),\n ...(options.snapshot !== undefined ? { snapshot: options.snapshot } : {}),\n };\n this.capabilities = {\n version: 3,\n profile: DUCKDB_PROFILE,\n groupedRows: true,\n calendarGrouping: true,\n computedSourceFilters: definitions.size > 0,\n regex: true,\n regexSourceFilters: true,\n regexAggregateExpressions: false,\n metricFilters: true,\n metricMinCount: true,\n maxRows: positive(options.maxRows, 10000, 10000),\n maxGroups: positive(options.maxGroups, 10000, 10000),\n maxPopulation: positive(options.maxPopulation, 250000, 10000000),\n };\n this.maxSamples = positive(options.maxSamples, 100000, 1000000);\n this.maxStagingBytes = positive(\n options.maxStagingBytes,\n 64 * 1024 * 1024,\n 1024 * 1024 * 1024,\n );\n }\n private serial<T>(work: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n const next = this.queue.then(() => {\n abort(signal);\n return work();\n });\n this.queue = next.catch(() => {});\n return next;\n }\n /** Wait before closing an owned driver connection. */\n async drain(): Promise<void> {\n await this.queue;\n }\n private async run(\n statement: DuckDBStatement,\n signal?: AbortSignal,\n ): Promise<DuckDBRow[]> {\n abort(signal);\n const cancel = () => {\n void this.options.connection.interrupt?.();\n };\n signal?.addEventListener(\"abort\", cancel, { once: true });\n try {\n const rows = await this.options.connection.query(\n statement.sql,\n statement.args,\n );\n abort(signal);\n return rows.map((row) => normalizeDuckDBValue(row) as DuckDBRow);\n } finally {\n signal?.removeEventListener(\"abort\", cancel);\n }\n }\n private sql(statement: string, args: unknown[] = [], signal?: AbortSignal) {\n return this.run({ sql: statement, args }, signal);\n }\n private window(query: ServerQuery): void {\n if (\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1 ||\n query.limit > this.capabilities.maxRows ||\n !Number.isSafeInteger(query.offset) ||\n query.offset < 0\n )\n throw Error(\"Invalid DuckDB result window.\");\n }\n private builder(schema = this.schema, now = Date.now()) {\n return new SQLBuilder(schema, now);\n }\n private projectedSource(now: number): DuckDBStatement {\n const bindings = Object.fromEntries(\n this.schema.fields\n .filter((field) => !this.computed.has(field.name))\n .map((field) => [\n field.name,\n (this.options.bindings &&\n Object.prototype.hasOwnProperty.call(\n this.options.bindings,\n field.name,\n )\n ? this.options.bindings[field.name]\n : undefined) ??\n id(\n (() => {\n const original = this.options.schema.fields.find(\n (item) => item.name === field.name,\n );\n return original?.source.kind === \"backend\"\n ? (original.source.path ?? field.name)\n : field.name;\n })(),\n ),\n ]),\n );\n const builder = new SQLBuilder(this.schema, now, bindings);\n const projections = this.schema.fields.map((field) => {\n const plan = this.computed.get(field.name),\n raw = plan ? builder.node(plan.ast) : bindings[field.name]!;\n return `${raw} AS ${id(field.name)}`;\n });\n return builder.statement(\n `SELECT ${projections.join(\", \")} FROM ${quoteRelation(this.options.relation)} AS r`,\n );\n }\n private async transaction<T>(\n work: (tables: string[]) => Promise<T>,\n signal?: AbortSignal,\n ): Promise<T> {\n return this.serial(async () => {\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n const tables: string[] = [];\n try {\n const result = await work(tables);\n for (const table of tables.reverse())\n await this.sql(`DROP TABLE ${id(table)}`, [], signal);\n await this.sql(\"COMMIT\", [], signal);\n return result;\n } catch (error) {\n await this.sql(\"ROLLBACK\").catch(() => {});\n // Metrics commit staged relations before isolating each clause, so a\n // rollback alone may not remove them.\n for (const table of tables.reverse())\n await this.sql(`DROP TABLE IF EXISTS ${id(table)}`).catch(() => {});\n abort(signal);\n throw error;\n }\n }, signal);\n }\n private temp(tables: string[]): string {\n const name = `qt_duckdb_${++this.sequence}`;\n tables.push(name);\n return name;\n }\n private async stage(\n source: ServerQuery,\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<{ name: string; count: number }> {\n const projection = this.projectedSource(now),\n builder = this.builder(this.schema, now);\n builder.args.push(...projection.args);\n const where = builder.where(source.where),\n name = this.temp(tables);\n const population = `(${projection.sql}) r WHERE ${where}`;\n const [{ n, bytes }] = (await this.run(\n builder.statement(\n `SELECT COUNT(*) AS n, COALESCE(SUM(octet_length(encode(CAST(to_json(r) AS VARCHAR)))),0) AS bytes FROM ${population}`,\n ),\n signal,\n )) as [{ n: number; bytes: number }];\n if (n > this.capabilities.maxPopulation || bytes > this.maxStagingBytes)\n throw Error(\"DuckDB source population or staging byte budget exceeded.\");\n await this.run(\n builder.statement(\n `CREATE TEMP TABLE ${id(name)} AS SELECT * FROM ${population}`,\n ),\n signal,\n );\n const [{ invalid }] = (await this.sql(\n `SELECT COUNT(*) - COUNT(DISTINCT ${id(this.schema.idField)}) AS invalid FROM ${id(name)}`,\n [],\n signal,\n )) as [{ invalid: number }];\n if (invalid !== 0)\n throw Error(\"DuckDB source identity must be unique and non-null.\");\n return { name, count: n };\n }\n private async page(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n now: number,\n signal?: AbortSignal,\n ) {\n this.window(query);\n const builder = this.builder(schema, now),\n where = builder.where(query.where);\n const [{ total }] = (await this.run(\n builder.statement(\n `SELECT COUNT(*) AS total FROM ${id(relation)} WHERE ${where}`,\n ),\n signal,\n )) as [{ total: number }];\n const order = builder.order(query.orderBy),\n names = [...new Set([schema.idField, ...query.select])];\n names.forEach((name) => {\n if (!isSelectable(builder.definition(name)) && name !== schema.idField)\n throw Error(`Field ${name} is not selectable.`);\n });\n const rows = await this.run(\n builder.statement(\n `SELECT ${names.map(id).join(\", \")} FROM ${id(relation)} WHERE ${where} ${order} LIMIT ${builder.bind(query.limit)} OFFSET ${builder.bind(query.offset)}`,\n ),\n signal,\n );\n return { rows: rows.map((row) => this.formatRow(row, schema)), total };\n }\n private formatRow(row: DuckDBRow, schema: FieldSchema): DuckDBRow {\n return Object.fromEntries(\n Object.entries(row).map(([name, value]) => {\n const field = schema.fields.find((field) => field.name === name);\n if (value != null && field?.type === \"datetime\") {\n // DuckDB's textual native TIMESTAMP has no suffix; our session profile\n // interprets that storage as UTC, independently of the JS host timezone.\n const text = String(value);\n const canonical =\n /^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?$/.test(text)\n ? `${text.replace(\" \", \"T\")}Z`\n : text;\n const date =\n typeof value === \"number\" ? new Date(value) : new Date(canonical);\n if (!Number.isFinite(date.getTime()))\n throw Error(`Invalid datetime returned for ${name}.`);\n value = date.toISOString();\n }\n return [name, value];\n }),\n );\n }\n private validateRequest(request: QueryRequestV3): void {\n if (\n request.version !== 3 ||\n request.profile !== DUCKDB_PROFILE ||\n request.diagnostics.length\n )\n throw Error(\"Invalid DuckDB execution request or profile.\");\n if (\n !Number.isSafeInteger(request.now) ||\n Math.abs(request.now) > 8640000000000000\n )\n throw Error(\"Invalid query clock.\");\n if (\n (request.planToken ?? \"\") !==\n (Object.keys(this.execution.fields).length\n ? this.execution.planToken\n : \"\") &&\n request.planToken !== this.execution.planToken\n )\n throw Error(\"DuckDB execution handshake changed.\");\n if ((request.snapshot ?? \"\") !== (this.options.snapshot ?? \"\"))\n throw Error(\"DuckDB snapshot changed.\");\n for (const [key, revision] of Object.entries(request.expectedRevisions))\n if (this.execution.resolvedRevisions[key] !== revision)\n throw Error(\"Computed definitions changed; refresh the handshake.\");\n if (request.metrics.length > 20)\n throw Error(\"At most 20 metrics are allowed.\");\n this.window(request.result);\n const model = createGroupingModel(this.schema);\n if (request.grouping) model.validate(request.grouping);\n const resultSchema = request.grouping\n ? model.resultSchema(request.grouping.keys, request.grouping.summaries)\n : this.schema;\n this.builder(this.schema, request.now).where(request.source.where);\n const result = this.builder(resultSchema, request.now);\n result.where(request.result.where);\n result.order(request.result.orderBy);\n request.result.select.forEach((name) => result.definition(name));\n }\n async execute(\n request: QueryRequestV3,\n signal?: AbortSignal,\n ): Promise<QueryResultV3> {\n this.validateRequest(request);\n return this.transaction(async (tables) => {\n const source = await this.stage(\n request.source,\n request.now,\n tables,\n signal,\n );\n let relation = source.name,\n schema = this.schema;\n if (request.grouping) {\n const grouping = request.grouping,\n model = createGroupingModel(schema),\n builder = this.builder(schema, request.now);\n const keys = grouping.keys.map((name) => builder.field(name, false)),\n names = grouping.keys.map(id);\n const representative = builder\n .order(\n grouping.representative?.orderBy ?? [\n { field: schema.idField, dir: \"desc\" },\n ],\n false,\n )\n .replace(/^ORDER BY /, \"\");\n const tie = grouping.representative?.orderBy.some(\n (term) => term.field === schema.idField,\n )\n ? \"\"\n : `, ${builder.field(schema.idField)} DESC NULLS LAST`;\n const summaries = grouping.summaries.map(\n (summary) =>\n `${\n summary.op === \"row\"\n ? `first(${builder.field(summary.field!, false)} ORDER BY ${representative}${tie})`\n : builder.expression(model.summaryExpression(summary), true).sql\n } AS ${id(summary.id)}`,\n );\n relation = this.temp(tables);\n const identity = `CAST(to_json(struct_pack(${keys.map((key, i) => `k${i} := ${key}`).join(\", \")})) AS VARCHAR)`;\n await this.run(\n builder.statement(\n `CREATE TEMP TABLE ${id(relation)} AS SELECT ${identity} AS ${id(GROUP_ID_FIELD)}, ${keys.map((key, i) => `${key} AS ${names[i]}`).join(\", \")}${summaries.length ? `, ${summaries.join(\", \")}` : \"\"} FROM ${id(source.name)} GROUP BY ${keys.join(\", \")}`,\n ),\n signal,\n );\n const [{ n }] = (await this.sql(\n `SELECT COUNT(*) AS n FROM ${id(relation)}`,\n [],\n signal,\n )) as [{ n: number }];\n if (n > this.capabilities.maxGroups)\n throw Error(\"DuckDB grouped row budget exceeded.\");\n schema = model.resultSchema(grouping.keys, grouping.summaries);\n }\n const page = await this.page(\n relation,\n schema,\n request.result,\n request.now,\n signal,\n );\n const metrics = await this.metrics(\n relation,\n schema,\n request.result,\n request.metrics,\n request.now,\n tables,\n signal,\n );\n return {\n version: 3,\n now: request.now,\n sourceTotal: source.count,\n rows: request.rows ? page.rows : [],\n total: page.total,\n schema: {\n name: schema.name,\n idField: schema.idField,\n fields: schema.fields.map((field) => ({\n name: field.name,\n type: field.type,\n })),\n },\n metrics,\n execution: { ...this.execution, planToken: request.planToken ?? \"\" },\n };\n }, signal);\n }\n private async metrics(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n clauses: AggregationClause[],\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<AggregationResultEntry[]> {\n const output: AggregationResultEntry[] = [];\n // A failed DuckDB statement aborts its transaction, and DuckDB has no\n // savepoints. Clauses read only staged temporary relations, so commit\n // them and give each clause its own transaction.\n await this.sql(\"COMMIT\", [], signal);\n for (const clause of clauses) {\n abort(signal);\n const created = tables.length;\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n try {\n const entry = await this.metric(\n relation,\n schema,\n query,\n clause,\n now,\n tables,\n signal,\n );\n await this.sql(\"COMMIT\", [], signal);\n output.push(entry);\n } catch (error) {\n await this.sql(\"ROLLBACK\").catch(() => {});\n // The rollback discarded this clause's scratch relations.\n tables.splice(created);\n abort(signal);\n output.push({\n id: clause.id,\n buckets: [],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n return output;\n }\n private async metric(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n clause: AggregationClause,\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<AggregationResultEntry> {\n // Wire metrics carry active distributions without presentation settings.\n if (clause.distribution && !clause.display)\n clause = { ...clause, display: { kind: clause.distribution.kind } };\n const issues = validateMetric(clause, schema);\n if (issues.length)\n throw Error(issues.map((issue) => issue.message).join(\" \"));\n const builder = this.builder(schema, now),\n where = builder.where(query.where);\n const window =\n clause.scope === \"shownRows\"\n ? `${builder.order(query.orderBy)} LIMIT ${builder.bind(query.limit)} OFFSET ${builder.bind(query.offset)}`\n : \"\";\n let population = `(SELECT * FROM ${id(relation)} WHERE ${where} ${window})`;\n // The metric's own predicate narrows the scoped rows (inside the page for\n // shown-row scope) and never changes the table rows.\n if (clause.where?.length)\n population = `(SELECT * FROM ${population} r WHERE ${builder.where(clause.where)})`;\n let dateMapping: string | undefined;\n if (clause.dateGrouping) {\n const config = clause.dateGrouping,\n source = builder.field(config.field, false);\n const dates = await this.run(\n builder.statement(\n `SELECT DISTINCT CAST(${source} AS VARCHAR) AS value FROM ${population} r WHERE ${source} IS NOT NULL`,\n ),\n signal,\n );\n dateMapping = this.temp(tables);\n await this.sql(\n `CREATE TEMP TABLE ${id(dateMapping)} (value TIMESTAMPTZ, bucket TIMESTAMPTZ)`,\n [],\n signal,\n );\n for (let i = 0; i < dates.length; i += 250) {\n const args: unknown[] = [];\n const values = dates.slice(i, i + 250).map((row) => {\n const value = /^\\d{4}-\\d{2}-\\d{2}$/.test(String(row.value))\n ? String(row.value)\n : (this.formatRow({ [config.field]: row.value }, schema)[\n config.field\n ] as string);\n args.push(\n value,\n new Date(\n metricDateFloor(\n metricDateTime(value, config.timeZone),\n config.interval,\n config.timeZone,\n ),\n ).toISOString(),\n );\n return `(CAST($${args.length - 1} AS TIMESTAMPTZ), CAST($${args.length} AS TIMESTAMPTZ))`;\n });\n if (values.length)\n await this.sql(\n `INSERT INTO ${id(dateMapping)} VALUES ${values.join(\", \")}`,\n args,\n signal,\n );\n }\n population = `(SELECT r.* EXCLUDE (${id(config.field)}), m.bucket AS ${id(config.field)} FROM ${population} r LEFT JOIN ${id(dateMapping)} m ON CAST(r.${id(config.field)} AS TIMESTAMPTZ) = m.value)`;\n }\n const keys = clause.groupBy.map((name) => builder.field(name, false)),\n groups = keys.length ? `GROUP BY ${keys.join(\", \")}` : \"\";\n const distribution =\n clause.distribution &&\n [\"box\", \"histogram\"].includes(clause.display?.kind ?? \"\")\n ? clause.distribution\n : undefined;\n const expression = distribution\n ? builder.expression(distribution.input).sql\n : builder.expression(metricExpression(clause), true).sql;\n const projections = keys.map(\n (key, index) => `${key} AS ${id(`g${index}`)}`,\n );\n projections.push(\n \"COUNT(*) AS count\",\n distribution\n ? `list(${expression}) FILTER (WHERE ${expression} IS NOT NULL) AS samples`\n : `${expression} AS value`,\n );\n if (!distribution && clause.display?.kind === \"scatter\")\n projections.push(\n `${builder.expression(clause.expressionY ?? \"COUNT()\", true).sql} AS y`,\n );\n const rows = await this.run(\n builder.statement(\n `SELECT ${projections.join(\", \")} FROM ${population} r ${groups} LIMIT ${this.capabilities.maxGroups + 1}`,\n ),\n signal,\n );\n if (rows.length > this.capabilities.maxGroups)\n throw Error(\"DuckDB metric group budget exceeded.\");\n if (\n distribution &&\n rows.some(\n (row) =>\n (row.samples as unknown[] | null)?.length &&\n (row.samples as unknown[]).length > this.maxSamples,\n )\n )\n throw Error(\n `The ${distribution.kind} distribution exceeded the ${this.maxSamples.toLocaleString(\"en-US\")}-sample budget${clause.groupBy.length ? \" for one or more groups\" : \"\"}.`,\n );\n const edges =\n distribution?.kind === \"histogram\"\n ? histogramEdges(\n rows.flatMap((row) => (row.samples as number[]) ?? []),\n distribution.bins ?? 10,\n )\n : [];\n const buckets: AggregationResultEntry[\"buckets\"] = rows.map((row) => {\n const samples = (row.samples as number[]) ?? [];\n return {\n keys: clause.groupBy.map((name, index) => {\n const value = row[`g${index}`] ?? null;\n return schema.fields.find((field) => field.name === name)?.type ===\n \"datetime\" && value !== null\n ? (this.formatRow({ [name]: value }, schema)[name] as string)\n : (value as MetricValue);\n }),\n count: row.count as number,\n value: distribution ? null : (row.value as MetricValue),\n ...(row.y !== undefined ? { y: row.y as MetricValue } : {}),\n ...(distribution\n ? {\n nullCount: (row.count as number) - samples.length,\n distribution:\n distribution.kind === \"box\"\n ? {\n kind: \"box\" as const,\n summary: boxSummary(samples, distribution.whiskers),\n }\n : {\n kind: \"histogram\" as const,\n n: samples.length,\n edges,\n counts: histogramCounts(samples, edges),\n },\n }\n : {}),\n };\n });\n if (clause.dateGrouping?.includeEmpty) {\n const config = clause.dateGrouping,\n observed = buckets\n .filter((bucket) => bucket.keys[0] !== null)\n .map((bucket) => metricDateTime(bucket.keys[0]!));\n const range = metricDateRange(\n config,\n {\n ...query,\n select: query.select.map((field) => ({ field })),\n } as QueryState,\n observed,\n now,\n (name) => name,\n );\n const series = new Map(\n buckets\n .filter((bucket) => bucket.keys[0] !== null)\n .map((bucket) => [\n JSON.stringify(bucket.keys.slice(1)),\n bucket.keys.slice(1),\n ]),\n );\n if (keys.length === 1 && !series.size) series.set(\"[]\", []);\n const existing = new Set(\n buckets.map((bucket) => JSON.stringify(bucket.keys)),\n );\n if (range)\n for (\n let time = range[0];\n time <= range[1];\n time = metricDateNext(time, config.interval, config.timeZone)\n ) {\n for (const tuple of series.values()) {\n const values = [new Date(time).toISOString(), ...tuple];\n if (!existing.has(JSON.stringify(values))) {\n if (buckets.length >= this.capabilities.maxGroups)\n throw Error(\"DuckDB calendar group budget exceeded.\");\n buckets.push({\n keys: values,\n count: 0,\n value:\n (!clause.expression &&\n [\"count\", \"count_distinct\", \"sum\"].includes(clause.op)) ||\n /^(COUNT|COUNT_DISTINCT|SUM)\\([^)]*\\)$/.test(\n metricExpression(clause),\n )\n ? 0\n : null,\n });\n }\n }\n }\n }\n // Calendar fill-ins (count 0) are never hidden; hidden groups leave the\n // ranking, the group limit and Other.\n let hiddenGroups: number | undefined;\n if (clause.minCount !== undefined) {\n const kept = buckets.filter(\n (bucket) => bucket.count === 0 || bucket.count >= clause.minCount!,\n );\n hiddenGroups = buckets.length - kept.length;\n buckets.splice(0, buckets.length, ...kept);\n }\n // Calendar metrics default to chronological order, like the other engines.\n const sort: MetricSort[] = clause.sort?.length\n ? clause.sort\n : clause.dateGrouping\n ? [{ key: \"group0\", dir: \"asc\", nulls: \"last\" }]\n : [{ key: \"value\", dir: \"desc\" }];\n buckets.sort((a, b) => {\n for (const term of sort) {\n const value = (bucket: typeof a): MetricValue =>\n term.key.startsWith(\"group\")\n ? (bucket.keys[Number(term.key.slice(5))] ?? null)\n : term.key === \"samples\"\n ? bucket.distribution?.kind === \"box\"\n ? (bucket.distribution.summary?.n ?? 0)\n : (bucket.distribution?.n ?? 0)\n : ((bucket as unknown as Record<string, MetricValue>)[term.key] ??\n null);\n const av = value(a),\n bv = value(b);\n if (av === null || bv === null) {\n if (av !== bv)\n return (av === null ? 1 : -1) * (term.nulls === \"first\" ? -1 : 1);\n } else {\n const result = compareMetricValues(av, bv);\n if (result) return result * (term.dir === \"asc\" ? 1 : -1);\n }\n }\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n const limit = clause.groupLimit ?? 10000;\n return {\n id: clause.id,\n buckets: buckets.slice(0, limit),\n groupCount: buckets.length,\n coverage: buckets.length > limit ? \"partial\" : \"exact\",\n ...(clause.scope ? { scope: clause.scope } : {}),\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n };\n }\n transport(): Transport<DuckDBRow> {\n return {\n queryCapabilities: this.capabilities,\n metricCapabilities: {\n version: 2,\n expressions: true,\n shownRows: true,\n distributions: true,\n computedFields: this.computed.size > 0,\n filters: true,\n minCount: true,\n profile: DUCKDB_PROFILE,\n maxGroups: this.capabilities.maxGroups,\n },\n fetchQueryV3: (request, signal) => this.execute(request, signal),\n fetchRows: (query, signal) =>\n this.transaction(async (tables) => {\n this.window(query);\n const source = await this.stage(query, Date.now(), tables, signal);\n return this.page(\n source.name,\n this.schema,\n { ...query, where: [] },\n Date.now(),\n signal,\n );\n }, signal),\n fetchMetrics: (query: MetricQuery, signal) => {\n if (\n query.diagnostics.length ||\n (query.profile && query.profile !== DUCKDB_PROFILE) ||\n query.metrics.length > 20\n )\n return Promise.reject(Error(\"Invalid DuckDB metric request.\"));\n return this.transaction(async (tables) => {\n const now = Date.now(),\n server = { ...query, select: [] };\n const source = await this.stage(server, now, tables, signal);\n return {\n metrics: await this.metrics(\n source.name,\n this.schema,\n server,\n query.metrics,\n now,\n tables,\n signal,\n ),\n };\n }, signal);\n },\n fetchAggregations: (query, signal) =>\n this.transaction(async (tables) => {\n if (query.diagnostics?.length || query.aggregations.length > 20)\n throw Error(\"Invalid DuckDB aggregation request.\");\n const server = {\n select: [],\n where: query.where,\n orderBy: [],\n limit: 100,\n offset: 0,\n },\n now = Date.now();\n const source = await this.stage(server, now, tables, signal);\n return {\n metrics: await this.metrics(\n source.name,\n this.schema,\n { ...server, where: [] },\n query.aggregations,\n now,\n tables,\n signal,\n ),\n };\n }, signal),\n fetchDistinctValues: (query, signal) =>\n this.serial(async () => {\n const builder = this.builder(),\n field = builder.definition(query.field),\n limit = positive(query.limit, 50, 500);\n if (!isFilterable(field))\n throw Error(`Field ${field.name} is not filterable.`);\n if (query.search.length > 2000)\n throw Error(\"Distinct search exceeds its budget.\");\n const source = this.projectedSource(Date.now()),\n value = builder.field(query.field),\n array = field.type === \"textarray\";\n builder.args.push(...source.args);\n const param = builder.bind(query.search);\n const rows = await this.run(\n builder.statement(\n `SELECT CAST(value AS VARCHAR) AS value, COUNT(*) AS n FROM (SELECT ${array ? `unnest(${value})` : value} AS value FROM (${source.sql}) r) v WHERE value IS NOT NULL AND contains(lower(CAST(value AS VARCHAR)), lower(${param})) GROUP BY value ORDER BY n DESC, value ASC LIMIT ${limit + 1}`,\n ),\n signal,\n );\n const [{ n }] = (await this.sql(\n `SELECT COUNT(*) AS n FROM (${source.sql}) r WHERE ${array ? `COALESCE(len(${value}),0) = 0` : `${value} IS NULL`}`,\n source.args,\n signal,\n )) as [{ n: number }];\n return {\n values: rows.slice(0, limit).map((row) => String(row.value)),\n hasMore: rows.length > limit,\n hasNull: n > 0,\n };\n }, signal),\n fetchRow: (identity, signal) =>\n this.serial(async () => {\n const source = this.projectedSource(Date.now());\n const rows = await this.sql(\n `SELECT * FROM (${source.sql}) r WHERE ${id(this.schema.idField)} = $${source.args.length + 1} LIMIT 2`,\n [...source.args, identity],\n signal,\n );\n if (rows.length > 1) throw Error(\"DuckDB identity must be unique.\");\n return rows[0] ? this.formatRow(rows[0], this.schema) : null;\n }, signal),\n fetchFieldStats: (fields, signal) =>\n this.serial(async () => {\n if (fields.length > 64)\n throw Error(\"At most 64 field stats can be requested.\");\n const stats: Record<\n string,\n import(\"@pythia-software/query-table-core\").FieldStats\n > = {};\n for (const name of fields) {\n const builder = this.builder(),\n field = builder.definition(name),\n source = this.projectedSource(Date.now()),\n value = builder.field(name);\n const rows = await this.sql(\n field.type === \"textarray\"\n ? `SELECT COUNT(DISTINCT value) AS \"distinct\" FROM (SELECT unnest(${value}) AS value FROM (${source.sql}) r)`\n : `SELECT COUNT(DISTINCT ${value}) AS \"distinct\", MIN(${value}) AS min, MAX(${value}) AS max FROM (${source.sql}) r`,\n source.args,\n signal,\n );\n const result = rows[0]!;\n stats[name] = {\n distinct: result.distinct as number,\n ...(typeof result.min === \"number\" ||\n typeof result.min === \"string\"\n ? { min: result.min }\n : {}),\n ...(typeof result.max === \"number\" ||\n typeof result.max === \"string\"\n ? { max: result.max }\n : {}),\n };\n }\n return stats;\n }, signal),\n };\n }\n}\n\nexport function createDuckDBTransport(\n options: DuckDBOptions,\n): Transport<DuckDBRow> {\n return new DuckDBBackend(options).transport();\n}\n","import type { DuckDBConnection, DuckDBRow } from \"./backend\";\n\n/** Structural adapter keeps duckdb-wasm optional and out of native bundles. */\nexport interface DuckDBWasmConnection {\n query(sql: string): Promise<{ toArray(): { toJSON(): unknown }[] }>;\n prepare(sql: string): Promise<{\n query(...args: any[]): Promise<{ toArray(): { toJSON(): unknown }[] }>;\n close(): Promise<void>;\n }>;\n}\nexport function fromDuckDBWasmConnection(\n connection: DuckDBWasmConnection,\n): DuckDBConnection {\n return {\n async query(sql, args) {\n if (!args.length)\n return (await connection.query(sql))\n .toArray()\n .map((row) => row.toJSON() as DuckDBRow);\n const statement = await connection.prepare(sql);\n try {\n return (await statement.query(...args))\n .toArray()\n .map((row) => row.toJSON() as DuckDBRow);\n } finally {\n await statement.close();\n }\n },\n };\n}\n","import {\n loadSchema,\n type FieldSchema,\n} from \"@pythia-software/query-table-core\";\n\n/** Read explicit DuckDB bindings; never reuse another engine's SQL. */\nexport function loadDuckDBSchema(document: unknown): {\n schema: FieldSchema;\n bindings: Record<string, string>;\n} {\n const schema = loadSchema(document);\n const raw = document as {\n fields: { name: string; bindings?: { duckdb?: { expr?: unknown } } }[];\n };\n const bindings: Record<string, string> = Object.create(null);\n for (const field of schema.fields) {\n if (field.source.kind !== \"backend\") continue;\n const binding = raw.fields.find((item) => item.name === field.name)\n ?.bindings?.duckdb;\n if (\n !binding ||\n typeof binding.expr !== \"string\" ||\n !binding.expr.trim() ||\n binding.expr.includes(\"\\0\")\n )\n throw Error(\n `Field ${field.name} requires an explicit bindings.duckdb.expr.`,\n );\n bindings[field.name] = binding.expr;\n }\n return { schema, bindings };\n}\n"],"mappings":"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","names":["field","compileFormula","isSelectable","isFilterable","compileFormula","isSelectable","field","isFilterable"]}
1
+ {"version":3,"sources":["../src/sql.ts","../src/backend.ts","../src/wasm.ts","../src/schema.ts"],"sourcesContent":["import {\n branchesOf,\n coerceValue,\n compileFormula,\n compileMetric,\n isFilterable,\n isSortable,\n isSelectable,\n opsForField,\n type FieldDef,\n type FieldSchema,\n type FormulaNode,\n type FormulaPlan,\n type WhereClause,\n type WhereTerm,\n type OrderByClause,\n type ServerQuery,\n} from \"@pythia-software/query-table-core\";\n\nexport interface DuckDBStatement {\n sql: string;\n args: unknown[];\n}\n/** Identifiers come only from the host catalogue, and are always quoted. */\nexport function quoteIdentifier(value: string): string {\n if (!value || value.includes(\"\\0\")) throw Error(\"Invalid DuckDB identifier.\");\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n}\nexport function quoteRelation(value: string): string {\n return value.split(\".\").map(quoteIdentifier).join(\".\");\n}\nconst aggregates = new Set([\n \"COUNT\",\n \"COUNT_DISTINCT\",\n \"SUM\",\n \"AVG\",\n \"MIN\",\n \"MAX\",\n \"MEDIAN\",\n]);\nconst safeNumber = (value: string) =>\n `(CASE WHEN ${value} IS NULL OR (isfinite(${value}) AND abs(${value}) <= 9007199254740991) THEN ${value} ELSE error('Query Table numeric precision exceeded') END)`;\n\nexport class SQLBuilder {\n readonly args: unknown[] = [];\n constructor(\n readonly schema: FieldSchema,\n readonly now = Date.now(),\n readonly bindings: Record<string, string> = {},\n ) {}\n bind(value: unknown): string {\n this.args.push(value);\n return `$${this.args.length}`;\n }\n statement(sql: string): DuckDBStatement {\n if (sql.length > 262144 || this.args.length > 10000)\n throw Error(\"DuckDB statement budget exceeded.\");\n return { sql, args: [...this.args] };\n }\n definition(name: string): FieldDef {\n const field = this.schema.fields.find((field) => field.name === name);\n if (!field || field.source.kind !== \"backend\")\n throw Error(`Unavailable DuckDB field: ${name}.`);\n return field;\n }\n field(name: string, normalize = true): string {\n const field = this.definition(name),\n value =\n (Object.prototype.hasOwnProperty.call(this.bindings, name)\n ? this.bindings[name]\n : undefined) ??\n quoteIdentifier(\n field.source.kind === \"backend\" ? (field.source.path ?? name) : name,\n );\n if (!normalize) return value;\n if (field.type === \"text\" || field.type === \"enum\")\n return `NULLIF(CAST(${value} AS VARCHAR), '')`;\n if (field.type === \"datetime\") return `CAST(${value} AS TIMESTAMPTZ)`;\n return value;\n }\n where(terms: WhereTerm[]): string {\n if (terms.length > 100)\n throw Error(\"At most 100 filter terms are allowed.\");\n let count = 0;\n return terms.length\n ? terms\n .map((term) => {\n // A term is an OR of branches, each an AND of literals (a single\n // literal, an OR group, or an OR of conjunctions).\n const branches = branchesOf(term);\n const size = branches.reduce((n, branch) => n + branch.length, 0);\n if (!branches.length || branches.some((branch) => !branch.length) || (count += size) > 100)\n throw Error(\"Invalid filter predicate budget.\");\n const compile = (clause: WhereClause): string => {\n const field = this.definition(clause.field),\n raw = this.field(field.name),\n op = clause.op;\n if (!isFilterable(field) || !opsForField(field).includes(op))\n throw Error(`Unsupported filter on ${field.name}: ${op}.`);\n const value =\n field.type === \"textarray\"\n ? `CASE WHEN len(${raw}) > 0 THEN ${raw} END`\n : raw;\n let sql: string;\n if (op === \"is_null\" || op === \"is_not_null\")\n sql = `${value} IS ${op === \"is_null\" ? \"\" : \"NOT \"}NULL`;\n else {\n const typed = coerceValue(field.type, clause.value, this.now);\n if (typeof typed === \"number\" && !Number.isFinite(typed))\n throw Error(\"Filter operands must be finite.\");\n const param = this.bind(\n field.type === \"datetime\"\n ? new Date(typed as number).toISOString()\n : typed,\n );\n const rhs =\n field.type === \"datetime\"\n ? `CAST(${param} AS TIMESTAMPTZ)`\n : param;\n if ([\"=\", \"!=\", \">\", \">=\", \"<\", \"<=\"].includes(op))\n sql = `${value} ${op} ${rhs}`;\n else if (\n [\"contains\", \"starts_with\", \"ends_with\"].includes(op)\n )\n sql = `${op}(lower(${value}), lower(${param}))`;\n else if (op === \"includes\")\n sql = field.filter?.arrayCaseSensitive\n ? `list_contains(${value}, ${param})`\n : `list_contains(list_transform(${value}, x -> lower(x)), lower(${param}))`;\n else if (op.startsWith(\"length_\"))\n sql = `length(${value}) ${op === \"length_gt\" ? \">\" : op === \"length_lt\" ? \"<\" : \"=\"} CAST(${param} AS DOUBLE)`;\n else if (\n op === \"matches_regex\" ||\n op === \"not_matches_regex\"\n ) {\n if (clause.value.length > 2000)\n throw Error(\"Regex exceeds 2,000 characters.\");\n sql = `${op === \"not_matches_regex\" ? \"NOT \" : \"\"}regexp_matches(${value}, ${param})`;\n } else throw Error(`Unsupported DuckDB operator: ${op}.`);\n }\n return clause.negated ? `NOT (${sql})` : sql;\n };\n return `(${branches\n .map((branch) => branch.length === 1 ? compile(branch[0]!) : `(${branch.map(compile).join(\" AND \")})`)\n .join(\" OR \")})`;\n })\n .join(\" AND \")\n : \"TRUE\";\n }\n order(terms: OrderByClause[], identity = true): string {\n if (terms.length > 20) throw Error(\"At most 20 sort fields are allowed.\");\n const output = terms.map((term) => {\n const field = this.definition(term.field);\n if (!isSortable(field) && field.name !== this.schema.idField)\n throw Error(`Field ${field.name} is not sortable.`);\n if (\n ![\"asc\", \"desc\"].includes(term.dir) ||\n (term.nulls && ![\"first\", \"last\"].includes(term.nulls))\n )\n throw Error(\"Invalid ordering.\");\n let value = this.field(field.name);\n if (term.extract) {\n if (field.type !== \"text\" || term.extract.regex.length > 2000)\n throw Error(\"Invalid regex extraction.\");\n const pattern = this.bind(term.extract.regex);\n // DuckDB/RE2 extraction uses the first capture, or the full match.\n const capture = /(^|[^\\\\])\\((?!\\?)/.test(term.extract.regex) ? 1 : 0;\n value = `CASE WHEN regexp_matches(${value}, ${pattern}) THEN regexp_extract(${value}, ${pattern}, ${capture}) END`;\n }\n return `${value} ${term.dir.toUpperCase()} NULLS ${(term.nulls ?? \"last\").toUpperCase()}`;\n });\n if (identity && !terms.some((term) => term.field === this.schema.idField))\n output.push(`${this.field(this.schema.idField)} ASC NULLS LAST`);\n return output.length ? `ORDER BY ${output.join(\", \")}` : \"\";\n }\n expression(\n source: string,\n aggregate = false,\n ): { sql: string; plan: FormulaPlan } {\n const plan = aggregate\n ? compileMetric(source, this.schema)\n : compileFormula(source, this.schema.fields);\n return { sql: this.node(plan.ast), plan };\n }\n node(node: FormulaNode): string {\n const sql = this.nodeSQL(node);\n if (sql.length > 131072)\n throw Error(\"DuckDB expression SQL budget exceeded.\");\n return sql;\n }\n private nodeSQL(node: FormulaNode): string {\n if (node.kind === \"literal\")\n return node.value === null ? \"NULL\" : this.bind(node.value);\n if (node.kind === \"field\") return this.field(node.name, false);\n const name = node.name,\n vs = node.args.map((arg) => this.node(arg)),\n a = vs[0]!,\n b = vs[1]!,\n c = vs[2]!;\n if (aggregates.has(name)) {\n if (name === \"COUNT\") return `CAST(COUNT(${a ?? \"*\"}) AS DOUBLE)`;\n if (name === \"COUNT_DISTINCT\")\n return `CAST(COUNT(DISTINCT ${a}) AS DOUBLE)`;\n const sql = `${name}(${a})`;\n return [\"SUM\", \"AVG\", \"MEDIAN\"].includes(name)\n ? safeNumber(\n `CAST(${name === \"SUM\" ? `COALESCE(${sql}, 0)` : sql} AS DOUBLE)`,\n )\n : sql;\n }\n if (name.startsWith(\"op:\")) {\n const op = name.slice(3);\n if (op === \"IN\") return `(${a} IN (${vs.slice(1).join(\", \")}))`;\n if (op === \"BETWEEN\") return `(${a} BETWEEN ${b} AND ${c})`;\n if ([\"/\", \"%\"].includes(op))\n return safeNumber(\n `(CASE WHEN ${b} = 0 THEN error('Division by zero') ELSE ${a} ${op} ${b} END)`,\n );\n return [\"+\", \"-\", \"*\"].includes(op)\n ? safeNumber(`(${a} ${op} ${b})`)\n : `(${a} ${op} ${b})`;\n }\n if (name.startsWith(\"unary:\")) return `(${name.slice(6)} ${a})`;\n if (name === \"IF\") return `CASE WHEN ${a} THEN ${b} ELSE ${c} END`;\n if (name === \"IFS\")\n return `CASE ${vs\n .slice(0, -1)\n .filter((_, i) => i % 2 === 0)\n .map((v, i) => `WHEN ${v} THEN ${vs[2 * i + 1]}`)\n .join(\" \")} ELSE ${vs[vs.length - 1]} END`;\n if (name === \"SWITCH\")\n return `CASE ${vs\n .slice(1, -1)\n .filter((_, i) => i % 2 === 0)\n .map(\n (v, i) => `WHEN ${a} IS NOT DISTINCT FROM ${v} THEN ${vs[2 * i + 2]}`,\n )\n .join(\" \")} ELSE ${vs[vs.length - 1]} END`;\n if (name === \"IS_NULL\") return `(${a} IS NULL)`;\n if (name === \"IS_EMPTY\") {\n const input = node.args[0]!;\n const array =\n (input.kind === \"field\" && input.valueType === \"textarray\") ||\n (input.kind === \"call\" &&\n [\"SPLIT\", \"ARRAY_UNIQUE\", \"ARRAY_SORT\"].includes(input.name));\n return `(${a} IS NULL OR len(${array ? a : `CAST(${a} AS VARCHAR)`}) = 0)`;\n }\n if (name === \"COALESCE\" || name === \"NULLIF\")\n return `${name}(${vs.join(\", \")})`;\n if (name === \"IFERROR\")\n throw Error(\"IFERROR is not available in the qt-duckdb-v1 SQL profile.\");\n if (name === \"ROUND\") {\n const scale = `power(10, ${b ?? \"0\"})`;\n return safeNumber(`(floor(${a} * ${scale} + 0.5) / ${scale})`);\n }\n if (name === \"CLAMP\")\n return `CASE WHEN ${a} IS NULL OR ${b} IS NULL OR ${c} IS NULL THEN NULL ELSE greatest(${b}, least(${c}, ${a})) END`;\n if (name === \"LEAST\" || name === \"GREATEST\" || name === \"CONCAT\")\n return `CASE WHEN ${vs.map((v) => `${v} IS NULL`).join(\" OR \")} THEN NULL ELSE ${name}(${vs.join(\", \")}) END`;\n if (name === \"CONCAT_WS\")\n return `CASE WHEN ${a} IS NULL THEN NULL ELSE concat_ws(${vs.join(\", \")}) END`;\n if ([\"CONTAINS\", \"STARTS_WITH\", \"ENDS_WITH\"].includes(name))\n return `${name.toLowerCase()}(CASE WHEN ${c ?? \"FALSE\"} THEN lower(${a}) ELSE ${a} END, CASE WHEN ${c ?? \"FALSE\"} THEN lower(${b}) ELSE ${b} END)`;\n if (name === \"TO_NUMBER\") return safeNumber(`CAST(${a} AS DOUBLE)`);\n if (name === \"TO_TEXT\") return `CAST(${a} AS VARCHAR)`;\n if (name === \"URL_ENCODE\") return `url_encode(${a})`;\n if (name === \"TO_BOOLEAN\") return `CAST(${a} AS BOOLEAN)`;\n if (name === \"TO_DATETIME\") return `CAST(${a} AS TIMESTAMPTZ)`;\n if (name === \"SPLIT\") return `string_split(${a}, ${b})`;\n if (name === \"JOIN\") return `array_to_string(${a}, ${b})`;\n if (name === \"ARRAY_LENGTH\") return `len(${a})`;\n if (name === \"ARRAY_CONTAINS\") return `list_contains(${a}, ${b})`;\n if (name === \"ARRAY_GET\")\n return `CASE WHEN ${b} < 0 THEN error('Array index must be nonnegative') ELSE list_extract(${a}, CAST(${b} + 1 AS BIGINT)) END`;\n if (name === \"ARRAY_SORT\") return `list_sort(${a})`;\n if (name === \"ARRAY_UNIQUE\")\n return `list_filter(${a}, (x, i) -> list_position(${a}, x) = i)`;\n if (name === \"WEEKDAY\")\n return `extract(isodow FROM CAST(${a} AS TIMESTAMPTZ))`;\n if ([\"YEAR\", \"MONTH\", \"DAY\", \"HOUR\"].includes(name))\n return `extract(${name.toLowerCase()} FROM CAST(${a} AS TIMESTAMPTZ))`;\n if (name === \"DATE_TRUNC\")\n return `date_trunc(${a}, CAST(${b} AS TIMESTAMPTZ))`;\n if (\n name === \"DATE_DIFF\" ||\n name === \"DATE_ADD\" ||\n name === \"FORMAT_DATE\" ||\n name.startsWith(\"REGEX_\")\n )\n throw Error(`${name} is not available in the qt-duckdb-v1 SQL profile.`);\n if (\n [\"LEFT\", \"RIGHT\", \"SUBSTRING\", \"LPAD\", \"RPAD\", \"SPLIT_PART\"].includes(\n name,\n )\n ) {\n const args = [...vs];\n const indices =\n name === \"SUBSTRING\" ? [1, 2] : name === \"SPLIT_PART\" ? [2] : [1];\n for (const index of indices)\n if (args[index] !== undefined)\n args[index] = `CAST(${args[index]} AS BIGINT)`;\n return `${name}(${args.join(\", \")})`;\n }\n if (\n [\n \"LENGTH\",\n \"LOWER\",\n \"UPPER\",\n \"TRIM\",\n \"LTRIM\",\n \"RTRIM\",\n \"REPLACE\",\n \"ABS\",\n \"FLOOR\",\n \"CEIL\",\n \"TRUNC\",\n \"POWER\",\n \"SQRT\",\n ].includes(name)\n )\n return `${name}(${vs.join(\", \")})`;\n throw Error(`Unsupported DuckDB function: ${name}.`);\n }\n}\n\nexport function compileDuckDBRows(\n query: ServerQuery,\n schema: FieldSchema,\n relation: string,\n now = Date.now(),\n): DuckDBStatement {\n const sql = new SQLBuilder(schema, now);\n if (\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1 ||\n query.limit > 10000 ||\n !Number.isSafeInteger(query.offset) ||\n query.offset < 0\n )\n throw Error(\"Invalid result window.\");\n const select = [...new Set([schema.idField, ...query.select])].map((name) => {\n const field = sql.definition(name);\n if (!isSelectable(field) && name !== schema.idField)\n throw Error(`Field ${name} is not selectable.`);\n return `${sql.field(name, false)} AS ${quoteIdentifier(name)}`;\n });\n const where = sql.where(query.where),\n order = sql.order(query.orderBy);\n return sql.statement(\n `SELECT ${select.join(\", \")} FROM ${quoteRelation(relation)} WHERE ${where} ${order} LIMIT ${sql.bind(query.limit)} OFFSET ${sql.bind(query.offset)}`,\n );\n}\n","import {\n compileFormula,\n createGroupingModel,\n GROUP_ID_FIELD,\n metricExpression,\n metricMinCount,\n metricMinCountKeeps,\n metricMinCountMeasure,\n validateMetric,\n isSelectable,\n isFilterable,\n boxSummary,\n histogramEdges,\n histogramCounts,\n compareMetricValues,\n metricDateFloor,\n isMetricCycle,\n metricCycleSlot,\n metricCycleSlots,\n metricDateTime,\n metricDateNext,\n metricDateRange,\n groupKeyFields,\n isCalendarGroupKey,\n type AggregationClause,\n type AggregationResult,\n type AggregationResultEntry,\n type ComputedColumn,\n type ComputedExecution,\n type FieldSchema,\n type FormulaPlan,\n type MetricQuery,\n type QueryCapabilitiesV3,\n type QueryRequestV3,\n type QueryResultV3,\n type ServerQuery,\n type Transport,\n type MetricDateGrouping,\n type MetricSort,\n type MetricValue,\n type QueryState,\n} from \"@pythia-software/query-table-core\";\nimport {\n SQLBuilder,\n quoteIdentifier as id,\n quoteRelation,\n type DuckDBStatement,\n} from \"./sql\";\n\nexport const DUCKDB_PROFILE = \"qt-duckdb-v1\";\nexport type DuckDBRow = Record<string, unknown>;\n/** One exclusive connection, with bound parameters; no driver runtime dependency. */\nexport interface DuckDBConnection {\n query(sql: string, args: unknown[]): Promise<DuckDBRow[]>;\n interrupt?(): void | Promise<void>;\n}\nexport interface DuckDBOptions {\n connection: DuckDBConnection;\n schema: FieldSchema;\n relation: string;\n /** Trusted SQL expressions, keyed by the host's field names. Never request SQL. */\n bindings?: Record<string, string>;\n computedColumns?: readonly ComputedColumn[];\n snapshot?: string;\n maxRows?: number;\n maxGroups?: number;\n maxPopulation?: number;\n maxSamples?: number;\n maxStagingBytes?: number;\n}\nfunction abort(signal?: AbortSignal): void {\n if (signal?.aborted)\n throw new DOMException(\"DuckDB query cancelled.\", \"AbortError\");\n}\n/** Normalize both Arrow and Node values at the transport boundary. */\nexport function normalizeDuckDBValue(value: unknown): unknown {\n if (typeof value === \"bigint\") {\n const numeric = Number(value);\n if (!Number.isSafeInteger(numeric))\n throw Error(\"DuckDB integer exceeds JavaScript safe precision.\");\n return numeric;\n }\n if (value instanceof Date) return value.toISOString();\n if (\n typeof value === \"number\" &&\n (!Number.isFinite(value) || Math.abs(value) > Number.MAX_SAFE_INTEGER)\n )\n throw Error(\"DuckDB number exceeds finite safe precision.\");\n if (Array.isArray(value)) return value.map(normalizeDuckDBValue);\n if (value && typeof value === \"object\") {\n // Arrow vectors expose toArray(); StructRow exposes toJSON().\n if (\"toArray\" in value && typeof value.toArray === \"function\")\n return Array.from(value.toArray()).map(normalizeDuckDBValue);\n if (\"toJSON\" in value && typeof value.toJSON === \"function\")\n return normalizeDuckDBValue(value.toJSON());\n return Object.fromEntries(\n Object.entries(value).map(([key, item]) => [\n key,\n normalizeDuckDBValue(item),\n ]),\n );\n }\n return value;\n}\nfunction positive(\n value: number | undefined,\n fallback: number,\n maximum: number,\n): number {\n const out = value ?? fallback;\n if (!Number.isSafeInteger(out) || out < 1 || out > maximum)\n throw Error(\"Invalid DuckDB resource budget.\");\n return out;\n}\n\nexport class DuckDBBackend {\n readonly schema: FieldSchema;\n readonly execution: ComputedExecution;\n readonly capabilities: QueryCapabilitiesV3;\n readonly maxSamples: number;\n readonly maxStagingBytes: number;\n private queue: Promise<unknown> = Promise.resolve();\n private sequence = 0;\n private readonly computed = new Map<string, FormulaPlan>();\n constructor(readonly options: DuckDBOptions) {\n const fields = options.schema.fields\n .filter((field) => field.source.kind === \"backend\")\n .map((field) => ({\n ...field,\n source: { ...field.source, kind: \"backend\" as const, path: field.name },\n }));\n if (\n !fields.some((field) => field.name === options.schema.idField) ||\n new Set(fields.map((field) => field.name)).size !== fields.length\n )\n throw Error(\n \"DuckDB needs a unique field catalogue and a bound identity.\",\n );\n quoteRelation(options.relation);\n this.schema = { ...options.schema, fields };\n const definitions = new Map(\n (options.computedColumns ?? []).map((column) => [\n `@computed/${column.id}`,\n column,\n ]),\n );\n const visiting = new Set<string>();\n const resolve = (name: string): FormulaPlan | undefined => {\n if (this.computed.has(name)) return this.computed.get(name);\n const definition = definitions.get(name);\n if (!definition) return undefined;\n if (visiting.has(name)) throw Error(\"Computed definition cycle.\");\n visiting.add(name);\n const plan = compileFormula(\n definition.expression.source,\n fields,\n resolve,\n );\n // Reject unsupported SQL at negotiation, before advertising capabilities.\n new SQLBuilder(this.schema).node(plan.ast);\n visiting.delete(name);\n this.computed.set(name, plan);\n return plan;\n };\n for (const name of definitions.keys()) {\n const plan = resolve(name)!;\n fields.push({\n name,\n label: definitions.get(name)!.label,\n type: plan.type === \"null\" ? \"text\" : plan.type,\n source: { kind: \"backend\", path: name },\n filter: { enabled: true },\n sort: { enabled: true },\n aggregate: { measure: true, groupable: plan.type !== \"textarray\" },\n });\n }\n this.execution = {\n profile: DUCKDB_PROFILE,\n planToken: `duckdb:${JSON.stringify([...definitions.values()].map((column) => [column.id, column.revision]))}`,\n resolvedRevisions: Object.fromEntries(\n [...definitions.values()].map((column) => [column.id, column.revision]),\n ),\n fields: Object.fromEntries(\n fields\n .filter((field) => definitions.has(field.name))\n .map((field) => [\n field.name,\n {\n type: field.type,\n select: true,\n filter: true,\n sort: true,\n measure: true,\n group: field.type !== \"textarray\",\n },\n ]),\n ),\n ...(options.snapshot !== undefined ? { snapshot: options.snapshot } : {}),\n };\n this.capabilities = {\n version: 3,\n profile: DUCKDB_PROFILE,\n groupedRows: true,\n calendarGrouping: true,\n calendarCycles: true,\n calendarGroupKeys: true,\n computedSourceFilters: definitions.size > 0,\n regex: true,\n regexSourceFilters: true,\n regexAggregateExpressions: false,\n metricFilters: true,\n metricMinCount: true,\n metricMinCountMeasures: true,\n maxRows: positive(options.maxRows, 10000, 10000),\n maxGroups: positive(options.maxGroups, 10000, 10000),\n maxPopulation: positive(options.maxPopulation, 250000, 10000000),\n };\n this.maxSamples = positive(options.maxSamples, 100000, 1000000);\n this.maxStagingBytes = positive(\n options.maxStagingBytes,\n 64 * 1024 * 1024,\n 1024 * 1024 * 1024,\n );\n }\n private serial<T>(work: () => Promise<T>, signal?: AbortSignal): Promise<T> {\n const next = this.queue.then(() => {\n abort(signal);\n return work();\n });\n this.queue = next.catch(() => {});\n return next;\n }\n /** Wait before closing an owned driver connection. */\n async drain(): Promise<void> {\n await this.queue;\n }\n private async run(\n statement: DuckDBStatement,\n signal?: AbortSignal,\n ): Promise<DuckDBRow[]> {\n abort(signal);\n const cancel = () => {\n void this.options.connection.interrupt?.();\n };\n signal?.addEventListener(\"abort\", cancel, { once: true });\n try {\n const rows = await this.options.connection.query(\n statement.sql,\n statement.args,\n );\n abort(signal);\n return rows.map((row) => normalizeDuckDBValue(row) as DuckDBRow);\n } finally {\n signal?.removeEventListener(\"abort\", cancel);\n }\n }\n private sql(statement: string, args: unknown[] = [], signal?: AbortSignal) {\n return this.run({ sql: statement, args }, signal);\n }\n private window(query: ServerQuery): void {\n if (\n !Number.isSafeInteger(query.limit) ||\n query.limit < 1 ||\n query.limit > this.capabilities.maxRows ||\n !Number.isSafeInteger(query.offset) ||\n query.offset < 0\n )\n throw Error(\"Invalid DuckDB result window.\");\n }\n private builder(schema = this.schema, now = Date.now()) {\n return new SQLBuilder(schema, now);\n }\n private projectedSource(now: number): DuckDBStatement {\n const bindings = Object.fromEntries(\n this.schema.fields\n .filter((field) => !this.computed.has(field.name))\n .map((field) => [\n field.name,\n (this.options.bindings &&\n Object.prototype.hasOwnProperty.call(\n this.options.bindings,\n field.name,\n )\n ? this.options.bindings[field.name]\n : undefined) ??\n id(\n (() => {\n const original = this.options.schema.fields.find(\n (item) => item.name === field.name,\n );\n return original?.source.kind === \"backend\"\n ? (original.source.path ?? field.name)\n : field.name;\n })(),\n ),\n ]),\n );\n const builder = new SQLBuilder(this.schema, now, bindings);\n const projections = this.schema.fields.map((field) => {\n const plan = this.computed.get(field.name),\n raw = plan ? builder.node(plan.ast) : bindings[field.name]!;\n return `${raw} AS ${id(field.name)}`;\n });\n return builder.statement(\n `SELECT ${projections.join(\", \")} FROM ${quoteRelation(this.options.relation)} AS r`,\n );\n }\n private async transaction<T>(\n work: (tables: string[]) => Promise<T>,\n signal?: AbortSignal,\n ): Promise<T> {\n return this.serial(async () => {\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n const tables: string[] = [];\n try {\n const result = await work(tables);\n for (const table of tables.reverse())\n await this.sql(`DROP TABLE ${id(table)}`, [], signal);\n await this.sql(\"COMMIT\", [], signal);\n return result;\n } catch (error) {\n await this.sql(\"ROLLBACK\").catch(() => {});\n // Metrics commit staged relations before isolating each clause, so a\n // rollback alone may not remove them.\n for (const table of tables.reverse())\n await this.sql(`DROP TABLE IF EXISTS ${id(table)}`).catch(() => {});\n abort(signal);\n throw error;\n }\n }, signal);\n }\n private temp(tables: string[]): string {\n const name = `qt_duckdb_${++this.sequence}`;\n tables.push(name);\n return name;\n }\n private async stage(\n source: ServerQuery,\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<{ name: string; count: number }> {\n const projection = this.projectedSource(now),\n builder = this.builder(this.schema, now);\n builder.args.push(...projection.args);\n const where = builder.where(source.where),\n name = this.temp(tables);\n const population = `(${projection.sql}) r WHERE ${where}`;\n const [{ n, bytes }] = (await this.run(\n builder.statement(\n `SELECT COUNT(*) AS n, COALESCE(SUM(octet_length(encode(CAST(to_json(r) AS VARCHAR)))),0) AS bytes FROM ${population}`,\n ),\n signal,\n )) as [{ n: number; bytes: number }];\n if (n > this.capabilities.maxPopulation || bytes > this.maxStagingBytes)\n throw Error(\"DuckDB source population or staging byte budget exceeded.\");\n await this.run(\n builder.statement(\n `CREATE TEMP TABLE ${id(name)} AS SELECT * FROM ${population}`,\n ),\n signal,\n );\n const [{ invalid }] = (await this.sql(\n `SELECT COUNT(*) - COUNT(DISTINCT ${id(this.schema.idField)}) AS invalid FROM ${id(name)}`,\n [],\n signal,\n )) as [{ invalid: number }];\n if (invalid !== 0)\n throw Error(\"DuckDB source identity must be unique and non-null.\");\n return { name, count: n };\n }\n private async page(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n now: number,\n signal?: AbortSignal,\n ) {\n this.window(query);\n const builder = this.builder(schema, now),\n where = builder.where(query.where);\n const [{ total }] = (await this.run(\n builder.statement(\n `SELECT COUNT(*) AS total FROM ${id(relation)} WHERE ${where}`,\n ),\n signal,\n )) as [{ total: number }];\n const order = builder.order(query.orderBy),\n names = [...new Set([schema.idField, ...query.select])];\n names.forEach((name) => {\n if (!isSelectable(builder.definition(name)) && name !== schema.idField)\n throw Error(`Field ${name} is not selectable.`);\n });\n const rows = await this.run(\n builder.statement(\n `SELECT ${names.map(id).join(\", \")} FROM ${id(relation)} WHERE ${where} ${order} LIMIT ${builder.bind(query.limit)} OFFSET ${builder.bind(query.offset)}`,\n ),\n signal,\n );\n return { rows: rows.map((row) => this.formatRow(row, schema)), total };\n }\n private formatRow(row: DuckDBRow, schema: FieldSchema): DuckDBRow {\n return Object.fromEntries(\n Object.entries(row).map(([name, value]) => {\n const field = schema.fields.find((field) => field.name === name);\n if (value != null && field?.type === \"datetime\") {\n // DuckDB's textual native TIMESTAMP has no suffix; our session profile\n // interprets that storage as UTC, independently of the JS host timezone.\n const text = String(value);\n const canonical =\n /^\\d{4}-\\d{2}-\\d{2}[ T]\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?$/.test(text)\n ? `${text.replace(\" \", \"T\")}Z`\n : text;\n const date =\n typeof value === \"number\" ? new Date(value) : new Date(canonical);\n if (!Number.isFinite(date.getTime()))\n throw Error(`Invalid datetime returned for ${name}.`);\n value = date.toISOString();\n }\n return [name, value];\n }),\n );\n }\n private validateRequest(request: QueryRequestV3): void {\n if (\n request.version !== 3 ||\n request.profile !== DUCKDB_PROFILE ||\n request.diagnostics.length\n )\n throw Error(\"Invalid DuckDB execution request or profile.\");\n if (\n !Number.isSafeInteger(request.now) ||\n Math.abs(request.now) > 8640000000000000\n )\n throw Error(\"Invalid query clock.\");\n if (\n (request.planToken ?? \"\") !==\n (Object.keys(this.execution.fields).length\n ? this.execution.planToken\n : \"\") &&\n request.planToken !== this.execution.planToken\n )\n throw Error(\"DuckDB execution handshake changed.\");\n if ((request.snapshot ?? \"\") !== (this.options.snapshot ?? \"\"))\n throw Error(\"DuckDB snapshot changed.\");\n for (const [key, revision] of Object.entries(request.expectedRevisions))\n if (this.execution.resolvedRevisions[key] !== revision)\n throw Error(\"Computed definitions changed; refresh the handshake.\");\n if (request.metrics.length > 20)\n throw Error(\"At most 20 metrics are allowed.\");\n this.window(request.result);\n const model = createGroupingModel(this.schema);\n if (request.grouping) model.validate(request.grouping);\n const resultSchema = request.grouping\n ? model.resultSchema(request.grouping.keys, request.grouping.summaries)\n : this.schema;\n this.builder(this.schema, request.now).where(request.source.where);\n const result = this.builder(resultSchema, request.now);\n result.where(request.result.where);\n result.order(request.result.orderBy);\n request.result.select.forEach((name) => result.definition(name));\n }\n async execute(\n request: QueryRequestV3,\n signal?: AbortSignal,\n ): Promise<QueryResultV3> {\n this.validateRequest(request);\n return this.transaction(async (tables) => {\n const source = await this.stage(\n request.source,\n request.now,\n tables,\n signal,\n );\n let relation = source.name,\n schema = this.schema;\n if (request.grouping) {\n const grouping = request.grouping,\n model = createGroupingModel(schema),\n builder = this.builder(schema, request.now);\n // A calendar key reads the interval start mapped from its field.\n let from = id(source.name);\n const keys: string[] = [];\n for (const [index, key] of grouping.keys.entries()) {\n if (!isCalendarGroupKey(key)) {\n keys.push(builder.field(key, false));\n continue;\n }\n const mapping = await this.calendarMapping(\n id(source.name),\n builder,\n schema,\n key,\n tables,\n signal,\n );\n const value = id(`qt_calendar_value${index}`),\n bucket = id(`qt_calendar_key${index}`);\n from += ` LEFT JOIN (SELECT value AS ${value}, bucket AS ${bucket} FROM ${id(mapping)}) AS ${id(`qt_calendar_map${index}`)} ON ${value} = CAST(${builder.field(key.field, false)} AS TIMESTAMPTZ)`;\n keys.push(bucket);\n }\n const names = groupKeyFields(grouping.keys).map(id);\n const representative = builder\n .order(\n grouping.representative?.orderBy ?? [\n { field: schema.idField, dir: \"desc\" },\n ],\n false,\n )\n .replace(/^ORDER BY /, \"\");\n const tie = grouping.representative?.orderBy.some(\n (term) => term.field === schema.idField,\n )\n ? \"\"\n : `, ${builder.field(schema.idField)} DESC NULLS LAST`;\n const summaries = grouping.summaries.map(\n (summary) =>\n `${\n summary.op === \"row\"\n ? `first(${builder.field(summary.field!, false)} ORDER BY ${representative}${tie})`\n : builder.expression(model.summaryExpression(summary), true).sql\n } AS ${id(summary.id)}`,\n );\n relation = this.temp(tables);\n const identity = `CAST(to_json(struct_pack(${keys.map((key, i) => `k${i} := ${key}`).join(\", \")})) AS VARCHAR)`;\n await this.run(\n builder.statement(\n `CREATE TEMP TABLE ${id(relation)} AS SELECT ${identity} AS ${id(GROUP_ID_FIELD)}, ${keys.map((key, i) => `${key} AS ${names[i]}`).join(\", \")}${summaries.length ? `, ${summaries.join(\", \")}` : \"\"} FROM ${from} GROUP BY ${keys.join(\", \")}`,\n ),\n signal,\n );\n const [{ n }] = (await this.sql(\n `SELECT COUNT(*) AS n FROM ${id(relation)}`,\n [],\n signal,\n )) as [{ n: number }];\n if (n > this.capabilities.maxGroups)\n throw Error(\"DuckDB grouped row budget exceeded.\");\n schema = model.resultSchema(grouping.keys, grouping.summaries);\n }\n const page = await this.page(\n relation,\n schema,\n request.result,\n request.now,\n signal,\n );\n const metrics = await this.metrics(\n relation,\n schema,\n request.result,\n request.metrics,\n request.now,\n tables,\n signal,\n );\n return {\n version: 3,\n now: request.now,\n sourceTotal: source.count,\n rows: request.rows ? page.rows : [],\n total: page.total,\n schema: {\n name: schema.name,\n idField: schema.idField,\n fields: schema.fields.map((field) => ({\n name: field.name,\n type: field.type,\n })),\n },\n metrics,\n execution: { ...this.execution, planToken: request.planToken ?? \"\" },\n };\n }, signal);\n }\n private async metrics(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n clauses: AggregationClause[],\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<AggregationResultEntry[]> {\n const output: AggregationResultEntry[] = [];\n // A failed DuckDB statement aborts its transaction, and DuckDB has no\n // savepoints. Clauses read only staged temporary relations, so commit\n // them and give each clause its own transaction.\n await this.sql(\"COMMIT\", [], signal);\n for (const clause of clauses) {\n abort(signal);\n const created = tables.length;\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n try {\n const entry = await this.metric(\n relation,\n schema,\n query,\n clause,\n now,\n tables,\n signal,\n );\n await this.sql(\"COMMIT\", [], signal);\n output.push(entry);\n } catch (error) {\n await this.sql(\"ROLLBACK\").catch(() => {});\n // The rollback discarded this clause's scratch relations.\n tables.splice(created);\n abort(signal);\n output.push({\n id: clause.id,\n buckets: [],\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n await this.sql(\"BEGIN TRANSACTION\", [], signal);\n return output;\n }\n /** A temporary (value, bucket) table mapping each distinct non-null value\n * of `config.field` in `population` to the start of its calendar interval,\n * or to its cyclic slot, computed with the core calendar. */\n private async calendarMapping(\n population: string,\n builder: SQLBuilder,\n schema: FieldSchema,\n config: Pick<MetricDateGrouping, \"field\" | \"interval\" | \"timeZone\">,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<string> {\n const source = builder.field(config.field, false),\n cycle = isMetricCycle(config.interval) ? config.interval : undefined;\n const dates = await this.run(\n builder.statement(\n `SELECT DISTINCT CAST(${source} AS VARCHAR) AS value FROM ${population} r WHERE ${source} IS NOT NULL`,\n ),\n signal,\n );\n const mapping = this.temp(tables);\n await this.sql(\n `CREATE TEMP TABLE ${id(mapping)} (value TIMESTAMPTZ, bucket ${cycle ? \"INTEGER\" : \"TIMESTAMPTZ\"})`,\n [],\n signal,\n );\n for (let i = 0; i < dates.length; i += 250) {\n const args: unknown[] = [];\n const values = dates.slice(i, i + 250).map((row) => {\n const value = /^\\d{4}-\\d{2}-\\d{2}$/.test(String(row.value))\n ? String(row.value)\n : (this.formatRow({ [config.field]: row.value }, schema)[\n config.field\n ] as string);\n const floor = metricDateFloor(\n metricDateTime(value, config.timeZone),\n config.interval,\n config.timeZone,\n );\n // A cyclic slot is the local hour or weekday of the record's interval.\n args.push(\n value,\n cycle\n ? metricCycleSlot(floor, cycle, config.timeZone)\n : new Date(floor).toISOString(),\n );\n return `(CAST($${args.length - 1} AS TIMESTAMPTZ), CAST($${args.length} AS ${cycle ? \"INTEGER\" : \"TIMESTAMPTZ\"}))`;\n });\n if (values.length)\n await this.sql(\n `INSERT INTO ${id(mapping)} VALUES ${values.join(\", \")}`,\n args,\n signal,\n );\n }\n return mapping;\n }\n private async metric(\n relation: string,\n schema: FieldSchema,\n query: ServerQuery,\n clause: AggregationClause,\n now: number,\n tables: string[],\n signal?: AbortSignal,\n ): Promise<AggregationResultEntry> {\n // Wire metrics carry active distributions without presentation settings.\n if (clause.distribution && !clause.display)\n clause = { ...clause, display: { kind: clause.distribution.kind } };\n const issues = validateMetric(clause, schema);\n if (issues.length)\n throw Error(issues.map((issue) => issue.message).join(\" \"));\n const builder = this.builder(schema, now),\n where = builder.where(query.where);\n const window =\n clause.scope === \"shownRows\"\n ? `${builder.order(query.orderBy)} LIMIT ${builder.bind(query.limit)} OFFSET ${builder.bind(query.offset)}`\n : \"\";\n let population = `(SELECT * FROM ${id(relation)} WHERE ${where} ${window})`;\n // The metric's own predicate narrows the scoped rows (inside the page for\n // shown-row scope) and never changes the table rows.\n if (clause.where?.length)\n population = `(SELECT * FROM ${population} r WHERE ${builder.where(clause.where)})`;\n if (clause.dateGrouping) {\n const config = clause.dateGrouping;\n const dateMapping = await this.calendarMapping(\n population,\n builder,\n schema,\n config,\n tables,\n signal,\n );\n population = `(SELECT r.* EXCLUDE (${id(config.field)}), m.bucket AS ${id(config.field)} FROM ${population} r LEFT JOIN ${id(dateMapping)} m ON CAST(r.${id(config.field)} AS TIMESTAMPTZ) = m.value)`;\n }\n const keys = clause.groupBy.map((name) => builder.field(name, false)),\n groups = keys.length ? `GROUP BY ${keys.join(\", \")}` : \"\";\n const distribution =\n clause.distribution &&\n [\"box\", \"histogram\"].includes(clause.display?.kind ?? \"\")\n ? clause.distribution\n : undefined;\n const expression = distribution\n ? builder.expression(distribution.input).sql\n : builder.expression(metricExpression(clause), true).sql;\n const projections = keys.map(\n (key, index) => `${key} AS ${id(`g${index}`)}`,\n );\n projections.push(\n \"COUNT(*) AS count\",\n distribution\n ? `list(${expression}) FILTER (WHERE ${expression} IS NOT NULL) AS samples`\n : `${expression} AS value`,\n );\n if (!distribution && clause.display?.kind === \"scatter\")\n projections.push(\n `${builder.expression(clause.expressionY ?? \"COUNT()\", true).sql} AS y`,\n );\n // An object minCount measures each group with its own aggregate.\n const minMeasure = metricMinCountMeasure(clause);\n if (minMeasure)\n projections.push(\n `${builder.expression(metricExpression({ id: \"\", groupBy: [], ...minMeasure }), true).sql} AS min_measure`,\n );\n const rows = await this.run(\n builder.statement(\n `SELECT ${projections.join(\", \")} FROM ${population} r ${groups} LIMIT ${this.capabilities.maxGroups + 1}`,\n ),\n signal,\n );\n if (rows.length > this.capabilities.maxGroups)\n throw Error(\"DuckDB metric group budget exceeded.\");\n if (\n distribution &&\n rows.some(\n (row) =>\n (row.samples as unknown[] | null)?.length &&\n (row.samples as unknown[]).length > this.maxSamples,\n )\n )\n throw Error(\n `The ${distribution.kind} distribution exceeded the ${this.maxSamples.toLocaleString(\"en-US\")}-sample budget${clause.groupBy.length ? \" for one or more groups\" : \"\"}.`,\n );\n const edges =\n distribution?.kind === \"histogram\"\n ? histogramEdges(\n rows.flatMap((row) => (row.samples as number[]) ?? []),\n distribution.bins ?? 10,\n )\n : [];\n const measures = new Map<object, { value: unknown }>();\n const buckets: AggregationResultEntry[\"buckets\"] = rows.map((row) => {\n const samples = (row.samples as number[]) ?? [];\n const bucket: AggregationResultEntry[\"buckets\"][number] = {\n keys: clause.groupBy.map((name, index) => {\n const value = row[`g${index}`] ?? null;\n if (index === 0 && isMetricCycle(clause.dateGrouping?.interval))\n return value === null ? null : Number(value);\n return schema.fields.find((field) => field.name === name)?.type ===\n \"datetime\" && value !== null\n ? (this.formatRow({ [name]: value }, schema)[name] as string)\n : (value as MetricValue);\n }),\n count: row.count as number,\n value: distribution ? null : (row.value as MetricValue),\n ...(row.y !== undefined ? { y: row.y as MetricValue } : {}),\n ...(distribution\n ? {\n nullCount: (row.count as number) - samples.length,\n distribution:\n distribution.kind === \"box\"\n ? {\n kind: \"box\" as const,\n summary: boxSummary(samples, distribution.whiskers),\n }\n : {\n kind: \"histogram\" as const,\n n: samples.length,\n edges,\n counts: histogramCounts(samples, edges),\n },\n }\n : {}),\n };\n if (minMeasure) measures.set(bucket, { value: row.min_measure });\n return bucket;\n });\n if (clause.dateGrouping?.includeEmpty) {\n const config = clause.dateGrouping,\n cycle = isMetricCycle(config.interval) ? config.interval : undefined,\n observed = cycle\n ? []\n : buckets\n .filter((bucket) => bucket.keys[0] !== null)\n .map((bucket) => metricDateTime(bucket.keys[0]!));\n const range = cycle ? undefined : metricDateRange(\n config,\n {\n ...query,\n select: query.select.map((field) => ({ field })),\n } as QueryState,\n observed,\n now,\n (name) => name,\n );\n const series = new Map(\n buckets\n .filter((bucket) => bucket.keys[0] !== null)\n .map((bucket) => [\n JSON.stringify(bucket.keys.slice(1)),\n bucket.keys.slice(1),\n ]),\n );\n if (keys.length === 1 && !series.size) series.set(\"[]\", []);\n const existing = new Set(\n buckets.map((bucket) => JSON.stringify(bucket.keys)),\n );\n // Every slot of a cycle exists, whatever the date range.\n const slots: MetricValue[] = cycle ? metricCycleSlots(cycle) : [];\n if (range)\n for (\n let time = range[0];\n time <= range[1];\n time = metricDateNext(time, config.interval, config.timeZone)\n )\n slots.push(new Date(time).toISOString());\n for (const slot of slots)\n for (const tuple of series.values()) {\n const values = [slot, ...tuple];\n if (!existing.has(JSON.stringify(values))) {\n if (buckets.length >= this.capabilities.maxGroups)\n throw Error(\"DuckDB calendar group budget exceeded.\");\n buckets.push({\n keys: values,\n count: 0,\n value:\n (!clause.expression &&\n [\"count\", \"count_distinct\", \"sum\"].includes(clause.op)) ||\n /^(COUNT|COUNT_DISTINCT|SUM)\\([^)]*\\)$/.test(\n metricExpression(clause),\n )\n ? 0\n : null,\n });\n }\n }\n }\n // Calendar fill-ins (count 0) are never hidden; hidden groups leave the\n // ranking, the group limit and Other.\n let hiddenGroups: number | undefined;\n const min = metricMinCount(clause);\n if (min !== undefined) {\n const kept = buckets.filter((bucket) =>\n metricMinCountKeeps(min, bucket.count, measures.get(bucket)),\n );\n hiddenGroups = buckets.length - kept.length;\n buckets.splice(0, buckets.length, ...kept);\n }\n // Calendar metrics default to chronological order, like the other engines.\n const sort: MetricSort[] = clause.sort?.length\n ? clause.sort\n : clause.dateGrouping\n ? [{ key: \"group0\", dir: \"asc\", nulls: \"last\" }]\n : [{ key: \"value\", dir: \"desc\" }];\n buckets.sort((a, b) => {\n for (const term of sort) {\n const value = (bucket: typeof a): MetricValue =>\n term.key.startsWith(\"group\")\n ? (bucket.keys[Number(term.key.slice(5))] ?? null)\n : term.key === \"samples\"\n ? bucket.distribution?.kind === \"box\"\n ? (bucket.distribution.summary?.n ?? 0)\n : (bucket.distribution?.n ?? 0)\n : ((bucket as unknown as Record<string, MetricValue>)[term.key] ??\n null);\n const av = value(a),\n bv = value(b);\n if (av === null || bv === null) {\n if (av !== bv)\n return (av === null ? 1 : -1) * (term.nulls === \"first\" ? -1 : 1);\n } else {\n const result = compareMetricValues(av, bv);\n if (result) return result * (term.dir === \"asc\" ? 1 : -1);\n }\n }\n return JSON.stringify(a.keys).localeCompare(JSON.stringify(b.keys));\n });\n const limit = clause.groupLimit ?? 10000;\n return {\n id: clause.id,\n buckets: buckets.slice(0, limit),\n groupCount: buckets.length,\n coverage: buckets.length > limit ? \"partial\" : \"exact\",\n ...(clause.scope ? { scope: clause.scope } : {}),\n ...(hiddenGroups !== undefined ? { hiddenGroups } : {}),\n };\n }\n transport(): Transport<DuckDBRow> {\n return {\n queryCapabilities: this.capabilities,\n metricCapabilities: {\n version: 2,\n expressions: true,\n shownRows: true,\n distributions: true,\n computedFields: this.computed.size > 0,\n filters: true,\n minCount: true,\n minCountMeasures: true,\n profile: DUCKDB_PROFILE,\n maxGroups: this.capabilities.maxGroups,\n },\n fetchQueryV3: (request, signal) => this.execute(request, signal),\n fetchRows: (query, signal) =>\n this.transaction(async (tables) => {\n this.window(query);\n const source = await this.stage(query, Date.now(), tables, signal);\n return this.page(\n source.name,\n this.schema,\n { ...query, where: [] },\n Date.now(),\n signal,\n );\n }, signal),\n fetchMetrics: (query: MetricQuery, signal) => {\n if (\n query.diagnostics.length ||\n (query.profile && query.profile !== DUCKDB_PROFILE) ||\n query.metrics.length > 20\n )\n return Promise.reject(Error(\"Invalid DuckDB metric request.\"));\n return this.transaction(async (tables) => {\n const now = Date.now(),\n server = { ...query, select: [] };\n const source = await this.stage(server, now, tables, signal);\n return {\n metrics: await this.metrics(\n source.name,\n this.schema,\n server,\n query.metrics,\n now,\n tables,\n signal,\n ),\n };\n }, signal);\n },\n fetchAggregations: (query, signal) =>\n this.transaction(async (tables) => {\n if (query.diagnostics?.length || query.aggregations.length > 20)\n throw Error(\"Invalid DuckDB aggregation request.\");\n const server = {\n select: [],\n where: query.where,\n orderBy: [],\n limit: 100,\n offset: 0,\n },\n now = Date.now();\n const source = await this.stage(server, now, tables, signal);\n return {\n metrics: await this.metrics(\n source.name,\n this.schema,\n { ...server, where: [] },\n query.aggregations,\n now,\n tables,\n signal,\n ),\n };\n }, signal),\n fetchDistinctValues: (query, signal) =>\n this.serial(async () => {\n const builder = this.builder(),\n field = builder.definition(query.field),\n limit = positive(query.limit, 50, 500);\n if (!isFilterable(field))\n throw Error(`Field ${field.name} is not filterable.`);\n if (query.search.length > 2000)\n throw Error(\"Distinct search exceeds its budget.\");\n const source = this.projectedSource(Date.now()),\n value = builder.field(query.field),\n array = field.type === \"textarray\";\n builder.args.push(...source.args);\n const param = builder.bind(query.search);\n const rows = await this.run(\n builder.statement(\n `SELECT CAST(value AS VARCHAR) AS value, COUNT(*) AS n FROM (SELECT ${array ? `unnest(${value})` : value} AS value FROM (${source.sql}) r) v WHERE value IS NOT NULL AND contains(lower(CAST(value AS VARCHAR)), lower(${param})) GROUP BY value ORDER BY n DESC, value ASC LIMIT ${limit + 1}`,\n ),\n signal,\n );\n const [{ n }] = (await this.sql(\n `SELECT COUNT(*) AS n FROM (${source.sql}) r WHERE ${array ? `COALESCE(len(${value}),0) = 0` : `${value} IS NULL`}`,\n source.args,\n signal,\n )) as [{ n: number }];\n return {\n values: rows.slice(0, limit).map((row) => String(row.value)),\n hasMore: rows.length > limit,\n hasNull: n > 0,\n };\n }, signal),\n fetchRow: (identity, signal) =>\n this.serial(async () => {\n const source = this.projectedSource(Date.now());\n const rows = await this.sql(\n `SELECT * FROM (${source.sql}) r WHERE ${id(this.schema.idField)} = $${source.args.length + 1} LIMIT 2`,\n [...source.args, identity],\n signal,\n );\n if (rows.length > 1) throw Error(\"DuckDB identity must be unique.\");\n return rows[0] ? this.formatRow(rows[0], this.schema) : null;\n }, signal),\n fetchFieldStats: (fields, signal) =>\n this.serial(async () => {\n if (fields.length > 64)\n throw Error(\"At most 64 field stats can be requested.\");\n const stats: Record<\n string,\n import(\"@pythia-software/query-table-core\").FieldStats\n > = {};\n for (const name of fields) {\n const builder = this.builder(),\n field = builder.definition(name),\n source = this.projectedSource(Date.now()),\n value = builder.field(name);\n const rows = await this.sql(\n field.type === \"textarray\"\n ? `SELECT COUNT(DISTINCT value) AS \"distinct\" FROM (SELECT unnest(${value}) AS value FROM (${source.sql}) r)`\n : `SELECT COUNT(DISTINCT ${value}) AS \"distinct\", MIN(${value}) AS min, MAX(${value}) AS max FROM (${source.sql}) r`,\n source.args,\n signal,\n );\n const result = rows[0]!;\n stats[name] = {\n distinct: result.distinct as number,\n ...(typeof result.min === \"number\" ||\n typeof result.min === \"string\"\n ? { min: result.min }\n : {}),\n ...(typeof result.max === \"number\" ||\n typeof result.max === \"string\"\n ? { max: result.max }\n : {}),\n };\n }\n return stats;\n }, signal),\n };\n }\n}\n\nexport function createDuckDBTransport(\n options: DuckDBOptions,\n): Transport<DuckDBRow> {\n return new DuckDBBackend(options).transport();\n}\n","import type { DuckDBConnection, DuckDBRow } from \"./backend\";\n\n/** Structural adapter keeps duckdb-wasm optional and out of native bundles. */\nexport interface DuckDBWasmConnection {\n query(sql: string): Promise<{ toArray(): { toJSON(): unknown }[] }>;\n prepare(sql: string): Promise<{\n query(...args: any[]): Promise<{ toArray(): { toJSON(): unknown }[] }>;\n close(): Promise<void>;\n }>;\n}\nexport function fromDuckDBWasmConnection(\n connection: DuckDBWasmConnection,\n): DuckDBConnection {\n return {\n async query(sql, args) {\n if (!args.length)\n return (await connection.query(sql))\n .toArray()\n .map((row) => row.toJSON() as DuckDBRow);\n const statement = await connection.prepare(sql);\n try {\n return (await statement.query(...args))\n .toArray()\n .map((row) => row.toJSON() as DuckDBRow);\n } finally {\n await statement.close();\n }\n },\n };\n}\n","import {\n loadSchema,\n type FieldSchema,\n} from \"@pythia-software/query-table-core\";\n\n/** Read explicit DuckDB bindings; never reuse another engine's SQL. */\nexport function loadDuckDBSchema(document: unknown): {\n schema: FieldSchema;\n bindings: Record<string, string>;\n} {\n const schema = loadSchema(document);\n const raw = document as {\n fields: { name: string; bindings?: { duckdb?: { expr?: unknown } } }[];\n };\n const bindings: Record<string, string> = Object.create(null);\n for (const field of schema.fields) {\n if (field.source.kind !== \"backend\") continue;\n const binding = raw.fields.find((item) => item.name === field.name)\n ?.bindings?.duckdb;\n if (\n !binding ||\n typeof binding.expr !== \"string\" ||\n !binding.expr.trim() ||\n binding.expr.includes(\"\\0\")\n )\n throw Error(\n `Field ${field.name} requires an explicit bindings.duckdb.expr.`,\n );\n bindings[field.name] = binding.expr;\n }\n return { schema, bindings };\n}\n"],"mappings":"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","names":["field","compileFormula","isSelectable","isFilterable","compileFormula","isSelectable","field","isFilterable"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pythia-software/query-table-duckdb",
3
- "version": "0.9.6",
3
+ "version": "0.9.7",
4
4
  "description": "Schema-bound DuckDB execution for Query Table, in Node.js or the browser.",
5
5
  "license": "MIT",
6
6
  "author": "Pythia Software",
@@ -41,6 +41,6 @@
41
41
  "prepack": "npm run build"
42
42
  },
43
43
  "dependencies": {
44
- "@pythia-software/query-table-core": "0.9.6"
44
+ "@pythia-software/query-table-core": "0.9.7"
45
45
  }
46
46
  }