@minnowdb/core 0.6.9 → 0.7.1

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.
Files changed (103) hide show
  1. package/dist/block-format/block.js +254 -325
  2. package/dist/block-format/checksum.js +30 -52
  3. package/dist/block-format/codecs.js +112 -125
  4. package/dist/block-format/column.js +187 -205
  5. package/dist/block-format/index.js +5 -1
  6. package/dist/block-format/physical.js +371 -387
  7. package/dist/block-format/types.js +4 -1
  8. package/dist/block-format/unicode.js +30 -39
  9. package/dist/date-value.d.ts +5 -0
  10. package/dist/date-value.js +71 -41
  11. package/dist/engine/artifact-cache.js +106 -116
  12. package/dist/engine/batch.js +36 -44
  13. package/dist/engine/buffered-writer.js +156 -158
  14. package/dist/engine/byte-estimates.js +20 -22
  15. package/dist/engine/cache-limits.js +24 -25
  16. package/dist/engine/cancellation.js +5 -3
  17. package/dist/engine/catalog.js +64 -73
  18. package/dist/engine/client.js +715 -780
  19. package/dist/engine/database.js +15952 -18465
  20. package/dist/engine/defaults.js +104 -111
  21. package/dist/engine/errors.js +113 -128
  22. package/dist/engine/fts.js +233 -280
  23. package/dist/engine/group-index.js +287 -321
  24. package/dist/engine/index.js +23 -12
  25. package/dist/engine/join-index.js +177 -186
  26. package/dist/engine/keyed-live.js +168 -173
  27. package/dist/engine/live-api.js +0 -1
  28. package/dist/engine/live-equal.js +32 -37
  29. package/dist/engine/live.js +603 -647
  30. package/dist/engine/memory.js +109 -111
  31. package/dist/engine/optimizer.d.ts +19 -1
  32. package/dist/engine/optimizer.js +2642 -2515
  33. package/dist/engine/point-read.d.ts +4 -2
  34. package/dist/engine/point-read.js +121 -171
  35. package/dist/engine/query-api.js +12 -3
  36. package/dist/engine/query-cache.js +61 -69
  37. package/dist/engine/query.d.ts +45 -0
  38. package/dist/engine/query.js +8506 -9375
  39. package/dist/engine/result-wire.js +221 -252
  40. package/dist/engine/schema-wire.js +97 -112
  41. package/dist/engine/schema.js +1099 -1254
  42. package/dist/engine/sort-keys.js +315 -389
  43. package/dist/engine/sql-domains.d.ts +7 -1
  44. package/dist/engine/sql-domains.js +648 -734
  45. package/dist/engine/sql-driver.js +0 -1
  46. package/dist/engine/sql-functions.d.ts +11 -0
  47. package/dist/engine/sql-functions.js +1092 -0
  48. package/dist/engine/sql-json.js +199 -218
  49. package/dist/engine/sql-semantics.d.ts +25 -4
  50. package/dist/engine/sql-semantics.js +579 -513
  51. package/dist/engine/typed-live.js +271 -293
  52. package/dist/engine/vector.d.ts +7 -1
  53. package/dist/engine/vector.js +4513 -4580
  54. package/dist/engine/worker-host.d.ts +8 -63
  55. package/dist/engine/worker-host.js +28 -1130
  56. package/dist/engine/worker-indexeddb.d.ts +1 -0
  57. package/dist/engine/worker-indexeddb.js +3 -0
  58. package/dist/engine/worker-memory.d.ts +1 -0
  59. package/dist/engine/worker-memory.js +3 -0
  60. package/dist/engine/worker-opfs.d.ts +1 -0
  61. package/dist/engine/worker-opfs.js +3 -0
  62. package/dist/engine/worker-server.d.ts +93 -0
  63. package/dist/engine/worker-server.js +999 -0
  64. package/dist/engine/worker-store-indexeddb.d.ts +2 -0
  65. package/dist/engine/worker-store-indexeddb.js +11 -0
  66. package/dist/engine/worker-store-memory.d.ts +2 -0
  67. package/dist/engine/worker-store-memory.js +6 -0
  68. package/dist/engine/worker-store-opfs.d.ts +2 -0
  69. package/dist/engine/worker-store-opfs.js +9 -0
  70. package/dist/engine/worker.js +0 -12
  71. package/dist/engine/write-block-planner.js +93 -100
  72. package/dist/plan/index.js +15 -16
  73. package/dist/plan/model.d.ts +9 -1
  74. package/dist/plan/model.js +20 -27
  75. package/dist/storage/index.js +0 -12
  76. package/dist/storage/indexeddb.js +11776 -13171
  77. package/dist/storage/memory.js +1198 -1241
  78. package/dist/storage/opfs/files.js +238 -295
  79. package/dist/storage/opfs/index.js +9 -3
  80. package/dist/storage/opfs/leader.js +4386 -4856
  81. package/dist/storage/opfs/rpc.js +223 -259
  82. package/dist/storage/opfs/snapshot-ledger.js +219 -260
  83. package/dist/storage/opfs/store.js +884 -1003
  84. package/dist/storage/persistence.js +59 -74
  85. package/dist/storage/snapshot-stream.js +788 -826
  86. package/dist/storage/snapshot.js +36 -37
  87. package/dist/storage/toolkit/extents.js +444 -520
  88. package/dist/storage/toolkit/index.js +28 -29
  89. package/dist/storage/toolkit/record-core.js +5792 -6377
  90. package/dist/storage/toolkit/sync-file.js +34 -42
  91. package/dist/storage/toolkit/wal.js +92 -127
  92. package/dist/storage/toolkit/wire.js +232 -256
  93. package/dist/storage/types.js +2952 -3228
  94. package/dist/testing/block-store-conformance.js +1556 -1629
  95. package/dist/testing/index.js +310 -291
  96. package/dist/testing/opfs-shim.js +280 -312
  97. package/dist/testing/simulator.js +496 -534
  98. package/dist/testing/sqllogictest.js +425 -365
  99. package/dist/transactions/index.js +1464 -1712
  100. package/dist/worker-protocol/index.js +70 -69
  101. package/package.json +20 -2
  102. package/postgres-feature-profile.json +15 -5
  103. package/sql-feature-matrix.json +252 -2
