@minnowdb/core 0.0.1 → 0.1.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 (186) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -1
  3. package/dist/block-format/block.d.ts +46 -0
  4. package/dist/block-format/block.d.ts.map +1 -0
  5. package/dist/block-format/block.js +244 -0
  6. package/dist/block-format/block.js.map +1 -0
  7. package/dist/block-format/checksum.d.ts +7 -0
  8. package/dist/block-format/checksum.d.ts.map +1 -0
  9. package/dist/block-format/checksum.js +56 -0
  10. package/dist/block-format/checksum.js.map +1 -0
  11. package/dist/block-format/codecs.d.ts +24 -0
  12. package/dist/block-format/codecs.d.ts.map +1 -0
  13. package/dist/block-format/codecs.js +102 -0
  14. package/dist/block-format/codecs.js.map +1 -0
  15. package/dist/block-format/column.d.ts +8 -0
  16. package/dist/block-format/column.d.ts.map +1 -0
  17. package/dist/block-format/column.js +166 -0
  18. package/dist/block-format/column.js.map +1 -0
  19. package/dist/block-format/index.d.ts +7 -0
  20. package/dist/block-format/index.d.ts.map +1 -0
  21. package/dist/block-format/index.js +7 -0
  22. package/dist/block-format/index.js.map +1 -0
  23. package/dist/block-format/physical.d.ts +20 -0
  24. package/dist/block-format/physical.d.ts.map +1 -0
  25. package/dist/block-format/physical.js +439 -0
  26. package/dist/block-format/physical.js.map +1 -0
  27. package/dist/block-format/types.d.ts +93 -0
  28. package/dist/block-format/types.d.ts.map +1 -0
  29. package/dist/block-format/types.js +2 -0
  30. package/dist/block-format/types.js.map +1 -0
  31. package/dist/engine/artifact-cache.d.ts +22 -0
  32. package/dist/engine/artifact-cache.d.ts.map +1 -0
  33. package/dist/engine/artifact-cache.js +68 -0
  34. package/dist/engine/artifact-cache.js.map +1 -0
  35. package/dist/engine/batch.d.ts +28 -0
  36. package/dist/engine/batch.d.ts.map +1 -0
  37. package/dist/engine/batch.js +38 -0
  38. package/dist/engine/batch.js.map +1 -0
  39. package/dist/engine/buffered-writer.d.ts +43 -0
  40. package/dist/engine/buffered-writer.d.ts.map +1 -0
  41. package/dist/engine/buffered-writer.js +158 -0
  42. package/dist/engine/buffered-writer.js.map +1 -0
  43. package/dist/engine/catalog.d.ts +82 -0
  44. package/dist/engine/catalog.d.ts.map +1 -0
  45. package/dist/engine/catalog.js +47 -0
  46. package/dist/engine/catalog.js.map +1 -0
  47. package/dist/engine/client.d.ts +211 -0
  48. package/dist/engine/client.d.ts.map +1 -0
  49. package/dist/engine/client.js +538 -0
  50. package/dist/engine/client.js.map +1 -0
  51. package/dist/engine/coordinator.d.ts +17 -0
  52. package/dist/engine/coordinator.d.ts.map +1 -0
  53. package/dist/engine/coordinator.js +60 -0
  54. package/dist/engine/coordinator.js.map +1 -0
  55. package/dist/engine/database.d.ts +661 -0
  56. package/dist/engine/database.d.ts.map +1 -0
  57. package/dist/engine/database.js +10313 -0
  58. package/dist/engine/database.js.map +1 -0
  59. package/dist/engine/defaults.d.ts +33 -0
  60. package/dist/engine/defaults.d.ts.map +1 -0
  61. package/dist/engine/defaults.js +87 -0
  62. package/dist/engine/defaults.js.map +1 -0
  63. package/dist/engine/errors.d.ts +55 -0
  64. package/dist/engine/errors.d.ts.map +1 -0
  65. package/dist/engine/errors.js +81 -0
  66. package/dist/engine/errors.js.map +1 -0
  67. package/dist/engine/fts.d.ts +93 -0
  68. package/dist/engine/fts.d.ts.map +1 -0
  69. package/dist/engine/fts.js +273 -0
  70. package/dist/engine/fts.js.map +1 -0
  71. package/dist/engine/group-index.d.ts +32 -0
  72. package/dist/engine/group-index.d.ts.map +1 -0
  73. package/dist/engine/group-index.js +366 -0
  74. package/dist/engine/group-index.js.map +1 -0
  75. package/dist/engine/index.d.ts +13 -0
  76. package/dist/engine/index.d.ts.map +1 -0
  77. package/dist/engine/index.js +12 -0
  78. package/dist/engine/index.js.map +1 -0
  79. package/dist/engine/join-index.d.ts +12 -0
  80. package/dist/engine/join-index.d.ts.map +1 -0
  81. package/dist/engine/join-index.js +217 -0
  82. package/dist/engine/join-index.js.map +1 -0
  83. package/dist/engine/live.d.ts +86 -0
  84. package/dist/engine/live.d.ts.map +1 -0
  85. package/dist/engine/live.js +289 -0
  86. package/dist/engine/live.js.map +1 -0
  87. package/dist/engine/memory.d.ts +37 -0
  88. package/dist/engine/memory.d.ts.map +1 -0
  89. package/dist/engine/memory.js +119 -0
  90. package/dist/engine/memory.js.map +1 -0
  91. package/dist/engine/optimizer.d.ts +20 -0
  92. package/dist/engine/optimizer.d.ts.map +1 -0
  93. package/dist/engine/optimizer.js +1170 -0
  94. package/dist/engine/optimizer.js.map +1 -0
  95. package/dist/engine/query-cache.d.ts +10 -0
  96. package/dist/engine/query-cache.d.ts.map +1 -0
  97. package/dist/engine/query-cache.js +58 -0
  98. package/dist/engine/query-cache.js.map +1 -0
  99. package/dist/engine/query.d.ts +844 -0
  100. package/dist/engine/query.d.ts.map +1 -0
  101. package/dist/engine/query.js +7450 -0
  102. package/dist/engine/query.js.map +1 -0
  103. package/dist/engine/schema-wire.d.ts +92 -0
  104. package/dist/engine/schema-wire.d.ts.map +1 -0
  105. package/dist/engine/schema-wire.js +115 -0
  106. package/dist/engine/schema-wire.js.map +1 -0
  107. package/dist/engine/schema.d.ts +394 -0
  108. package/dist/engine/schema.d.ts.map +1 -0
  109. package/dist/engine/schema.js +709 -0
  110. package/dist/engine/schema.js.map +1 -0
  111. package/dist/engine/sort-keys.d.ts +36 -0
  112. package/dist/engine/sort-keys.d.ts.map +1 -0
  113. package/dist/engine/sort-keys.js +60 -0
  114. package/dist/engine/sort-keys.js.map +1 -0
  115. package/dist/engine/sql-json.d.ts +30 -0
  116. package/dist/engine/sql-json.d.ts.map +1 -0
  117. package/dist/engine/sql-json.js +120 -0
  118. package/dist/engine/sql-json.js.map +1 -0
  119. package/dist/engine/sql-semantics.d.ts +31 -0
  120. package/dist/engine/sql-semantics.d.ts.map +1 -0
  121. package/dist/engine/sql-semantics.js +121 -0
  122. package/dist/engine/sql-semantics.js.map +1 -0
  123. package/dist/engine/vector.d.ts +87 -0
  124. package/dist/engine/vector.d.ts.map +1 -0
  125. package/dist/engine/vector.js +4227 -0
  126. package/dist/engine/vector.js.map +1 -0
  127. package/dist/engine/worker-host.d.ts +48 -0
  128. package/dist/engine/worker-host.d.ts.map +1 -0
  129. package/dist/engine/worker-host.js +501 -0
  130. package/dist/engine/worker-host.js.map +1 -0
  131. package/dist/engine/worker.d.ts +2 -0
  132. package/dist/engine/worker.d.ts.map +1 -0
  133. package/dist/engine/worker.js +14 -0
  134. package/dist/engine/worker.js.map +1 -0
  135. package/dist/index.d.ts +2 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +2 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/plan/index.d.ts +17 -0
  140. package/dist/plan/index.d.ts.map +1 -0
  141. package/dist/plan/index.js +17 -0
  142. package/dist/plan/index.js.map +1 -0
  143. package/dist/storage/fixture-shape.d.ts +42 -0
  144. package/dist/storage/fixture-shape.d.ts.map +1 -0
  145. package/dist/storage/fixture-shape.js +146 -0
  146. package/dist/storage/fixture-shape.js.map +1 -0
  147. package/dist/storage/index.d.ts +5 -0
  148. package/dist/storage/index.d.ts.map +1 -0
  149. package/dist/storage/index.js +5 -0
  150. package/dist/storage/index.js.map +1 -0
  151. package/dist/storage/indexeddb.d.ts +139 -0
  152. package/dist/storage/indexeddb.d.ts.map +1 -0
  153. package/dist/storage/indexeddb.js +3161 -0
  154. package/dist/storage/indexeddb.js.map +1 -0
  155. package/dist/storage/memory.d.ts +121 -0
  156. package/dist/storage/memory.d.ts.map +1 -0
  157. package/dist/storage/memory.js +1455 -0
  158. package/dist/storage/memory.js.map +1 -0
  159. package/dist/storage/snapshot.d.ts +108 -0
  160. package/dist/storage/snapshot.d.ts.map +1 -0
  161. package/dist/storage/snapshot.js +276 -0
  162. package/dist/storage/snapshot.js.map +1 -0
  163. package/dist/storage/types.d.ts +895 -0
  164. package/dist/storage/types.d.ts.map +1 -0
  165. package/dist/storage/types.js +1549 -0
  166. package/dist/storage/types.js.map +1 -0
  167. package/dist/testing/index.d.ts +76 -0
  168. package/dist/testing/index.d.ts.map +1 -0
  169. package/dist/testing/index.js +233 -0
  170. package/dist/testing/index.js.map +1 -0
  171. package/dist/testing/seeds.d.ts +11 -0
  172. package/dist/testing/seeds.d.ts.map +1 -0
  173. package/dist/testing/seeds.js +50 -0
  174. package/dist/testing/seeds.js.map +1 -0
  175. package/dist/transactions/index.d.ts +148 -0
  176. package/dist/transactions/index.d.ts.map +1 -0
  177. package/dist/transactions/index.js +662 -0
  178. package/dist/transactions/index.js.map +1 -0
  179. package/dist/worker-protocol/index.d.ts +84 -0
  180. package/dist/worker-protocol/index.d.ts.map +1 -0
  181. package/dist/worker-protocol/index.js +117 -0
  182. package/dist/worker-protocol/index.js.map +1 -0
  183. package/package.json +66 -16
  184. package/sql-feature-matrix.json +1275 -0
  185. package/index.d.ts +0 -1
  186. package/index.js +0 -1
