@minnowdb/core 0.0.1 → 0.1.0
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/LICENSE +21 -0
- package/README.md +27 -1
- package/dist/block-format/block.d.ts +46 -0
- package/dist/block-format/block.d.ts.map +1 -0
- package/dist/block-format/block.js +244 -0
- package/dist/block-format/block.js.map +1 -0
- package/dist/block-format/checksum.d.ts +7 -0
- package/dist/block-format/checksum.d.ts.map +1 -0
- package/dist/block-format/checksum.js +56 -0
- package/dist/block-format/checksum.js.map +1 -0
- package/dist/block-format/codecs.d.ts +24 -0
- package/dist/block-format/codecs.d.ts.map +1 -0
- package/dist/block-format/codecs.js +102 -0
- package/dist/block-format/codecs.js.map +1 -0
- package/dist/block-format/column.d.ts +8 -0
- package/dist/block-format/column.d.ts.map +1 -0
- package/dist/block-format/column.js +166 -0
- package/dist/block-format/column.js.map +1 -0
- package/dist/block-format/index.d.ts +7 -0
- package/dist/block-format/index.d.ts.map +1 -0
- package/dist/block-format/index.js +7 -0
- package/dist/block-format/index.js.map +1 -0
- package/dist/block-format/physical.d.ts +20 -0
- package/dist/block-format/physical.d.ts.map +1 -0
- package/dist/block-format/physical.js +439 -0
- package/dist/block-format/physical.js.map +1 -0
- package/dist/block-format/types.d.ts +93 -0
- package/dist/block-format/types.d.ts.map +1 -0
- package/dist/block-format/types.js +2 -0
- package/dist/block-format/types.js.map +1 -0
- package/dist/engine/artifact-cache.d.ts +22 -0
- package/dist/engine/artifact-cache.d.ts.map +1 -0
- package/dist/engine/artifact-cache.js +68 -0
- package/dist/engine/artifact-cache.js.map +1 -0
- package/dist/engine/batch.d.ts +28 -0
- package/dist/engine/batch.d.ts.map +1 -0
- package/dist/engine/batch.js +38 -0
- package/dist/engine/batch.js.map +1 -0
- package/dist/engine/buffered-writer.d.ts +43 -0
- package/dist/engine/buffered-writer.d.ts.map +1 -0
- package/dist/engine/buffered-writer.js +158 -0
- package/dist/engine/buffered-writer.js.map +1 -0
- package/dist/engine/catalog.d.ts +82 -0
- package/dist/engine/catalog.d.ts.map +1 -0
- package/dist/engine/catalog.js +47 -0
- package/dist/engine/catalog.js.map +1 -0
- package/dist/engine/client.d.ts +211 -0
- package/dist/engine/client.d.ts.map +1 -0
- package/dist/engine/client.js +538 -0
- package/dist/engine/client.js.map +1 -0
- package/dist/engine/coordinator.d.ts +17 -0
- package/dist/engine/coordinator.d.ts.map +1 -0
- package/dist/engine/coordinator.js +60 -0
- package/dist/engine/coordinator.js.map +1 -0
- package/dist/engine/database.d.ts +661 -0
- package/dist/engine/database.d.ts.map +1 -0
- package/dist/engine/database.js +10313 -0
- package/dist/engine/database.js.map +1 -0
- package/dist/engine/defaults.d.ts +33 -0
- package/dist/engine/defaults.d.ts.map +1 -0
- package/dist/engine/defaults.js +87 -0
- package/dist/engine/defaults.js.map +1 -0
- package/dist/engine/dsl/db.d.ts +137 -0
- package/dist/engine/dsl/db.d.ts.map +1 -0
- package/dist/engine/dsl/db.js +161 -0
- package/dist/engine/dsl/db.js.map +1 -0
- package/dist/engine/dsl/expression.d.ts +172 -0
- package/dist/engine/dsl/expression.d.ts.map +1 -0
- package/dist/engine/dsl/expression.js +397 -0
- package/dist/engine/dsl/expression.js.map +1 -0
- package/dist/engine/dsl/index.d.ts +8 -0
- package/dist/engine/dsl/index.d.ts.map +1 -0
- package/dist/engine/dsl/index.js +7 -0
- package/dist/engine/dsl/index.js.map +1 -0
- package/dist/engine/dsl/live-query.d.ts +45 -0
- package/dist/engine/dsl/live-query.d.ts.map +1 -0
- package/dist/engine/dsl/live-query.js +116 -0
- package/dist/engine/dsl/live-query.js.map +1 -0
- package/dist/engine/dsl/mutations.d.ts +123 -0
- package/dist/engine/dsl/mutations.d.ts.map +1 -0
- package/dist/engine/dsl/mutations.js +241 -0
- package/dist/engine/dsl/mutations.js.map +1 -0
- package/dist/engine/dsl/select-query-builder.d.ts +148 -0
- package/dist/engine/dsl/select-query-builder.d.ts.map +1 -0
- package/dist/engine/dsl/select-query-builder.js +377 -0
- package/dist/engine/dsl/select-query-builder.js.map +1 -0
- package/dist/engine/dsl/sql-tag.d.ts +46 -0
- package/dist/engine/dsl/sql-tag.d.ts.map +1 -0
- package/dist/engine/dsl/sql-tag.js +85 -0
- package/dist/engine/dsl/sql-tag.js.map +1 -0
- package/dist/engine/dsl/types.d.ts +133 -0
- package/dist/engine/dsl/types.d.ts.map +1 -0
- package/dist/engine/dsl/types.js +9 -0
- package/dist/engine/dsl/types.js.map +1 -0
- package/dist/engine/errors.d.ts +55 -0
- package/dist/engine/errors.d.ts.map +1 -0
- package/dist/engine/errors.js +81 -0
- package/dist/engine/errors.js.map +1 -0
- package/dist/engine/fts.d.ts +93 -0
- package/dist/engine/fts.d.ts.map +1 -0
- package/dist/engine/fts.js +273 -0
- package/dist/engine/fts.js.map +1 -0
- package/dist/engine/group-index.d.ts +32 -0
- package/dist/engine/group-index.d.ts.map +1 -0
- package/dist/engine/group-index.js +366 -0
- package/dist/engine/group-index.js.map +1 -0
- package/dist/engine/index.d.ts +13 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +12 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/join-index.d.ts +12 -0
- package/dist/engine/join-index.d.ts.map +1 -0
- package/dist/engine/join-index.js +217 -0
- package/dist/engine/join-index.js.map +1 -0
- package/dist/engine/live.d.ts +86 -0
- package/dist/engine/live.d.ts.map +1 -0
- package/dist/engine/live.js +289 -0
- package/dist/engine/live.js.map +1 -0
- package/dist/engine/memory.d.ts +37 -0
- package/dist/engine/memory.d.ts.map +1 -0
- package/dist/engine/memory.js +119 -0
- package/dist/engine/memory.js.map +1 -0
- package/dist/engine/optimizer.d.ts +20 -0
- package/dist/engine/optimizer.d.ts.map +1 -0
- package/dist/engine/optimizer.js +1170 -0
- package/dist/engine/optimizer.js.map +1 -0
- package/dist/engine/query-cache.d.ts +10 -0
- package/dist/engine/query-cache.d.ts.map +1 -0
- package/dist/engine/query-cache.js +58 -0
- package/dist/engine/query-cache.js.map +1 -0
- package/dist/engine/query.d.ts +844 -0
- package/dist/engine/query.d.ts.map +1 -0
- package/dist/engine/query.js +7450 -0
- package/dist/engine/query.js.map +1 -0
- package/dist/engine/schema-wire.d.ts +92 -0
- package/dist/engine/schema-wire.d.ts.map +1 -0
- package/dist/engine/schema-wire.js +115 -0
- package/dist/engine/schema-wire.js.map +1 -0
- package/dist/engine/schema.d.ts +394 -0
- package/dist/engine/schema.d.ts.map +1 -0
- package/dist/engine/schema.js +709 -0
- package/dist/engine/schema.js.map +1 -0
- package/dist/engine/sort-keys.d.ts +36 -0
- package/dist/engine/sort-keys.d.ts.map +1 -0
- package/dist/engine/sort-keys.js +60 -0
- package/dist/engine/sort-keys.js.map +1 -0
- package/dist/engine/sql-json.d.ts +30 -0
- package/dist/engine/sql-json.d.ts.map +1 -0
- package/dist/engine/sql-json.js +120 -0
- package/dist/engine/sql-json.js.map +1 -0
- package/dist/engine/sql-semantics.d.ts +31 -0
- package/dist/engine/sql-semantics.d.ts.map +1 -0
- package/dist/engine/sql-semantics.js +121 -0
- package/dist/engine/sql-semantics.js.map +1 -0
- package/dist/engine/vector.d.ts +87 -0
- package/dist/engine/vector.d.ts.map +1 -0
- package/dist/engine/vector.js +4227 -0
- package/dist/engine/vector.js.map +1 -0
- package/dist/engine/worker-host.d.ts +48 -0
- package/dist/engine/worker-host.d.ts.map +1 -0
- package/dist/engine/worker-host.js +501 -0
- package/dist/engine/worker-host.js.map +1 -0
- package/dist/engine/worker.d.ts +2 -0
- package/dist/engine/worker.d.ts.map +1 -0
- package/dist/engine/worker.js +14 -0
- package/dist/engine/worker.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/plan/index.d.ts +17 -0
- package/dist/plan/index.d.ts.map +1 -0
- package/dist/plan/index.js +17 -0
- package/dist/plan/index.js.map +1 -0
- package/dist/storage/fixture-shape.d.ts +42 -0
- package/dist/storage/fixture-shape.d.ts.map +1 -0
- package/dist/storage/fixture-shape.js +146 -0
- package/dist/storage/fixture-shape.js.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/indexeddb.d.ts +139 -0
- package/dist/storage/indexeddb.d.ts.map +1 -0
- package/dist/storage/indexeddb.js +3161 -0
- package/dist/storage/indexeddb.js.map +1 -0
- package/dist/storage/memory.d.ts +121 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +1455 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/snapshot.d.ts +108 -0
- package/dist/storage/snapshot.d.ts.map +1 -0
- package/dist/storage/snapshot.js +276 -0
- package/dist/storage/snapshot.js.map +1 -0
- package/dist/storage/types.d.ts +895 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +1549 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/testing/index.d.ts +76 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +233 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/seeds.d.ts +11 -0
- package/dist/testing/seeds.d.ts.map +1 -0
- package/dist/testing/seeds.js +50 -0
- package/dist/testing/seeds.js.map +1 -0
- package/dist/transactions/index.d.ts +148 -0
- package/dist/transactions/index.d.ts.map +1 -0
- package/dist/transactions/index.js +662 -0
- package/dist/transactions/index.js.map +1 -0
- package/dist/worker-protocol/index.d.ts +84 -0
- package/dist/worker-protocol/index.d.ts.map +1 -0
- package/dist/worker-protocol/index.js +117 -0
- package/dist/worker-protocol/index.js.map +1 -0
- package/package.json +66 -16
- package/sql-feature-matrix.json +1275 -0
- package/index.d.ts +0 -1
- 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
|