@@ -9,10 +9,11 @@ export interface PointReadShape {
9
9
  /** Conjunctive equalities, in predicate order; may repeat a column. */
10
10
  equalities: PointReadEquality[];
11
11
  /** Plain column projections, in select order. */
12
+ /** Projected columns, or "*" for a bare wildcard the catalog expands at execution. */
12
13
  select: Array<{
13
14
  column: string;
14
15
  alias: string;
15
- }>;
16
+ }> | "*";
16
17
  }
17
18
  /** The statement-shaped half of the analysis, computed once per cached plan. */
18
19
  interface PointReadTemplate {
@@ -24,10 +25,11 @@ interface PointReadTemplate {
24
25
  column: string;
25
26
  parameter: number;
26
27
  }>;
28
+ /** Projected columns, or "*" for a bare wildcard the catalog expands at execution. */
27
29
  select: Array<{
28
30
  column: string;
29
31
  alias: string;
30
- }>;
32
+ }> | "*";
31
33
  }
32
34
  /**
33
35
  * Test-only escape hatch and counters. Not exported from any public entry point: in-repo
@@ -1,190 +1,140 @@
1
- /**
2
- * Shape analysis for the keyed point-read fast path: a single-table conjunction of
3
- * column-equals-literal predicates that covers the table's unique key, projecting bare
4
- * columns — plain or logical-domain typed, since domain scalars externalize through the
5
- * same result boundary. Such a statement addresses at most one row, so execution can skip parameter
6
- * binding, plan cloning, streamed-view construction, and the vector pipeline entirely and
7
- * answer from cached decoded blocks. Anything this module cannot prove eligible falls back to
8
- * the ordinary executor, which stays the authority on errors and semantics.
9
- */
10
1
  import { dateMilliseconds } from "../date-value.js";