@@ -0,0 +1,844 @@
1
+ import type { DatabaseRow } from "./database.js";
2
+ import type { ColumnDefault } from "../storage/types.js";
3
+ import { type FtsStats } from "./fts.js";
4
+ import { QueryMemoryContext, type QueryMemoryUsage } from "./memory.js";
5
+ import { type ColumnarTable, type AsyncQueryExecutionOptions } from "./vector.js";
6
+ export type QueryValue = boolean | number | string | Date | null;
7
+ export type QueryRow = Record<string, QueryValue>;
8
+ export interface QueryResult {
9
+ columns: string[];
10
+ rows: QueryRow[];
11
+ }
12
+ export interface PreparedQuery {
13
+ readonly sql: string;
14
+ readonly tables: string[];
15
+ /**
16
+ * Current retained and high-water byte counts for the documented modeled query-memory scope.
17
+ * Result-construction bytes affect the peak but transfer out of the context when execute returns.
18
+ */
19
+ readonly memoryUsage: QueryMemoryUsage;
20
+ execute(): QueryResult;
21
+ executeAsync(options?: AsyncQueryExecutionOptions): Promise<QueryResult>;
22
+ close(): void;
23
+ }
24
+ export interface QueryExecutionOptions {
25
+ /**
26
+ * Bounds the modeled vector, row-index, group/result payload, and ordering buffers. This is not a
27
+ * total JavaScript heap limit; input preparation, container/allocator overhead, and returned-result
28
+ * lifetime are excluded. The schema-less empty-table row adapter rejects configured budgets;
29
+ * MinnowDatabase retains catalog types and does not use that fallback.
30
+ */
31
+ readonly executionMemoryBudgetBytes?: number;
32
+ }
33
+ export type BinaryOperator = "+" | "-" | "*" | "/" | "%" | "||";
34
+ export type ComparisonOperator = "=" | "!=" | "<>" | ">" | ">=" | "<" | "<=";
35
+ export type AggregateName = "COUNT" | "SUM" | "AVG" | "MIN" | "MAX";
36
+ export type ScalarFunctionName = "ROUND" | "COALESCE" | "DATE_TRUNC" | "DATE_ADD" | "UPPER" | "LOWER" | "LENGTH" | "ABS" | "TRIM" | "LTRIM" | "RTRIM" | "SUBSTR" | "REPLACE" | "INSTR" | "NULLIF" | "GREATEST" | "LEAST" | "FLOOR" | "CEIL" | "MOD" | "POWER" | "SQRT" | "EXTRACT" | "CAST" | "OCTET_LENGTH" | "LPAD" | "RPAD" | "OVERLAY" | "CURRENT_DATE" | "CURRENT_TIMESTAMP" | "LOCALTIME" | "GROUPING" | "JSON_VALUE" | "JSON_QUERY" | "JSON_EXISTS" | "JSON_OBJECT" | "JSON_ARRAY" | "IS_JSON";
37
+ export declare const scalarFunctionNames: ReadonlySet<string>;
38
+ /**
39
+ * The niladic datetime functions (F051-06/07/08). Their value is the statement's own clock
40
+ * reading, so they are resolved once per execution rather than evaluated per row: every row of
41
+ * one statement sees one instant, both executors agree, and constant folding leaves them alone.
42
+ */
43
+ export declare const statementDatetimeNames: ReadonlySet<string>;
44
+ export declare function isScalarFunctionName(name: AggregateName | ScalarFunctionName): name is ScalarFunctionName;
45
+ /**
46
+ * Evaluates one scalar function over already-evaluated argument values. Every executor calls
47
+ * through here, so a function behaves identically in the row executor, the vectorized executor,
48
+ * and constant folding. COALESCE is not handled here — it short-circuits, so each call site
49
+ * evaluates it lazily. A NULL first argument returns NULL (SQL scalar semantics); LENGTH and
50
+ * SUBSTR count characters, not UTF-16 units, matching SQLite and PostgreSQL.
51
+ */
52
+ export declare function scalarFunctionValue(name: Exclude<ScalarFunctionName, "COALESCE">, values: readonly unknown[]): unknown;
53
+ export declare const dateTruncUnits: ReadonlySet<string>;
54
+ /**
55
+ * `INTERVAL '1 month'`, `INTERVAL '2 years 3 days'`. Months are kept apart from milliseconds
56
+ * rather than converted, because a month is not a fixed number of them: adding one to January 31
57
+ * has to land on the end of February, which only calendar arithmetic can do.
58
+ */
59
+ export declare function intervalLiteral(text: string): {
60
+ months: number;
61
+ milliseconds: number;
62
+ };
63
+ /**
64
+ * A datetime shifted by a calendar interval: whole months first, then milliseconds. A day that
65
+ * does not exist in the target month clamps to that month's last day, which is what both SQLite
66
+ * and PostgreSQL do with 31 January plus a month.
67
+ */
68
+ export declare function dateAddValue(value: unknown, months: unknown, milliseconds: unknown): Date | null;
69
+ export declare function dateTruncValue(unit: unknown, value: unknown): Date | null;
70
+ export type Expression = {
71
+ kind: "literal";
72
+ value: QueryValue;
73
+ }
74
+ /** A `?` or `$n` placeholder; `index` is 0-based. Replaced by a literal at bind time. */
75
+ | {
76
+ kind: "parameter";
77
+ index: number;
78
+ } | {
79
+ kind: "column";
80
+ reference: string;
81
+ }
82
+ /**
83
+ * `*`, or `alias.*` when `table` is set (E051-07). A qualified wildcard names one source and
84
+ * may sit beside other select items; every executor entry expands it into that source's
85
+ * columns, so past the entry only a bare wildcard — the whole-row projection — survives.
86
+ */
87
+ | {
88
+ kind: "wildcard";
89
+ table?: string;
90
+ } | {
91
+ kind: "binary";
92
+ operator: BinaryOperator;
93
+ left: Expression;
94
+ right: Expression;
95
+ } | {
96
+ kind: "call";
97
+ name: AggregateName | ScalarFunctionName;
98
+ arguments: Expression[];
99
+ distinct?: boolean;
100
+ } | {
101
+ kind: "list";
102
+ items: Expression[];
103
+ } | {
104
+ kind: "subquery";
105
+ block: CompiledQuery;
106
+ } | {
107
+ kind: "condition";
108
+ operator: PredicateOperator;
109
+ left: Expression;
110
+ right: Expression;
111
+ /** LIKE/ILIKE escape character, from LIKE ... ESCAPE 'c'. */
112
+ escape?: string;
113
+ } | {
114
+ kind: "logical";
115
+ operator: "and" | "or";
116
+ left: Expression;
117
+ right: Expression;
118
+ } | {
119
+ kind: "not";
120
+ operand: Expression;
121
+ } | {
122
+ kind: "exists";
123
+ block: CompiledQuery;
124
+ negated: boolean;
125
+ } | {
126
+ kind: "case";
127
+ branches: Array<{
128
+ when: Expression;
129
+ then: Expression;
130
+ }>;
131
+ otherwise?: Expression;
132
+ } | {
133
+ kind: "window";
134
+ name: WindowFunctionName;
135
+ partitionBy: Expression[];
136
+ orderBy: Array<{
137
+ expression: Expression;
138
+ direction: "asc" | "desc";
139
+ nulls?: "first" | "last";
140
+ }>;
141
+ argument?: Expression;
142
+ /** LAG/LEAD row distance; parsed as a literal non-negative integer, defaulting to 1. */
143
+ offset?: number;
144
+ /** LAG/LEAD default when the offset row falls outside the partition; NULL when absent. */
145
+ fallback?: QueryValue;
146
+ frame?: WindowFrame;
147
+ } | {
148
+ kind: "fts";
149
+ op: "match" | "bm25";
150
+ /**
151
+ * Column references forming the document, or "*" for every searchable column of the
152
+ * single scan source. "*" stays unexpanded through compilation (both front ends emit the
153
+ * identical node — plan parity), and the engine expands it against the catalog at
154
+ * prepare time via expandFtsColumns.
155
+ */
156
+ columns: Expression[] | "*";
157
+ query: string;
158
+ /**
159
+ * Corpus statistics for BM25, annotated by the executor onto its cloned plan before
160
+ * evaluation; never set by compilation.
161
+ */
162
+ stats?: FtsStats;
163
+ };
164
+ export type WindowFunctionName = "ROW_NUMBER" | "RANK" | "DENSE_RANK" | "PERCENT_RANK" | "CUME_DIST" | "NTILE" | "LAG" | "LEAD" | "FIRST_VALUE" | "LAST_VALUE" | "NTH_VALUE" | AggregateName;
165
+ export interface WindowFrameBound {
166
+ kind: "unbounded-preceding" | "preceding" | "current-row" | "following" | "unbounded-following";
167
+ /** Row distance for preceding/following bounds (ROWS unit only). */
168
+ offset?: number;
169
+ }
170
+ /** How a frame's rows are excluded around the current row (T612). */
171
+ export type WindowFrameExclusion = "no-others" | "current-row" | "group" | "ties";
172
+ /** An explicit frame clause; absent means the SQL default for the window's ordering. */
173
+ export interface WindowFrame {
174
+ unit: "rows" | "range" | "groups";
175
+ start: WindowFrameBound;
176
+ end: WindowFrameBound;
177
+ /** Rows excluded around the current row; absent means EXCLUDE NO OTHERS. */
178
+ exclude?: WindowFrameExclusion;
179
+ }
180
+ export interface WindowSpec {
181
+ alias: string;
182
+ name: WindowFunctionName;
183
+ partitionAliases: string[];
184
+ orderAliases: Array<{
185
+ alias: string;
186
+ direction: "asc" | "desc";
187
+ nulls?: "first" | "last";
188
+ }>;
189
+ /** Hidden inner alias of an aggregate window's argument; absent for COUNT(*) and rankings. */
190
+ argumentAlias?: string;
191
+ /** LAG/LEAD row distance. */
192
+ offset?: number;
193
+ /** LAG/LEAD default when the offset row falls outside the partition. */
194
+ fallback?: QueryValue;
195
+ frame?: WindowFrame;
196
+ }
197
+ /** The output column type of one window: rankings and most aggregates count, MIN/MAX carry. */
198
+ export declare function windowOutputType(window: WindowSpec, innerSchema: readonly SqlColumnSchema[]): SqlColumnType;
199
+ export interface SelectItem {
200
+ expression: Expression;
201
+ alias: string;
202
+ }
203
+ export interface TableSource {
204
+ table: string;
205
+ alias: string;
206
+ /** A parenthesized SELECT or expanded CTE body; `table` is then a unique synthetic name. */
207
+ derived?: CompiledQuery;
208
+ /** A top-level set operation; members combine positionally under the first member's schema. */
209
+ union?: {
210
+ blocks: CompiledQuery[];
211
+ ops: SetOperator[];
212
+ };
213
+ recursive?: RecursiveCte;
214
+ /** A window-function desugar: the inner block executes, then window columns append. */
215
+ windowed?: {
216
+ block: CompiledQuery;
217
+ windows: WindowSpec[];
218
+ };
219
+ /**
220
+ * `FROM t AS y(a, b)`: positional new names for a base table's columns (E051-09). Every
221
+ * executor entry turns the source into a derived projection, so past that point the rename
222
+ * is an ordinary select list and nothing else has to know about it.
223
+ */
224
+ columnAliases?: string[];
225
+ }
226
+ export interface JoinPlan extends TableSource {
227
+ kind: "inner" | "left";
228
+ left: Expression;
229
+ right: Expression;
230
+ /** General ON condition for non-equi or multi-key joins; left/right are inert placeholders. */
231
+ on?: Expression;
232
+ /** Parser marker: FULL OUTER JOIN. Assembly desugars it into a union of two left joins. */
233
+ full?: boolean;
234
+ /**
235
+ * Parser marker: NATURAL JOIN. Every execution entry replaces it with the equality
236
+ * conjunction over the columns this source shares with the ones before it, so no executor
237
+ * ever sees the marker (F401-01).
238
+ */
239
+ natural?: boolean;
240
+ }
241
+ export type SetOperator = "union" | "union all" | "intersect" | "intersect all" | "except" | "except all";
242
+ /**
243
+ * A WITH RECURSIVE source: the base block seeds the working set, then the step block re-executes
244
+ * with `reference` bound to the previous iteration's new rows (linear delta recursion) until no
245
+ * new rows appear. UNION deduplicates against everything seen; UNION ALL appends raw.
246
+ */
247
+ export interface RecursiveCte {
248
+ reference: string;
249
+ base: CompiledQuery;
250
+ step: CompiledQuery;
251
+ all: boolean;
252
+ }
253
+ export type PredicateOperator = ComparisonOperator | `${ComparisonOperator} ANY` | `${ComparisonOperator} ALL` | "IN" | "NOT IN" | "IS NULL" | "IS NOT NULL" | "LIKE" | "NOT LIKE" | "ILIKE" | "NOT ILIKE" | "IS DISTINCT FROM" | "IS NOT DISTINCT FROM" | "IS TRUE";
254
+ export interface Predicate {
255
+ left: Expression;
256
+ operator: PredicateOperator;
257
+ right: Expression;
258
+ /** LIKE/ILIKE escape character, carried from the parsed condition. */
259
+ escape?: string;
260
+ }
261
+ export interface CompiledQuery {
262
+ sql: string;
263
+ base: TableSource;
264
+ joins: JoinPlan[];
265
+ select: SelectItem[];
266
+ predicates: Predicate[];
267
+ groupBy: Expression[];
268
+ having: Predicate[];
269
+ orderBy: Array<{
270
+ expression: Expression;
271
+ direction: "asc" | "desc";
272
+ /**
273
+ * Explicit NULL placement, absolute regardless of direction. Absent keeps the default:
274
+ * NULL sorts smallest, so ASC puts NULLs first and DESC puts them last (SQLite's default).
275
+ */
276
+ nulls?: "first" | "last";
277
+ }>;
278
+ limit?: number;
279
+ offset?: number;
280
+ /**
281
+ * SELECT DISTINCT * awaiting expansion: the wildcard's columns are unknown until input
282
+ * schemas exist, so every executor entry expands this into a concrete select list plus a
283
+ * matching GROUP BY exactly once (see expandDistinctWildcard), like MATCH(*).
284
+ */
285
+ distinctWildcard?: boolean;
286
+ /** Parameter slots for LIMIT ? / OFFSET ?; binding resolves them into limit/offset. */
287
+ limitParameter?: number;
288
+ offsetParameter?: number;
289
+ /**
290
+ * FETCH FIRST n ROWS WITH TIES (F866): rows tying with the last retained row under the
291
+ * ORDER BY are kept too. The limit cannot be pushed into a scan then, so every execution
292
+ * entry runs the query unlimited and trims the ordered result.
293
+ */
294
+ limitWithTies?: boolean;
295
+ /**
296
+ * Number of `?`/`$n` placeholders in the whole statement; set only on the top-level plan.
297
+ * A plan with placeholders must pass through bindPlanParameters before it prepares.
298
+ */
299
+ parameterCount?: number;
300
+ /**
301
+ * CURRENT_DATE / CURRENT_TIMESTAMP / LOCALTIME appear somewhere in the statement. Every
302
+ * executor entry replaces them with one instant per execution, and results never memoize,
303
+ * because the answer depends on the clock rather than on the data.
304
+ */
305
+ usesStatementDatetime?: boolean;
306
+ }
307
+ /** ORDER BY / LIMIT / OFFSET tail of a select or set operation. */
308
+ export interface SelectTail {
309
+ orderBy: CompiledQuery["orderBy"];
310
+ limit?: number;
311
+ offset?: number;
312
+ limitParameter?: number;
313
+ offsetParameter?: number;
314
+ limitWithTies?: boolean;
315
+ }
316
+ /**
317
+ * The virtual one-row source behind a FROM-less SELECT. The name cannot collide with a real
318
+ * table (parentheses never survive identifier parsing unquoted), and its single hidden column
319
+ * keeps the row alive through columnar conversion, which derives row count from column vectors.
320
+ */
321
+ export declare const DUAL_TABLE = "(dual)";
322
+ /** The dual source's single row, shared by every resolution path. */
323
+ export declare function dualTableRows(): DatabaseRow[];
324
+ export interface CompileQueryOptions {
325
+ /** Set false to skip deterministic plan rewrites, for example to snapshot the raw plan. */
326
+ readonly optimize?: boolean;
327
+ }
328
+ export declare function compileQuery(sql: string, options?: CompileQueryOptions): CompiledQuery;
329
+ /**
330
+ * One WHEN clause of a MERGE (F312). Branches are tried in order for each source row, and the
331
+ * first whose match state and optional condition hold decides what happens to that row.
332
+ */
333
+ export type MergeBranch = {
334
+ when: "matched";
335
+ condition?: Expression;
336
+ action: {
337
+ kind: "update";
338
+ assignments: Array<{
339
+ column: string;
340
+ expression: Expression;
341
+ }>;
342
+ } | {
343
+ kind: "delete";
344
+ };
345
+ } | {
346
+ when: "not-matched";
347
+ condition?: Expression;
348
+ action: {
349
+ kind: "insert";
350
+ columns: string[];
351
+ values: Expression[];
352
+ };
353
+ };
354
+ /**
355
+ * One FOREIGN KEY as written (E141-04). The parent column is optional in the text and defaults
356
+ * to the parent's unique key, which is the only column this engine can reference.
357
+ */
358
+ export interface ForeignKeyDefinition {
359
+ name: string;
360
+ column: string;
361
+ parentTable: string;
362
+ parentColumn?: string;
363
+ onDelete: "restrict" | "cascade" | "set null";
364
+ }
365
+ /** An INSERT value: a constant, or an unbound `?`/`$n` placeholder awaiting its parameter. */
366
+ export type InsertValue = QueryValue | {
367
+ parameter: number;
368
+ };
369
+ export type CompiledStatement = {
370
+ kind: "select";
371
+ sql: string;
372
+ parameterCount?: number;
373
+ } | {
374
+ kind: "insert";
375
+ table: string;
376
+ columns: string[];
377
+ rows: InsertValue[][];
378
+ /** INSERT ... SELECT source; `rows` is then empty and fills at execution. */
379
+ query?: CompiledQuery;
380
+ /**
381
+ * ON CONFLICT (column) DO NOTHING skips rows whose key exists. DO UPDATE SET with every
382
+ * inserted column drawn from EXCLUDED is "replace" (whole-row upsert); a subset is
383
+ * "update", which merges only the listed columns into existing rows.
384
+ */
385
+ onConflict?: {
386
+ column: string;
387
+ action: "nothing" | "replace" | "update";
388
+ /** The EXCLUDED columns a partial DO UPDATE merges; present only for "update". */
389
+ columns?: string[];
390
+ };
391
+ returning?: string[] | "*";
392
+ parameterCount?: number;
393
+ } | {
394
+ kind: "update";
395
+ table: string;
396
+ assignments: Array<{
397
+ column: string;
398
+ expression: Expression;
399
+ }>;
400
+ predicates: Array<{
401
+ left: Expression;
402
+ operator: PredicateOperator;
403
+ right: Expression;
404
+ }>;
405
+ returning?: string[] | "*";
406
+ parameterCount?: number;
407
+ } | {
408
+ kind: "delete";
409
+ table: string;
410
+ predicates: Array<{
411
+ left: Expression;
412
+ operator: PredicateOperator;
413
+ right: Expression;
414
+ }>;
415
+ returning?: string[] | "*";
416
+ parameterCount?: number;
417
+ } | {
418
+ kind: "create-table";
419
+ table: string;
420
+ columns: Array<{
421
+ name: string;
422
+ type: SqlColumnType;
423
+ nullable?: boolean;
424
+ defaultValue?: ColumnDefault;
425
+ }>;
426
+ checks?: Array<{
427
+ name: string;
428
+ sql: string;
429
+ }>;
430
+ foreignKeys?: ForeignKeyDefinition[];
431
+ uniqueKey?: string;
432
+ /** CREATE TABLE IF NOT EXISTS: an existing table of that name is left alone. */
433
+ ifNotExists?: boolean;
434
+ parameterCount?: number;
435
+ } | {
436
+ kind: "create-trigger";
437
+ table: string;
438
+ trigger: {
439
+ name: string;
440
+ event: "insert" | "update" | "delete";
441
+ timing: "before" | "after";
442
+ statements: Array<{
443
+ /** Body INSERT with every NEW.col / OLD.col rewritten to a positional placeholder. */
444
+ sql: string;
445
+ bindings: Array<{
446
+ source: "new" | "old";
447
+ column: string;
448
+ }>;
449
+ }>;
450
+ };
451
+ parameterCount?: number;
452
+ } | {
453
+ kind: "drop-trigger";
454
+ name: string;
455
+ parameterCount?: number;
456
+ } | {
457
+ kind: "create-table-as";
458
+ table: string;
459
+ query: CompiledQuery;
460
+ ifNotExists?: boolean;
461
+ parameterCount?: number;
462
+ } | {
463
+ kind: "drop-table";
464
+ table: string;
465
+ ifExists?: boolean;
466
+ parameterCount?: number;
467
+ } | {
468
+ kind: "create-view";
469
+ view: string;
470
+ sql: string;
471
+ orReplace?: boolean;
472
+ parameterCount?: number;
473
+ } | {
474
+ kind: "drop-view";
475
+ view: string;
476
+ ifExists?: boolean;
477
+ parameterCount?: number;
478
+ } | {
479
+ kind: "transaction";
480
+ action: "begin" | "commit" | "rollback";
481
+ parameterCount?: number;
482
+ } | {
483
+ kind: "merge";
484
+ /** The target table, and the correlation name its columns are read under. */
485
+ table: string;
486
+ alias: string;
487
+ /**
488
+ * The source: a table or view by name, or a parenthesized query kept as its own text —
489
+ * the statement re-reads it through the ordinary query pipeline, so a source query sees
490
+ * views, CTEs, and joins exactly as it would on its own.
491
+ */
492
+ source: {
493
+ alias: string;
494
+ table?: string;
495
+ sql?: string;
496
+ };
497
+ /**
498
+ * The match condition. The engine requires it to equate the target's unique key with a
499
+ * source expression, which is also what makes each source row match at most one target
500
+ * row — the standard's cardinality violation cannot arise.
501
+ */
502
+ on: Expression;
503
+ branches: MergeBranch[];
504
+ parameterCount?: number;
505
+ } | {
506
+ kind: "add-column";
507
+ table: string;
508
+ column: {
509
+ name: string;
510
+ type: SqlColumnType;
511
+ nullable?: boolean;
512
+ defaultValue?: ColumnDefault;
513
+ };
514
+ parameterCount?: number;
515
+ };
516
+ /**
517
+ * Compiles one CHECK constraint's stored text into the expression the writer evaluates per row.
518
+ * Kept beside the parser because the same restrictions apply wherever a constraint is read: a
519
+ * row condition over this table's columns, with no aggregate, window, subquery, or parameter.
520
+ */
521
+ export declare function compileCheckExpression(sql: string, name: string): Expression;
522
+ /**
523
+ * Routes one SQL statement: SELECT and WITH compile through the read-only query pipeline, while
524
+ * INSERT ... VALUES, UPDATE ... SET, and DELETE FROM parse into mutation statements. Any other
525
+ * leading keyword fails explicitly.
526
+ */
527
+ export declare function compileStatement(sql: string): CompiledStatement;
528
+ /**
529
+ * Evaluates an expression against several named rows — the shape MERGE works in, where one
530
+ * condition or assignment reads the target and the source at once.
531
+ */
532
+ export declare function evaluateJoinedRowExpression(expression: Expression, rows: Readonly<Record<string, DatabaseRow | undefined>>): QueryValue;
533
+ /** Evaluates an expression against one row, for UPDATE SET assignment computation. */
534
+ export declare function evaluateRowExpression(expression: Expression, alias: string, row: DatabaseRow): QueryValue;
535
+ export interface SubqueryResolutionStep {
536
+ /** The uncorrelated block to execute; earlier steps have already substituted inside it. */
537
+ readonly block: CompiledQuery;
538
+ /** Replaces the subquery node with the executed result as literals. */
539
+ substitute(result: QueryResult): void;
540
+ }
541
+ /**
542
+ * Clones a plan and returns its subquery sites in post-order: executing each step's block and
543
+ * substituting its result leaves the returned plan free of subquery nodes. A scalar subquery must
544
+ * select one column and return at most one row (empty is NULL); an IN subquery must select one
545
+ * column and becomes a literal membership list. Correlated references fail inside the subquery's
546
+ * own scope as unknown aliases.
547
+ */
548
+ export declare function subqueryResolutionSteps(plan: CompiledQuery): {
549
+ plan: CompiledQuery;
550
+ steps: SubqueryResolutionStep[];
551
+ };
552
+ export declare function blockHasSubqueries(plan: CompiledQuery): boolean;
553
+ /** True when any `?`/`$n` placeholder remains anywhere in the expression tree. */
554
+ export declare function containsParameter(expression: Expression): boolean;
555
+ export declare function blockHasParameters(block: CompiledQuery): boolean;
556
+ /**
557
+ * Replaces every placeholder with its parameter value as a literal. The input plan is never
558
+ * modified — plans come from the compile cache, so binding is copy-on-write. The parameter list
559
+ * must match the statement's placeholder count exactly; a plan without placeholders passes
560
+ * through untouched (and rejects a non-empty parameter list explicitly).
561
+ */
562
+ export declare function bindPlanParameters(plan: CompiledQuery, params: readonly QueryValue[] | undefined): CompiledQuery;
563
+ /** The mutation-statement counterpart of bindPlanParameters; SELECTs bind through their plan. */
564
+ export declare function bindStatementParameters(statement: CompiledStatement, params: readonly QueryValue[] | undefined): CompiledStatement;
565
+ export type SqlColumnType = "boolean" | "number" | "string" | "datetime";
566
+ export interface SqlColumnSchema {
567
+ name: string;
568
+ type: SqlColumnType;
569
+ }
570
+ /**
571
+ * Infers the typed output schema of one select block from typed source schemas. A column whose
572
+ * type cannot be established (for example a bare NULL literal) is rejected explicitly, so a
573
+ * derived table always has concrete column types even when its result is empty.
574
+ */
575
+ export declare function inferBlockSchema(plan: CompiledQuery, schemas: ReadonlyMap<string, readonly SqlColumnSchema[]>): SqlColumnSchema[];
576
+ export declare function referencedColumns(plan: CompiledQuery, schemas: ReadonlyMap<string, readonly string[]>): Map<string, string[]>;
577
+ export declare function createPreparedQuery(plan: CompiledQuery, tables: ReadonlyMap<string, DatabaseRow[]>, options?: QueryExecutionOptions): PreparedQuery;
578
+ /** Internal columnar entry point used after MinnowDatabase materializes a stable snapshot. */
579
+ export declare function createPreparedColumnarQuery(plan: CompiledQuery, tables: ReadonlyMap<string, ColumnarTable>, memory?: QueryMemoryContext, options?: {
580
+ ftsStats?: ReadonlyMap<string, FtsStats>;
581
+ }): PreparedQuery;
582
+ export declare function executeQuery(plan: CompiledQuery, tables: ReadonlyMap<string, DatabaseRow[]>, options?: QueryExecutionOptions): QueryResult;
583
+ /**
584
+ * Combines set-operation member results positionally under the first member's column names,
585
+ * folding left: UNION deduplicates the entire accumulated set, UNION ALL concatenates. Values
586
+ * compare with SQL grouping semantics (NULLs equal, dates by instant, signed zeros equal).
587
+ */
588
+ export declare function combineUnionResults(results: readonly QueryResult[], ops: readonly SetOperator[]): QueryResult;
589
+ interface RecursiveCteState {
590
+ readonly columns: readonly string[];
591
+ readonly rows: QueryRow[];
592
+ frontier: QueryRow[];
593
+ iterations: number;
594
+ absorb(step: QueryResult): void;
595
+ }
596
+ /**
597
+ * Drives one recursive CTE to its fixpoint: absorb() renames a step result positionally onto the
598
+ * base columns, appends what is new (all rows for UNION ALL, unseen rows for UNION), and refreshes
599
+ * the frontier. Hard caps bound runaway recursions explicitly instead of exhausting memory.
600
+ */
601
+ export declare function createRecursiveCteState(base: QueryResult, all: boolean): RecursiveCteState;
602
+ /** The direct child expressions of a node; subqueries and EXISTS scope their own blocks. */
603
+ export declare function childExpressions(expression: Expression): Expression[];
604
+ /**
605
+ * `childExpressions` in reverse: the same node with each child replaced by `map(child)`. A node
606
+ * with no children — or one whose children are positions this cannot rebuild, like a window's
607
+ * own clauses — comes back untouched, so a caller that rewrites a subtree has to reach those
608
+ * itself. Kept beside `childExpressions` because the two have to agree about what a child is.
609
+ */
610
+ export declare function mapChildExpressions(expression: Expression, map: (child: Expression) => Expression): Expression;
611
+ /**
612
+ * Visits every expression position of one block — select, predicates, HAVING, GROUP BY,
613
+ * ORDER BY, and join conditions — without descending into nested blocks. Every plan feature
614
+ * that scans "all expressions of a block" goes through here, so a future clause is added to
615
+ * one list instead of one per feature.
616
+ */
617
+ export declare function forEachBlockExpression(block: CompiledQuery, visit: (expression: Expression) => void): void;
618
+ /** Visits every nested block of one block's sources (derived, union, windowed, recursive). */
619
+ export declare function forEachNestedBlock(block: CompiledQuery, visit: (nested: CompiledQuery) => void): void;
620
+ /**
621
+ * Rewrites every expression slot of one block in place, the writing counterpart to
622
+ * `forEachBlockExpression`. The mapper receives each root expression and returns its
623
+ * replacement; returning the same object leaves the slot untouched.
624
+ */
625
+ export declare function mapBlockExpressions(block: CompiledQuery, map: (expression: Expression) => Expression): void;
626
+ /**
627
+ * Replaces CURRENT_DATE / CURRENT_TIMESTAMP / LOCALTIME with one reading of the clock, so that
628
+ * every row of one execution — and both executors — see a single instant. Plans that never
629
+ * mention them are returned untouched, which is every plan the parser did not flag.
630
+ */
631
+ export declare function resolveStatementDatetimes(plan: CompiledQuery, now?: Date): CompiledQuery;
632
+ /** One top-level full-text MATCH conjunct of a plan, with its resolved column expressions. */
633
+ export interface FtsMatchConjunct {
634
+ columns: Expression[];
635
+ query: string;
636
+ }
637
+ /**
638
+ * The plan's top-level `MATCH ... AGAINST` conjuncts — the ones index pruning may exploit,
639
+ * because every result row must satisfy them. This is the sole authority on how a bare MATCH
640
+ * appears in `plan.predicates`: `splitCondition` wraps non-comparison booleans as
641
+ * `IS TRUE` predicates, and a test pins that pairing so an optimizer or parser change that
642
+ * rewraps the conjunct fails loudly instead of silently disabling pruning. Unexpanded `"*"`
643
+ * documents and negated/OR-wrapped matches are deliberately excluded.
644
+ */
645
+ export declare function topLevelFtsMatchConjuncts(plan: CompiledQuery): FtsMatchConjunct[];
646
+ /**
647
+ * True when the plan reads anything beyond its single flat base scan: a nested block (derived
648
+ * table, set-operation branch, windowed or recursive source) or a subquery/EXISTS expression.
649
+ * Selectivity proofs that reason only about the base scan's predicates (the live-query zone
650
+ * gate) are unsound for such plans — a change the base predicates reject can still shift a
651
+ * value the nested read produces — so they must widen to "can affect".
652
+ */
653
+ export declare function planReadsBeyondSingleScan(plan: CompiledQuery): boolean;
654
+ /** True when any expression in the plan or its nested blocks is a full-text node. */
655
+ export declare function planContainsFts(plan: CompiledQuery, op?: "match" | "bm25"): boolean;
656
+ /**
657
+ * Expands every `MATCH(*)`/`BM25(*)` in the plan into the single scan source's searchable
658
+ * columns (string, number, datetime — booleans are excluded from documents), and enforces the
659
+ * v1 restriction that a full-text document draws from exactly one base table source. Runs at
660
+ * prepare time when the catalog is known. Copy-on-write: plans without full-text nodes pass
661
+ * through untouched, and full-text plans are cloned before rewriting — the input is often the
662
+ * compile cache's own copy (subquery resolution returns the original plan when it has nothing
663
+ * to resolve), and freezing an expansion into the cache would pin a stale column list across
664
+ * later migrations.
665
+ */
666
+ export declare function expandFtsColumns(plan: CompiledQuery, searchableColumnsFor: (tableName: string) => readonly string[] | undefined): CompiledQuery;
667
+ /**
668
+ * Appends window-function columns to an executed inner-block result. Rows sort stably by the
669
+ * hidden partition and ordering aliases with the same comparison semantics as ORDER BY;
670
+ * ROW_NUMBER numbers rows per partition, RANK shares ranks across ordering ties with gaps, and
671
+ * DENSE_RANK shares without gaps. Without OVER ordering every partition row is a peer.
672
+ */
673
+ export declare function applyWindowFunctions(result: QueryResult, windows: readonly WindowSpec[]): QueryResult;
674
+ /** Correctness reference retained while the vector executor matures. */
675
+ export declare function executeRowQuery(plan: CompiledQuery, tables: ReadonlyMap<string, DatabaseRow[]>): QueryResult;
676
+ /** One ORDER BY resolution source: an alias and the columns a wildcard select exposes from it. */
677
+ export interface OrderSourceShape {
678
+ readonly alias: string;
679
+ readonly columns: readonly string[];
680
+ }
681
+ /**
682
+ * Resolves one ORDER BY reference to the output column that carries its values, throwing when
683
+ * nothing matches. Dropping an unresolved sort key silently would return rows in an arbitrary
684
+ * order with no sign of the problem, which paging built on ORDER BY turns into skipped and
685
+ * repeated rows.
686
+ */
687
+ export declare function orderOutputName(expression: Expression, select: readonly SelectItem[], sources: readonly OrderSourceShape[]): string;
688
+ export interface ListMembership {
689
+ set: ReadonlySet<unknown>;
690
+ hasNull: boolean;
691
+ }
692
+ /**
693
+ * IN lists produced by subquery materialization can hold many thousands of literals, and
694
+ * probing them per row makes membership quadratic. A list whose items are all literals
695
+ * gets one hash set of comparable values (plus a null flag), cached weakly on the list
696
+ * node so repeated executions of a prepared plan reuse it. Lists with non-literal items
697
+ * return null and take the general per-row path.
698
+ */
699
+ export declare function cachedListMembership(node: object, items: ReadonlyArray<{
700
+ kind: string;
701
+ }>): ListMembership | null;
702
+ /** Compiles a LIKE pattern (% = any run, _ = any character) to an anchored RegExp, cached. */
703
+ export declare function likeRegExp(pattern: string, caseInsensitive?: boolean, escape?: string): RegExp;
704
+ /**
705
+ * A compiled LIKE matcher. Patterns shaped `abc%`, `%abc`, `%abc%`, and `abc` skip the regular
706
+ * expression entirely — prefix/suffix/containment string scans are several times faster and
707
+ * dominate real workloads — and everything else falls back to the anchored RegExp.
708
+ */
709
+ export declare function likeMatches(pattern: string, value: string, caseInsensitive?: boolean, escape?: string): boolean;
710
+ /** Splits a quantified operator like "> ANY" into its comparison and quantifier. */
711
+ export declare function parseQuantified(operator: PredicateOperator): {
712
+ comparison: ComparisonOperator;
713
+ quantifier: "any" | "all";
714
+ } | undefined;
715
+ /**
716
+ * SQL quantified comparison over a resolved value list, with three-valued logic: an empty list
717
+ * is false for ANY and true for ALL before any comparison happens; otherwise NULL operands make
718
+ * the result unknown unless a definite answer exists.
719
+ */
720
+ export declare function quantifiedComparison(comparison: ComparisonOperator, quantifier: "any" | "all", left: unknown, values: readonly unknown[]): boolean | null;
721
+ /** Null-safe distinctness: NULL is not distinct from NULL, and distinct from every value. */
722
+ export declare function distinctFromComparison(left: unknown, right: unknown): boolean;
723
+ /**
724
+ * Evaluates a boolean expression tree with SQL three-valued logic: comparisons over NULL are
725
+ * unknown (null), AND/OR/NOT propagate unknown, and only the caller collapses unknown to false.
726
+ * Leaf values come from the executor-specific callback so both executors share these semantics.
727
+ */
728
+ export declare function evaluateBooleanExpression(expression: Expression, evaluateValue: (expression: Expression) => unknown): boolean | null;
729
+ export declare function hasAggregate(expression: Expression): boolean;
730
+ /** The column references inside one expression; a subquery contributes none (its own scope). */
731
+ export declare function expressionColumnNames(expression: Expression): string[];
732
+ export declare function expressionColumns(expression: Expression): string[];
733
+ export declare function expressionAliases(expression: Expression): Set<string>;
734
+ /**
735
+ * Resolves an explicit NULLS FIRST/LAST placement for one order term. Returns undefined when
736
+ * no explicit placement applies (either none was requested or neither side is NULL); otherwise
737
+ * the signed placement, which is absolute — direction negation must not apply to it. Two NULLs
738
+ * return 0 so the comparison falls through to the next term.
739
+ */
740
+ export declare function explicitNullOrder(left: unknown, right: unknown, nulls: "first" | "last" | undefined): number | undefined;
741
+ export interface SelectBlockParts {
742
+ sql: string;
743
+ base: TableSource;
744
+ joins: JoinPlan[];
745
+ select: SelectItem[];
746
+ distinct: boolean;
747
+ predicates: Predicate[];
748
+ /** Raw GROUP BY expressions; DISTINCT desugaring appends to a copy here. */
749
+ groupBy: Expression[];
750
+ having: Predicate[];
751
+ orderBy: CompiledQuery["orderBy"];
752
+ limit?: number;
753
+ offset?: number;
754
+ limitParameter?: number;
755
+ offsetParameter?: number;
756
+ limitWithTies?: boolean;
757
+ /** GROUP BY GROUPING SETS/ROLLUP/CUBE: the grouping lists to union; groupBy is then unused. */
758
+ groupingSets?: Expression[][];
759
+ }
760
+ export declare function assembleSelectBlock(parts: SelectBlockParts, nextSequence: () => number): CompiledQuery;
761
+ /**
762
+ * Expands a pending SELECT DISTINCT * against known input columns: the select list becomes
763
+ * every wildcard output (alias-qualified when more than one source contributes), and GROUP BY
764
+ * over those same columns provides the deduplication through the grouped executor. Runs
765
+ * exactly once per execution entry, like MATCH(*) expansion.
766
+ */
767
+ export declare function expandDistinctWildcard(plan: CompiledQuery, columnsOf: (tableName: string) => readonly string[] | undefined): CompiledQuery;
768
+ /**
769
+ * Turns every source carrying a column alias list into a derived projection that renames the
770
+ * table's columns positionally (E051-09). The table's own column order is only known here, so
771
+ * the parser records the names and this pass — one per execution entry — applies them.
772
+ */
773
+ /** Whether any block of the plan reads a table name the catalog answers with a view. */
774
+ export declare function planReadsViews(plan: CompiledQuery, isView: (name: string) => boolean): boolean;
775
+ /**
776
+ * Replaces every reference to a view with the query it stands for, as a derived table under the
777
+ * reference's own alias (F031-02). A view whose body reads another view expands too, up to a
778
+ * depth that stops a cycle from recursing forever — a view cannot be defined in terms of itself,
779
+ * but two views can be redefined into a loop after the fact.
780
+ */
781
+ export declare function expandViewSources(plan: CompiledQuery, viewFor: (tableName: string) => CompiledQuery | undefined, maxDepth?: number): CompiledQuery;
782
+ export declare function planHasSourceColumnAliases(plan: CompiledQuery): boolean;
783
+ /**
784
+ * FETCH FIRST n ROWS WITH TIES (F866). The plan runs without its limit — a limit pushed into a
785
+ * scan cannot know whether the next row ties — and the ordered result is trimmed here: rows up
786
+ * to the limit, plus every following row equal to the last one on all ORDER BY columns.
787
+ */
788
+ export declare function withTiesPlan(plan: CompiledQuery): {
789
+ plan: CompiledQuery;
790
+ trim: (result: QueryResult) => QueryResult;
791
+ };
792
+ /** Whether any block of the plan still carries an unresolved NATURAL join marker. */
793
+ export declare function planHasNaturalJoins(plan: CompiledQuery): boolean;
794
+ /**
795
+ * Resolves NATURAL joins into ordinary equality conditions (F401-01): the join columns are the
796
+ * names the new source shares with the sources already joined, compared in the order they are
797
+ * declared. A pair with no shared column is a cross join, which is what the standard says.
798
+ */
799
+ export declare function expandNaturalJoins(plan: CompiledQuery, columnsOf: (tableName: string) => readonly string[] | undefined): CompiledQuery;
800
+ export declare function expandSourceColumnAliases(plan: CompiledQuery, columnsOf: (tableName: string) => readonly string[] | undefined): CompiledQuery;
801
+ /**
802
+ * Expands `alias.*` select items into that source's columns (E051-07), at every nesting depth.
803
+ * Output names follow the same rule as a bare `*`: the column's own name when the block reads
804
+ * one source, and `alias.column` when it reads several, so two sources cannot collide.
805
+ * Runs once per execution entry, like MATCH(*) and DISTINCT * expansion.
806
+ */
807
+ export declare function expandQualifiedWildcards(plan: CompiledQuery, columnsOf: (tableName: string) => readonly string[] | undefined): CompiledQuery;
808
+ /** Wraps compound members into the set-operation source the executor folds left to right. */
809
+ export declare function compoundSelectBlock(sql: string, blocks: CompiledQuery[], ops: SetOperator[], tail: SelectTail, nextSequence: () => number): CompiledQuery;
810
+ /**
811
+ * Detects a pure projection wrapper over one derived block — the shape the ORDER-BY-expression
812
+ * desugar emits: no joins, filters, grouping, ordering, or paging of its own, and every select
813
+ * item passing an inner output alias through under the same name. Whole-plan strategies (the
814
+ * streamed scan today) run the inner block and project its result, so a hidden ordering column
815
+ * never changes which execution paths a query is eligible for — `.search()` performs the same
816
+ * whether or not the caller also selects the score.
817
+ */
818
+ export declare function transparentProjectionSource(plan: CompiledQuery): {
819
+ inner: CompiledQuery;
820
+ aliases: string[];
821
+ } | undefined;
822
+ /** Projects a result to a wrapper's visible aliases, preserving row order. */
823
+ export declare function projectResultColumns(result: QueryResult, aliases: readonly string[]): QueryResult;
824
+ /** Names a derived (subquery or expanded CTE) source under the shared sequence. */
825
+ export declare function derivedTableSource(derived: CompiledQuery, alias: string, nextSequence: () => number): TableSource;
826
+ /** The parser's LIMIT range contract, shared with the typed builder. */
827
+ export declare function validateLimit(limit: number): number;
828
+ /**
829
+ * `TIMESTAMP '2026-01-02 03:04:05'` — the standard's spelling, which writes a space where ISO
830
+ * writes a T and leaves the time off entirely for midnight. A literal without a zone is UTC, the
831
+ * same reading `DATE` already takes and the same one every datetime in a Minnow database has.
832
+ */
833
+ export declare function timestampLiteral(text: string): Date;
834
+ /** The parser's OFFSET range contract, shared with the typed builder. */
835
+ export declare function validateOffset(offset: number): number;
836
+ /**
837
+ * Splits a parsed boolean expression into the plan's AND-list of predicates. Top-level ANDs and
838
+ * plain comparisons keep the classic {left, operator, right} shape (so predicate pushdown, zone
839
+ * maps, and the dictionary fast path see exactly what they always saw); any OR/NOT subtree or bare
840
+ * boolean expression becomes a single IS TRUE predicate evaluated with three-valued logic.
841
+ */
842
+ export declare function splitCondition(expression: Expression): Predicate[];
843
+ export {};
844
+ //# sourceMappingURL=query.d.ts.map