11
- /**
12
- * Test-only escape hatch and counters. Not exported from any public entry point: in-repo
13
- * differential suites import this module directly to force the ordinary executor and to
14
- * assert the fast path actually served eligible statements.
15
- */
16
- export const pointReadTestHooks = {
17
- disabled: false,
18
- attempted: 0,
19
- served: 0,
2
+ const pointReadTestHooks = {
3
+ disabled: false,
4
+ attempted: 0,
5
+ served: 0
20
6
  };
21
7
  const DUAL_TABLE = "(dual)";
22
- /** A base-table column reference: bare, or qualified by the base source's alias. */
23
8
  function baseColumnReference(expression, alias) {
24
- if (expression.kind !== "column")
25
- return undefined;
26
- const reference = expression.reference;
27
- const dot = reference.indexOf(".");
28
- if (dot < 0)
29
- return reference;
30
- if (reference.slice(0, dot) !== alias)
31
- return undefined;
32
- const column = reference.slice(dot + 1);
33
- // A nested qualifier ("a.b.c") is not a base-table column.
34
- return column.includes(".") ? undefined : column;
9
+ if (expression.kind !== "column")
10
+ return void 0;
11
+ const reference = expression.reference;
12
+ const dot = reference.indexOf(".");
13
+ if (dot < 0)
14
+ return reference;
15
+ if (reference.slice(0, dot) !== alias)
16
+ return void 0;
17
+ const column = reference.slice(dot + 1);
18
+ return column.includes(".") ? void 0 : column;
35
19
  }
36
- /** A usable equality operand: a plain non-null literal of a storage type, verified exactly. */
37
20
  function equalityValue(value) {
38
- if (value === null)
39
- return undefined;
40
- if (typeof value === "number" && !Number.isFinite(value))
41
- return undefined;
42
- // Strings in the engine's protected NUL namespace are wrapped at the write boundary, so a
43
- // raw comparison against stored bytes would not reproduce the ordinary path's answer.
44
- if (typeof value === "string" && value.startsWith("\u0000"))
45
- return undefined;
46
- // The internal-slot read never invokes caller-controlled Date methods.
47
- if (value instanceof Date && Number.isNaN(dateMilliseconds(value)))
48
- return undefined;
49
- return value;
21
+ if (value === null)
22
+ return void 0;
23
+ if (typeof value === "number" && !Number.isFinite(value))
24
+ return void 0;
25
+ if (typeof value === "string" && value.startsWith("\0"))
26
+ return void 0;
27
+ if (value instanceof Date && Number.isNaN(dateMilliseconds(value)))
28
+ return void 0;
29
+ return value;
50
30
  }
51
31
  function templateEquality(expression) {
52
- if (expression.kind === "parameter")
53
- return { parameter: expression.index };
54
- if (expression.kind !== "literal")
55
- return undefined;
56
- // Tagged internal values and logical-domain literals compare under domain rules the fast
57
- // path does not implement; a NULL literal never equals anything.
58
- if (expression.internalSqlValue === true || expression.sqlDomain !== undefined)
59
- return undefined;
60
- const value = equalityValue(expression.value);
61
- return value === undefined ? undefined : { value };
32
+ if (expression.kind === "parameter")
33
+ return { parameter: expression.index };
34
+ if (expression.kind !== "literal")
35
+ return void 0;
36
+ if (expression.internalSqlValue === true || expression.sqlDomain !== void 0)
37
+ return void 0;
38
+ const value = equalityValue(expression.value);
39
+ return value === void 0 ? void 0 : { value };
62
40
  }
63
- /**
64
- * Recognizes the eligible statement shape. Purely syntactic: catalog checks (column existence,
65
- * types, key coverage, view expansion, physical history) belong to the caller, which falls
66
- * back to the ordinary executor whenever they cannot be proven.
67
- */
68
41
  function pointReadTemplate(plan) {
69
- const base = plan.base;
70
- if (base.table === DUAL_TABLE ||
71
- base.derived !== undefined ||
72
- base.union !== undefined ||
73
- base.recursive !== undefined ||
74
- base.windowed !== undefined ||
75
- base.lateral === true ||
76
- base.columnAliases !== undefined ||
77
- plan.joins.length > 0 ||
78
- plan.groupBy.length > 0 ||
79
- plan.having.length > 0 ||
80
- plan.orderBy.length > 0 ||
81
- plan.select.length === 0 ||
82
- plan.predicates.length === 0 ||
83
- plan.limit !== undefined ||
84
- plan.offset !== undefined ||
85
- plan.limitParameter !== undefined ||
86
- plan.offsetParameter !== undefined ||
87
- (plan.limitValidationParameters?.length ?? 0) > 0 ||
88
- (plan.offsetValidationParameters?.length ?? 0) > 0 ||
89
- plan.limitWithTies === true ||
90
- plan.distinctWildcard === true ||
91
- plan.usesStatementDatetime === true ||
92
- plan.usesSequenceCalls === true ||
93
- plan.usesVolatileFunctions === true) {
94
- return undefined;
95
- }
96
- const select = [];
42
+ const base = plan.base;
43
+ if (base.table === DUAL_TABLE || base.derived !== void 0 || base.union !== void 0 || base.recursive !== void 0 || base.windowed !== void 0 || base.lateral === true || base.columnAliases !== void 0 || plan.joins.length > 0 || plan.groupBy.length > 0 || plan.having.length > 0 || plan.orderBy.length > 0 || plan.select.length === 0 || plan.predicates.length === 0 || plan.limit !== void 0 || plan.offset !== void 0 || plan.limitParameter !== void 0 || plan.offsetParameter !== void 0 || (plan.limitValidationParameters?.length ?? 0) > 0 || (plan.offsetValidationParameters?.length ?? 0) > 0 || plan.limitWithTies === true || plan.distinctWildcard === true || plan.usesStatementDatetime === true || plan.usesSequenceCalls === true || plan.usesVolatileFunctions === true) {
44
+ return void 0;
45
+ }
46
+ let select = [];
47
+ const first = plan.select[0];
48
+ if (plan.select.length === 1 && first?.expression.kind === "wildcard" && (first.expression.table === void 0 || first.expression.table === base.alias)) {
49
+ select = "*";
50
+ } else {
97
51
  for (const item of plan.select) {
98
- const column = baseColumnReference(item.expression, base.alias);
99
- if (column === undefined)
100
- return undefined;
101
- select.push({ column, alias: item.alias });
102
- }
103
- const equalities = [];
104
- for (const predicate of plan.predicates) {
105
- if (predicate.operator !== "=" || predicate.escape !== undefined)
106
- return undefined;
107
- const leftColumn = baseColumnReference(predicate.left, base.alias);
108
- const rightColumn = baseColumnReference(predicate.right, base.alias);
109
- const operand = leftColumn !== undefined && rightColumn === undefined
110
- ? templateEquality(predicate.right)
111
- : rightColumn !== undefined && leftColumn === undefined
112
- ? templateEquality(predicate.left)
113
- : undefined;
114
- const column = leftColumn ?? rightColumn;
115
- if (operand === undefined || column === undefined)
116
- return undefined;
117
- equalities.push({ column, ...operand });
52
+ const column = baseColumnReference(item.expression, base.alias);
53
+ if (column === void 0)
54
+ return void 0;
55
+ select.push({ column, alias: item.alias });
118
56
  }
119
- return { table: base.table, equalities, select };
57
+ }
58
+ const equalities = [];
59
+ for (const predicate of plan.predicates) {
60
+ if (predicate.operator !== "=" || predicate.escape !== void 0)
61
+ return void 0;
62
+ const leftColumn = baseColumnReference(predicate.left, base.alias);
63
+ const rightColumn = baseColumnReference(predicate.right, base.alias);
64
+ const operand = leftColumn !== void 0 && rightColumn === void 0 ? templateEquality(predicate.right) : rightColumn !== void 0 && leftColumn === void 0 ? templateEquality(predicate.left) : void 0;
65
+ const column = leftColumn ?? rightColumn;
66
+ if (operand === void 0 || column === void 0)
67
+ return void 0;
68
+ equalities.push({ column, ...operand });
69
+ }
70
+ return { table: base.table, equalities, select };
120
71
  }
121
- const templates = new WeakMap();
122
- /** The template for a cached compiled plan, analyzed once per statement. */
123
- export function cachedPointReadTemplate(plan) {
124
- const cached = templates.get(plan);
125
- if (cached !== undefined)
126
- return cached;
127
- const template = pointReadTemplate(plan) ?? null;
128
- templates.set(plan, template);
129
- return template;
72
+ const templates = /* @__PURE__ */ new WeakMap();
73
+ function cachedPointReadTemplate(plan) {
74
+ const cached = templates.get(plan);
75
+ if (cached !== void 0)
76
+ return cached;
77
+ const template = pointReadTemplate(plan) ?? null;
78
+ templates.set(plan, template);
79
+ return template;
130
80
  }
131
- /**
132
- * Substitutes this call's parameters into the statement template. Undefined means a parameter
133
- * carries a value the fast path cannot compare exactly (NULL, a non-finite number, an invalid
134
- * Date, or a non-storage value), and the ordinary executor must decide what it means.
135
- */
136
- export function resolvePointReadShape(template, params) {
137
- const equalities = [];
138
- for (const entry of template.equalities) {
139
- if ("value" in entry) {
140
- equalities.push(entry);
141
- continue;
142
- }
143
- const raw = params[entry.parameter];
144
- if (raw === undefined)
145
- return undefined;
146
- const value = equalityValue(raw);
147
- if (value === undefined)
148
- return undefined;
149
- equalities.push({ column: entry.column, value });
81
+ function resolvePointReadShape(template, params) {
82
+ const equalities = [];
83
+ for (const entry of template.equalities) {
84
+ if ("value" in entry) {
85
+ equalities.push(entry);
86
+ continue;
150
87
  }
151
- return { table: template.table, equalities, select: template.select };
88
+ const raw = params[entry.parameter];
89
+ if (raw === void 0)
90
+ return void 0;
91
+ const value = equalityValue(raw);
92
+ if (value === void 0)
93
+ return void 0;
94
+ equalities.push({ column: entry.column, value });
95
+ }
96
+ return { table: template.table, equalities, select: template.select };
152
97
  }
153
- const ascendingRuns = new WeakMap();
154
- /** Whether the array is non-strictly ascending; memoized per immutable decoded array. */
155
- export function valuesAreAscending(values) {
156
- const cached = ascendingRuns.get(values);
157
- if (cached !== undefined)
158
- return cached;
159
- let ascending = true;
160
- for (let index = 1; index < values.length; index += 1) {
161
- if ((values[index] ?? 0) < (values[index - 1] ?? 0)) {
162
- ascending = false;
163
- break;
164
- }
98
+ const ascendingRuns = /* @__PURE__ */ new WeakMap();
99
+ function valuesAreAscending(values) {
100
+ const cached = ascendingRuns.get(values);
101
+ if (cached !== void 0)
102
+ return cached;
103
+ let ascending = true;
104
+ for (let index = 1; index < values.length; index += 1) {
105
+ if ((values[index] ?? 0) < (values[index - 1] ?? 0)) {
106
+ ascending = false;
107
+ break;
165
108
  }
166
- ascendingRuns.set(values, ascending);
167
- return ascending;
109
+ }
110
+ ascendingRuns.set(values, ascending);
111
+ return ascending;
168
112
  }
169
- /** The [begin, end) run of slots equal to `target` over an ascending array. */
170
- export function equalRunRange(values, target) {
171
- let low = 0;
172
- let high = values.length;
173
- while (low < high) {
174
- const middle = (low + high) >>> 1;
175
- if ((values[middle] ?? 0) < target)
176
- low = middle + 1;
177
- else
178
- high = middle;
179
- }
180
- const begin = low;
181
- high = values.length;
182
- while (low < high) {
183
- const middle = (low + high) >>> 1;
184
- if ((values[middle] ?? 0) <= target)
185
- low = middle + 1;
186
- else
187
- high = middle;
188
- }
189
- return { begin, end: low };
113
+ function equalRunRange(values, target) {
114
+ let low = 0;
115
+ let high = values.length;
116
+ while (low < high) {
117
+ const middle = low + high >>> 1;
118
+ if ((values[middle] ?? 0) < target)
119
+ low = middle + 1;
120
+ else
121
+ high = middle;
122
+ }
123
+ const begin = low;
124
+ high = values.length;
125
+ while (low < high) {
126
+ const middle = low + high >>> 1;
127
+ if ((values[middle] ?? 0) <= target)
128
+ low = middle + 1;
129
+ else
130
+ high = middle;
131
+ }
132
+ return { begin, end: low };
190
133
  }
134
+ export {
135
+ cachedPointReadTemplate,
136
+ equalRunRange,
137
+ pointReadTestHooks,
138
+ resolvePointReadShape,
139
+ valuesAreAscending
140
+ };
@@ -1,3 +1,12 @@
1
- /** SQL compilation, standalone execution, and plan inspection for tooling and adapters. */
2
- export { bindPlanParameters, bindStatementParameters, compileQuery, compileStatement, executeQuery, referencedColumns, } from "./query.js";
3
- export { optimizePlan, renderPlan } from "./optimizer.js";
1
+ import { bindPlanParameters, bindStatementParameters, compileQuery, compileStatement, executeQuery, referencedColumns } from "./query.js";
2
+ import { optimizePlan, renderPlan } from "./optimizer.js";
3
+ export {
4
+ bindPlanParameters,
5
+ bindStatementParameters,
6
+ compileQuery,
7
+ compileStatement,
8
+ executeQuery,
9
+ optimizePlan,
10
+ referencedColumns,
11
+ renderPlan
12
+ };
@@ -2,78 +2,70 @@ import { copyDate, dateMilliseconds } from "../date-value.js";
2
2
  import { estimateValuesBytes } from "./byte-estimates.js";
3
3
  import { copyQueryResultExternalization } from "./query.js";
4
4
  import { defineSqlResultProperty } from "./sql-semantics.js";
5
- /** Modest per-entry cap so one giant result cannot thrash the shared artifact cache. */
6
- export const RESULT_MEMO_MAX_BYTES = 4 * 1024 * 1024;
7
- /** Stable, collision-free memo-key encoding for bound SQL parameters. */
8
- export function queryResultMemoKey(sql, params) {
9
- return JSON.stringify([sql, params.map(encodeParameter)]);
5
+ const RESULT_MEMO_MAX_BYTES = 4 * 1024 * 1024;
6
+ function queryResultMemoKey(sql, params) {
7
+ return JSON.stringify([sql, params.map(encodeParameter)]);
10
8
  }
11
- /**
12
- * A memo key for a compiled plan: its JSON with the values JSON cannot tell apart made
13
- * distinct — a Date from its ISO string, -0 from 0, NaN and the infinities from null — so two
14
- * plans with the same key are the same query over the same literals.
15
- */
16
- export function planMemoKey(plan) {
17
- return JSON.stringify(plan, (_key, value) => {
18
- if (value instanceof Date)
19
- return { $date: dateMilliseconds(value) };
20
- if (typeof value === "bigint")
21
- return { $bigint: value.toString() };
22
- if (typeof value === "number") {
23
- if (Object.is(value, -0))
24
- return { $number: "-0" };
25
- if (!Number.isFinite(value))
26
- return { $number: String(value) };
27
- }
28
- return value;
29
- });
9
+ function planMemoKey(plan) {
10
+ return JSON.stringify(plan, (_key, value) => {
11
+ if (value instanceof Date)
12
+ return { $date: dateMilliseconds(value) };
13
+ if (typeof value === "bigint")
14
+ return { $bigint: value.toString() };
15
+ if (typeof value === "number") {
16
+ if (Object.is(value, -0))
17
+ return { $number: "-0" };
18
+ if (!Number.isFinite(value))
19
+ return { $number: String(value) };
20
+ }
21
+ return value;
22
+ });
30
23
  }
31
- /**
32
- * Defensive copy because callers own query results and may mutate both rows and Dates. Object
33
- * spread copies own enumerable properties with define semantics, so a column named `__proto__`
34
- * stays an own property; only a Date cell needs the explicit define, and only because its
35
- * value is replaced. This used to define every cell, which made a memo hit on a result of a
36
- * few thousand rows cost more than re-executing the query.
37
- */
38
- export function copyQueryResult(result) {
39
- const columns = result.columns;
40
- const copy = {
41
- columns: [...columns],
42
- columnDomains: structuredClone(result.columnDomains),
43
- rows: result.rows.map((row) => {
44
- const copy = { ...row };
45
- for (const name of columns) {
46
- const value = copy[name];
47
- if (value instanceof Date)
48
- defineSqlResultProperty(copy, name, copyDate(value));
49
- }
50
- return copy;
51
- }),
52
- };
53
- return copyQueryResultExternalization(result, copy);
24
+ function copyQueryResult(result) {
25
+ const columns = result.columns;
26
+ const copy = {
27
+ columns: [...columns],
28
+ columnDomains: structuredClone(result.columnDomains),
29
+ rows: result.rows.map((row) => {
30
+ const copy2 = { ...row };
31
+ for (const name of columns) {
32
+ const value = copy2[name];
33
+ if (value instanceof Date)
34
+ defineSqlResultProperty(copy2, name, copyDate(value));
35
+ }
36
+ return copy2;
37
+ })
38
+ };
39
+ return copyQueryResultExternalization(result, copy);
54
40
  }
55
- /** Modeled retained payload for one cached query result. */
56
- export function queryResultRetainedBytes(result) {
57
- let bytes = 64;
58
- for (const column of result.columns)
59
- bytes += 16 + column.length * 2;
60
- for (const row of result.rows)
61
- bytes += estimateValuesBytes(Object.values(row));
62
- return bytes;
41
+ function queryResultRetainedBytes(result) {
42
+ let bytes = 64;
43
+ for (const column of result.columns)
44
+ bytes += 16 + column.length * 2;
45
+ for (const row of result.rows)
46
+ bytes += estimateValuesBytes(Object.values(row));
47
+ return bytes;
63
48
  }
64
49
  function encodeParameter(value) {
65
- if (value === null)
66
- return [0];
67
- if (typeof value === "boolean")
68
- return [1, value];
69
- if (typeof value === "number") {
70
- if (Object.is(value, -0))
71
- return [2, "-0"];
72
- return [2, String(value)];
73
- }
74
- if (typeof value === "string")
75
- return [3, value];
76
- if (value instanceof Date)
77
- return [4, dateMilliseconds(value)];
78
- throw new TypeError("Query parameter has an unsupported value");
50
+ if (value === null)
51
+ return [0];
52
+ if (typeof value === "boolean")
53
+ return [1, value];
54
+ if (typeof value === "number") {
55
+ if (Object.is(value, -0))
56
+ return [2, "-0"];
57
+ return [2, String(value)];
58
+ }
59
+ if (typeof value === "string")
60
+ return [3, value];
61
+ if (value instanceof Date)
62
+ return [4, dateMilliseconds(value)];
63
+ throw new TypeError("Query parameter has an unsupported value");
79
64
  }
65
+ export {
66
+ RESULT_MEMO_MAX_BYTES,
67
+ copyQueryResult,
68
+ planMemoKey,
69
+ queryResultMemoKey,
70
+ queryResultRetainedBytes
71
+ };
@@ -31,6 +31,12 @@ export interface QueryExecutionOptions {
31
31
  export declare const scalarFunctionNames: ReadonlySet<string>;
32
32
  /** Functions whose answer can change without any catalog or input-row change. */
33
33
  export declare const volatileScalarFunctionNames: ReadonlySet<string>;
34
+ /**
35
+ * The niladic datetime functions (F051-06/07/08). Their value is the statement's own clock
36
+ * reading, so they are resolved once per execution rather than evaluated per row: every row of
37
+ * one statement sees one instant, both executors agree, and constant folding leaves them alone.
38
+ */
39
+ export declare const statementDatetimeNames: ReadonlySet<string>;
34
40
  export declare function isScalarFunctionName(name: AggregateName | ScalarFunctionName): name is ScalarFunctionName;
35
41
  /**
36
42
  * Evaluates one scalar function over already-evaluated argument values. Every executor calls
@@ -40,6 +46,14 @@ export declare function isScalarFunctionName(name: AggregateName | ScalarFunctio
40
46
  * SUBSTR count characters, not UTF-16 units, matching SQLite and PostgreSQL.
41
47
  */
42
48
  export declare function scalarFunctionValue(name: Exclude<ScalarFunctionName, "COALESCE">, values: readonly unknown[]): unknown;
49
+ export type ScalarFunctionEvaluator = (values: readonly unknown[]) => unknown;
50
+ /**
51
+ * The evaluator for one function name, resolved once. A call site that keeps the evaluator
52
+ * skips the name dispatch on every row; the registry functions and the hottest built-ins get
53
+ * a closure of their own, everything else a closure over the general dispatch.
54
+ */
55
+ export declare function scalarFunctionEvaluator(name: Exclude<ScalarFunctionName, "COALESCE">): ScalarFunctionEvaluator;
56
+ export declare function dateTruncValue(unit: unknown, value: unknown): Date | null;
43
57
  /** The output column type of one window: rankings and most aggregates count, MIN/MAX carry. */
44
58
  export declare function windowOutputType(window: WindowSpec, innerSchema: readonly SqlColumnSchema[]): SqlColumnType;
45
59
  /** Logical domain carried or produced by a window result, when its physical type is not enough. */
@@ -56,6 +70,14 @@ interface CompileQueryOptions {
56
70
  /** Set false to skip deterministic plan rewrites, for example to snapshot the raw plan. */
57
71
  readonly optimize?: boolean;
58
72
  }
73
+ /** One RETURNING item beyond a plain column: its statement text, output name, and the column it names when it is one. */
74
+ export interface ReturningItem {
75
+ sql: string;
76
+ alias: string;
77
+ expression: Expression;
78
+ /** The target column the item names, when it is a bare column reference. */
79
+ column?: string;
80
+ }
59
81
  export declare function compileQuery(sql: string, options?: CompileQueryOptions): CompiledQuery;
60
82
  /**
61
83
  * One WHEN clause of a MERGE (F312). Branches are tried in order for each source row, and the
@@ -135,6 +157,11 @@ export type CompiledStatement = {
135
157
  column: string;
136
158
  /** The full PostgreSQL conflict target; `column` remains the scalar fast-path name. */
137
159
  columns?: string[];
160
+ /**
161
+ * `ON CONFLICT DO NOTHING` with no target: the statement names no columns, and the
162
+ * table's unique key is resolved at execution, where the catalog is known.
163
+ */
164
+ anyTarget?: true;
138
165
  action: "nothing" | "replace" | "update";
139
166
  /** Expressions evaluated against the stored target row and the proposed EXCLUDED row. */
140
167
  assignments?: Array<{
@@ -145,10 +172,14 @@ export type CompiledStatement = {
145
172
  where?: Expression;
146
173
  };
147
174
  returning?: string[] | "*";
175
+ /** RETURNING items that are not plain columns, evaluated over the affected rows. */
176
+ returningItems?: ReturningItem[];
148
177
  parameterCount?: number;
149
178
  } | {
150
179
  kind: "update";
151
180
  table: string;
181
+ /** `UPDATE t AS u`: the name the assignments, predicates, and RETURNING may qualify by. */
182
+ alias?: string;
152
183
  assignments: Array<{
153
184
  column: string;
154
185
  expression: Expression;
@@ -159,16 +190,21 @@ export type CompiledStatement = {
159
190
  right: Expression;
160
191
  }>;
161
192
  returning?: string[] | "*";
193
+ /** RETURNING items that are not plain columns, evaluated over the affected rows. */
194
+ returningItems?: ReturningItem[];
162
195
  parameterCount?: number;
163
196
  } | {
164
197
  kind: "delete";
165
198
  table: string;
199
+ alias?: string;
166
200
  predicates: Array<{
167
201
  left: Expression;
168
202
  operator: PredicateOperator;
169
203
  right: Expression;
170
204
  }>;
171
205
  returning?: string[] | "*";
206
+ /** RETURNING items that are not plain columns, evaluated over the affected rows. */
207
+ returningItems?: ReturningItem[];
172
208
  parameterCount?: number;
173
209
  } | {
174
210
  kind: "create-table";
@@ -535,6 +571,8 @@ export declare function orderOutputName(expression: Expression, select: readonly
535
571
  interface ListMembership {
536
572
  set: ReadonlySet<unknown>;
537
573
  hasNull: boolean;
574
+ /** Whether any member is text, which a typed left value may read in its own type. */
575
+ hasText: boolean;
538
576
  }
539
577
  /**
540
578
  * IN lists produced by subquery materialization can hold many thousands of literals, and
@@ -668,6 +706,13 @@ export declare function projectResultColumns(result: QueryResult, aliases: reado
668
706
  export declare function derivedTableSource(derived: CompiledQuery, alias: string, nextSequence: () => number): TableSource;
669
707
  /** The parser's LIMIT range contract, shared with the typed builder. */
670
708
  export declare function validateLimit(limit: number): number;
709
+ /**
710
+ * Reads datetime text the way the TIMESTAMP literal does — a zoneless `2026-01-02 03:04:05` is
711
+ * UTC, never the host's zone — and falls back to the JavaScript parser for other spellings.
712
+ * `new Date("2026-01-02 03:04:05")` alone would read the same text in local time, so a CAST
713
+ * would answer differently on two machines.
714
+ */
715
+ export declare function datetimeText(text: string): Date;
671
716
  /** The parser's OFFSET range contract, shared with the typed builder. */
672
717
  export declare function validateOffset(offset: number): number;
673
718
  /**