@minnowdb/core 0.6.9 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/block-format/block.js +254 -325
  2. package/dist/block-format/checksum.js +30 -52
  3. package/dist/block-format/codecs.js +112 -125
  4. package/dist/block-format/column.js +187 -205
  5. package/dist/block-format/index.js +5 -1
  6. package/dist/block-format/physical.js +371 -387
  7. package/dist/block-format/types.js +4 -1
  8. package/dist/block-format/unicode.js +30 -39
  9. package/dist/date-value.d.ts +5 -0
  10. package/dist/date-value.js +71 -41
  11. package/dist/engine/artifact-cache.js +106 -116
  12. package/dist/engine/batch.js +36 -44
  13. package/dist/engine/buffered-writer.js +156 -158
  14. package/dist/engine/byte-estimates.js +20 -22
  15. package/dist/engine/cache-limits.js +24 -25
  16. package/dist/engine/cancellation.js +5 -3
  17. package/dist/engine/catalog.js +64 -73
  18. package/dist/engine/client.js +715 -780
  19. package/dist/engine/database.js +15952 -18465
  20. package/dist/engine/defaults.js +104 -111
  21. package/dist/engine/errors.js +113 -128
  22. package/dist/engine/fts.js +233 -280
  23. package/dist/engine/group-index.js +287 -321
  24. package/dist/engine/index.js +23 -12
  25. package/dist/engine/join-index.js +177 -186
  26. package/dist/engine/keyed-live.js +168 -173
  27. package/dist/engine/live-api.js +0 -1
  28. package/dist/engine/live-equal.js +32 -37
  29. package/dist/engine/live.js +603 -647
  30. package/dist/engine/memory.js +109 -111
  31. package/dist/engine/optimizer.d.ts +19 -1
  32. package/dist/engine/optimizer.js +2642 -2515
  33. package/dist/engine/point-read.d.ts +4 -2
  34. package/dist/engine/point-read.js +121 -171
  35. package/dist/engine/query-api.js +12 -3
  36. package/dist/engine/query-cache.js +61 -69
  37. package/dist/engine/query.d.ts +45 -0
  38. package/dist/engine/query.js +8506 -9375
  39. package/dist/engine/result-wire.js +221 -252
  40. package/dist/engine/schema-wire.js +97 -112
  41. package/dist/engine/schema.js +1099 -1254
  42. package/dist/engine/sort-keys.js +315 -389
  43. package/dist/engine/sql-domains.d.ts +7 -1
  44. package/dist/engine/sql-domains.js +648 -734
  45. package/dist/engine/sql-driver.js +0 -1
  46. package/dist/engine/sql-functions.d.ts +11 -0
  47. package/dist/engine/sql-functions.js +1092 -0
  48. package/dist/engine/sql-json.js +199 -218
  49. package/dist/engine/sql-semantics.d.ts +25 -4
  50. package/dist/engine/sql-semantics.js +579 -513
  51. package/dist/engine/typed-live.js +271 -293
  52. package/dist/engine/vector.d.ts +7 -1
  53. package/dist/engine/vector.js +4513 -4580
  54. package/dist/engine/worker-host.d.ts +8 -63
  55. package/dist/engine/worker-host.js +28 -1130
  56. package/dist/engine/worker-indexeddb.d.ts +1 -0
  57. package/dist/engine/worker-indexeddb.js +3 -0
  58. package/dist/engine/worker-memory.d.ts +1 -0
  59. package/dist/engine/worker-memory.js +3 -0
  60. package/dist/engine/worker-opfs.d.ts +1 -0
  61. package/dist/engine/worker-opfs.js +3 -0
  62. package/dist/engine/worker-server.d.ts +93 -0
  63. package/dist/engine/worker-server.js +999 -0
  64. package/dist/engine/worker-store-indexeddb.d.ts +2 -0
  65. package/dist/engine/worker-store-indexeddb.js +11 -0
  66. package/dist/engine/worker-store-memory.d.ts +2 -0
  67. package/dist/engine/worker-store-memory.js +6 -0
  68. package/dist/engine/worker-store-opfs.d.ts +2 -0
  69. package/dist/engine/worker-store-opfs.js +9 -0
  70. package/dist/engine/worker.js +0 -12
  71. package/dist/engine/write-block-planner.js +93 -100
  72. package/dist/plan/index.js +15 -16
  73. package/dist/plan/model.d.ts +9 -1
  74. package/dist/plan/model.js +20 -27
  75. package/dist/storage/index.js +0 -12
  76. package/dist/storage/indexeddb.js +11776 -13171
  77. package/dist/storage/memory.js +1198 -1241
  78. package/dist/storage/opfs/files.js +238 -295
  79. package/dist/storage/opfs/index.js +9 -3
  80. package/dist/storage/opfs/leader.js +4386 -4856
  81. package/dist/storage/opfs/rpc.js +223 -259
  82. package/dist/storage/opfs/snapshot-ledger.js +219 -260
  83. package/dist/storage/opfs/store.js +884 -1003
  84. package/dist/storage/persistence.js +59 -74
  85. package/dist/storage/snapshot-stream.js +788 -826
  86. package/dist/storage/snapshot.js +36 -37
  87. package/dist/storage/toolkit/extents.js +444 -520
  88. package/dist/storage/toolkit/index.js +28 -29
  89. package/dist/storage/toolkit/record-core.js +5792 -6377
  90. package/dist/storage/toolkit/sync-file.js +34 -42
  91. package/dist/storage/toolkit/wal.js +92 -127
  92. package/dist/storage/toolkit/wire.js +232 -256
  93. package/dist/storage/types.js +2952 -3228
  94. package/dist/testing/block-store-conformance.js +1556 -1629
  95. package/dist/testing/index.js +310 -291
  96. package/dist/testing/opfs-shim.js +280 -312
  97. package/dist/testing/simulator.js +496 -534
  98. package/dist/testing/sqllogictest.js +425 -365
  99. package/dist/transactions/index.js +1464 -1712
  100. package/dist/worker-protocol/index.js +70 -69
  101. package/package.json +20 -2
  102. package/postgres-feature-profile.json +15 -5
  103. package/sql-feature-matrix.json +252 -2
@@ -1,239 +1,220 @@
1
1
  import { stringArgument } from "./sql-semantics.js";
2
2
  import { externalSqlDomainValue, jsonDomainDocument } from "./sql-domains.js";
3
3
  import { MAX_CACHEABLE_TEXT_CHARACTERS, MAX_SQL_SCALAR_RESULT_CHARACTERS } from "./cache-limits.js";
4
- export function parseJsonPath(path, caller) {
5
- const text = stringArgument(caller, path).trim();
6
- if (text.length > MAX_CACHEABLE_TEXT_CHARACTERS) {
7
- throw new RangeError(`${caller} path exceeds ${String(MAX_CACHEABLE_TEXT_CHARACTERS)} characters`);
8
- }
9
- if (!text.startsWith("$"))
10
- throw new TypeError(`${caller} paths start at $`);
11
- const steps = [];
12
- let cursor = 1;
13
- while (cursor < text.length) {
14
- if (text[cursor] === ".") {
15
- cursor += 1;
16
- const start = cursor;
17
- while (cursor < text.length && /[A-Za-z0-9_]/.test(text[cursor] ?? ""))
18
- cursor += 1;
19
- if (cursor === start)
20
- throw new TypeError(`${caller} path expects a member name after .`);
21
- steps.push({ kind: "member", name: text.slice(start, cursor), index: 0 });
22
- continue;
23
- }
24
- if (text[cursor] === "[") {
25
- const close = text.indexOf("]", cursor);
26
- if (close === -1)
27
- throw new TypeError(`${caller} path has an unclosed subscript`);
28
- const inner = text.slice(cursor + 1, close).trim();
29
- cursor = close + 1;
30
- if (/^\d+$/.test(inner)) {
31
- steps.push({ kind: "index", name: "", index: Number(inner) });
32
- continue;
33
- }
34
- const quoted = /^'(.*)'$/.exec(inner) ?? /^"(.*)"$/.exec(inner);
35
- if (quoted?.[1] !== undefined) {
36
- steps.push({ kind: "member", name: quoted[1], index: 0 });
37
- continue;
38
- }
39
- throw new TypeError(`${caller} paths take array indexes and member names, not: ${inner}`);
40
- }
41
- throw new TypeError(`${caller} path is not understood: ${text}`);
42
- }
43
- return steps;
4
+ function parseJsonPath(path, caller) {
5
+ const text = stringArgument(caller, path).trim();
6
+ if (text.length > MAX_CACHEABLE_TEXT_CHARACTERS) {
7
+ throw new RangeError(`${caller} path exceeds ${String(MAX_CACHEABLE_TEXT_CHARACTERS)} characters`);
8
+ }
9
+ if (!text.startsWith("$"))
10
+ throw new TypeError(`${caller} paths start at $`);
11
+ const steps = [];
12
+ let cursor = 1;
13
+ while (cursor < text.length) {
14
+ if (text[cursor] === ".") {
15
+ cursor += 1;
16
+ const start = cursor;
17
+ while (cursor < text.length && /[A-Za-z0-9_]/.test(text[cursor] ?? ""))
18
+ cursor += 1;
19
+ if (cursor === start)
20
+ throw new TypeError(`${caller} path expects a member name after .`);
21
+ steps.push({ kind: "member", name: text.slice(start, cursor), index: 0 });
22
+ continue;
23
+ }
24
+ if (text[cursor] === "[") {
25
+ const close = text.indexOf("]", cursor);
26
+ if (close === -1)
27
+ throw new TypeError(`${caller} path has an unclosed subscript`);
28
+ const inner = text.slice(cursor + 1, close).trim();
29
+ cursor = close + 1;
30
+ if (/^\d+$/.test(inner)) {
31
+ steps.push({ kind: "index", name: "", index: Number(inner) });
32
+ continue;
33
+ }
34
+ const quoted = /^'(.*)'$/.exec(inner) ?? /^"(.*)"$/.exec(inner);
35
+ if (quoted?.[1] !== void 0) {
36
+ steps.push({ kind: "member", name: quoted[1], index: 0 });
37
+ continue;
38
+ }
39
+ throw new TypeError(`${caller} paths take array indexes and member names, not: ${inner}`);
40
+ }
41
+ throw new TypeError(`${caller} path is not understood: ${text}`);
42
+ }
43
+ return steps;
44
44
  }
45
- /** Walks one path over a document, reporting whether it selected anything. */
46
- export function jsonAtPath(document, path, caller) {
47
- const steps = parseJsonPath(path, caller);
48
- let current;
49
- const source = boundedJsonDocument(document, caller);
50
- try {
51
- current = JSON.parse(source);
52
- }
53
- catch {
54
- // A document that is not JSON selects nothing rather than failing the whole statement,
55
- // matching the standard's default ON ERROR behaviour for these functions.
45
+ function jsonAtPath(document, path, caller) {
46
+ const steps = parseJsonPath(path, caller);
47
+ let current;
48
+ const source = boundedJsonDocument(document, caller);
49
+ try {
50
+ current = JSON.parse(source);
51
+ } catch {
52
+ return { found: false };
53
+ }
54
+ for (const step of steps) {
55
+ if (current === null || current === void 0)
56
+ return { found: false };
57
+ if (step.kind === "index") {
58
+ if (!Array.isArray(current))
56
59
  return { found: false };
57
- }
58
- for (const step of steps) {
59
- if (current === null || current === undefined)
60
- return { found: false };
61
- if (step.kind === "index") {
62
- if (!Array.isArray(current))
63
- return { found: false };
64
- if (step.index >= current.length)
65
- return { found: false };
66
- current = current[step.index];
67
- continue;
68
- }
69
- if (typeof current !== "object" || Array.isArray(current))
70
- return { found: false };
71
- const members = current;
72
- if (!Object.hasOwn(members, step.name))
73
- return { found: false };
74
- current = members[step.name];
75
- }
76
- return { found: true, value: current };
60
+ if (step.index >= current.length)
61
+ return { found: false };
62
+ current = current[step.index];
63
+ continue;
64
+ }
65
+ if (typeof current !== "object" || Array.isArray(current))
66
+ return { found: false };
67
+ const members = current;
68
+ if (!Object.hasOwn(members, step.name))
69
+ return { found: false };
70
+ current = members[step.name];
71
+ }
72
+ return { found: true, value: current };
77
73
  }
78
- /**
79
- * One step of PostgreSQL's `->`/`->>` access. A text key selects an object member; an integer
80
- * key selects an array element, counting from the end when negative. The behaviour follows
81
- * PostgreSQL's `json` type: a document of the wrong shape for the key selects nothing (NULL)
82
- * rather than jsonb's scalar-as-one-element-array reading. Unlike the SQL/JSON functions, whose
83
- * standard ON ERROR default swallows malformed documents, PostgreSQL's operators only exist on
84
- * values already parsed as json, so a document that is not JSON is an error here.
85
- */
86
- export function jsonArrowStep(document, key, caller) {
87
- const source = boundedJsonDocument(document, caller);
88
- let parsed;
89
- try {
90
- parsed = JSON.parse(source);
91
- }
92
- catch {
93
- throw new TypeError(`${caller} requires a JSON document`);
94
- }
95
- const step = externalSqlDomainValue(key);
96
- if (typeof step === "number") {
97
- if (!Number.isInteger(step)) {
98
- throw new TypeError(`${caller} array positions are integers`);
99
- }
100
- if (!Array.isArray(parsed))
101
- return { found: false };
102
- const index = step < 0 ? parsed.length + step : step;
103
- if (index < 0 || index >= parsed.length)
104
- return { found: false };
105
- return { found: true, value: parsed[index] };
106
- }
107
- if (typeof step === "string") {
108
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
109
- return { found: false };
110
- }
111
- const members = parsed;
112
- if (!Object.hasOwn(members, step))
113
- return { found: false };
114
- return { found: true, value: members[step] };
115
- }
116
- throw new TypeError(`${caller} keys are member names or array positions`);
74
+ function jsonArrowStep(document, key, caller) {
75
+ const source = boundedJsonDocument(document, caller);
76
+ let parsed;
77
+ try {
78
+ parsed = JSON.parse(source);
79
+ } catch {
80
+ throw new TypeError(`${caller} requires a JSON document`);
81
+ }
82
+ const step = externalSqlDomainValue(key);
83
+ if (typeof step === "number") {
84
+ if (!Number.isInteger(step)) {
85
+ throw new TypeError(`${caller} array positions are integers`);
86
+ }
87
+ if (!Array.isArray(parsed))
88
+ return { found: false };
89
+ const index = step < 0 ? parsed.length + step : step;
90
+ if (index < 0 || index >= parsed.length)
91
+ return { found: false };
92
+ return { found: true, value: parsed[index] };
93
+ }
94
+ if (typeof step === "string") {
95
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
96
+ return { found: false };
97
+ }
98
+ const members = parsed;
99
+ if (!Object.hasOwn(members, step))
100
+ return { found: false };
101
+ return { found: true, value: members[step] };
102
+ }
103
+ throw new TypeError(`${caller} keys are member names or array positions`);
117
104
  }
118
- /** Whether a value is JSON text of the requested shape (T825). */
119
- export function jsonIsValid(document, kind) {
120
- document = externalSqlDomainValue(document);
121
- if (typeof document !== "string")
122
- return false;
123
- if (document.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
124
- throw new RangeError(`JSON document exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
125
- }
126
- let parsed;
127
- try {
128
- parsed = JSON.parse(document);
129
- }
130
- catch {
131
- return false;
132
- }
133
- const isObject = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
134
- switch (kind) {
135
- case "object":
136
- return isObject;
137
- case "array":
138
- return Array.isArray(parsed);
139
- case "scalar":
140
- return !isObject && !Array.isArray(parsed);
141
- default:
142
- return true;
143
- }
105
+ function jsonIsValid(document, kind) {
106
+ document = externalSqlDomainValue(document);
107
+ if (typeof document !== "string")
108
+ return false;
109
+ if (document.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
110
+ throw new RangeError(`JSON document exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
111
+ }
112
+ let parsed;
113
+ try {
114
+ parsed = JSON.parse(document);
115
+ } catch {
116
+ return false;
117
+ }
118
+ const isObject = typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
119
+ switch (kind) {
120
+ case "object":
121
+ return isObject;
122
+ case "array":
123
+ return Array.isArray(parsed);
124
+ case "scalar":
125
+ return !isObject && !Array.isArray(parsed);
126
+ default:
127
+ return true;
128
+ }
144
129
  }
145
- /** A SQL value as its JSON counterpart: datetimes serialize as ISO text, like every cast. */
146
130
  function jsonValueOf(value) {
147
- const external = externalSqlDomainValue(value);
148
- return external instanceof Date ? dateIsoString(external) : external;
131
+ const external = externalSqlDomainValue(value);
132
+ return external instanceof Date ? dateIsoString(external) : external;
149
133
  }
150
- /**
151
- * JSON_ARRAY(v, ...) and JSON_OBJECT(k, v, ...) (T811/T812). The omitted null-handling clause is
152
- * `NULL ON NULL`: SQL NULL becomes a JSON null. `ABSENT ON NULL` is a separate spelling rather
153
- * than the default. Constructors return JSON text at the JavaScript boundary.
154
- */
155
- export function jsonConstructor(name, values) {
156
- if (name === "JSON_ARRAY") {
157
- const members = values.map((value) => boundedJsonValue(value ?? null, "JSON_ARRAY value"));
158
- return joinBoundedJson("[", members, "]", "JSON_ARRAY result");
159
- }
160
- const members = [];
161
- for (let index = 0; index + 1 < values.length; index += 2) {
162
- const rawKey = externalSqlDomainValue(values[index]);
163
- if (rawKey === null || rawKey === undefined) {
164
- throw new TypeError("JSON_OBJECT keys cannot be NULL");
165
- }
166
- let key;
167
- if (rawKey instanceof Date)
168
- key = dateIsoString(rawKey);
169
- else if (typeof rawKey === "string")
170
- key = rawKey;
171
- else if (typeof rawKey === "number" || typeof rawKey === "boolean")
172
- key = String(rawKey);
173
- else
174
- throw new TypeError("JSON_OBJECT keys must be scalar values");
175
- const member = values[index + 1];
176
- // Build JSON text directly. WITHOUT UNIQUE KEYS is the default, so duplicate names must be
177
- // preserved; assigning through a JavaScript object would collapse them and mishandle
178
- // special names such as "__proto__".
179
- // Keys are always JSON strings. In particular, a JSON-domain expression used as a key is
180
- // its document text, not a raw object member token as JSON-domain values are below.
181
- const encodedKey = boundedJsonString(key, "JSON_OBJECT key");
182
- const encodedValue = boundedJsonValue(member ?? null, "JSON_OBJECT value");
183
- members.push(`${encodedKey}:${encodedValue}`);
184
- }
185
- return joinBoundedJson("{", members, "}", "JSON_OBJECT result");
134
+ function jsonConstructor(name, values) {
135
+ if (name === "JSON_ARRAY") {
136
+ const members2 = values.map((value) => boundedJsonValue(value ?? null, "JSON_ARRAY value"));
137
+ return joinBoundedJson("[", members2, "]", "JSON_ARRAY result");
138
+ }
139
+ const members = [];
140
+ for (let index = 0; index + 1 < values.length; index += 2) {
141
+ const rawKey = externalSqlDomainValue(values[index]);
142
+ if (rawKey === null || rawKey === void 0) {
143
+ throw new TypeError("JSON_OBJECT keys cannot be NULL");
144
+ }
145
+ let key;
146
+ if (rawKey instanceof Date)
147
+ key = dateIsoString(rawKey);
148
+ else if (typeof rawKey === "string")
149
+ key = rawKey;
150
+ else if (typeof rawKey === "number" || typeof rawKey === "boolean")
151
+ key = String(rawKey);
152
+ else
153
+ throw new TypeError("JSON_OBJECT keys must be scalar values");
154
+ const member = values[index + 1];
155
+ const encodedKey = boundedJsonString(key, "JSON_OBJECT key");
156
+ const encodedValue = boundedJsonValue(member ?? null, "JSON_OBJECT value");
157
+ members.push(`${encodedKey}:${encodedValue}`);
158
+ }
159
+ return joinBoundedJson("{", members, "}", "JSON_OBJECT result");
186
160
  }
187
161
  function boundedJsonString(value, label) {
188
- if (value.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
189
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
190
- }
191
- const encoded = JSON.stringify(value);
192
- if (encoded.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
193
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
194
- }
195
- return encoded;
162
+ if (value.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
163
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
164
+ }
165
+ const encoded = JSON.stringify(value);
166
+ if (encoded.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
167
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
168
+ }
169
+ return encoded;
196
170
  }
197
171
  function boundedJsonDocument(value, caller) {
198
- const document = stringArgument(caller, externalSqlDomainValue(value));
199
- if (document.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
200
- throw new RangeError(`${caller} document exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
201
- }
202
- return document;
172
+ const document = stringArgument(caller, externalSqlDomainValue(value));
173
+ if (document.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
174
+ throw new RangeError(`${caller} document exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
175
+ }
176
+ return document;
203
177
  }
204
178
  function boundedJsonValue(value, label) {
205
- const domainDocument = jsonDomainDocument(value);
206
- if (domainDocument !== undefined) {
207
- if (domainDocument.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
208
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
209
- }
210
- return domainDocument;
211
- }
212
- const normalized = jsonValueOf(value);
213
- if (typeof normalized === "string" && normalized.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
214
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
215
- }
216
- const encoded = JSON.stringify(normalized);
217
- if (typeof encoded !== "string")
218
- throw new TypeError(`${label} is not JSON serializable`);
219
- if (encoded.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
220
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
221
- }
222
- return encoded;
179
+ const domainDocument = jsonDomainDocument(value);
180
+ if (domainDocument !== void 0) {
181
+ if (domainDocument.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
182
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
183
+ }
184
+ return domainDocument;
185
+ }
186
+ const normalized = jsonValueOf(value);
187
+ if (typeof normalized === "string" && normalized.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
188
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
189
+ }
190
+ const encoded = JSON.stringify(normalized);
191
+ if (typeof encoded !== "string")
192
+ throw new TypeError(`${label} is not JSON serializable`);
193
+ if (encoded.length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
194
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
195
+ }
196
+ return encoded;
223
197
  }
224
198
  function joinBoundedJson(prefix, members, suffix, label) {
225
- let length = prefix.length + suffix.length;
226
- for (const member of members) {
227
- length += member.length;
228
- if (!Number.isSafeInteger(length) || length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
229
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
230
- }
231
- }
232
- if (members.length > 1)
233
- length += members.length - 1;
199
+ let length = prefix.length + suffix.length;
200
+ for (const member of members) {
201
+ length += member.length;
234
202
  if (!Number.isSafeInteger(length) || length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
235
- throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
236
- }
237
- return `${prefix}${members.join(",")}${suffix}`;
203
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
204
+ }
205
+ }
206
+ if (members.length > 1)
207
+ length += members.length - 1;
208
+ if (!Number.isSafeInteger(length) || length > MAX_SQL_SCALAR_RESULT_CHARACTERS) {
209
+ throw new RangeError(`${label} exceeds ${String(MAX_SQL_SCALAR_RESULT_CHARACTERS)} characters`);
210
+ }
211
+ return `${prefix}${members.join(",")}${suffix}`;
238
212
  }
239
213
  import { dateIsoString } from "../date-value.js";
214
+ export {
215
+ jsonArrowStep,
216
+ jsonAtPath,
217
+ jsonConstructor,
218
+ jsonIsValid,
219
+ parseJsonPath
220
+ };
@@ -1,9 +1,23 @@
1
1
  /**
2
- * SQL value semantics shared by the row and vector executors.
3
- *
4
- * Keep comparison, equality-key, scalar, and pattern behavior here so an execution-path
5
- * optimization cannot silently change query results.
2
+ * The standard's datetime text `2026-01-02`, `2026-01-02 03:04:05`, `2026-01-02T03:04:05.250Z`,
3
+ * an optional zone offset — read as an instant. A zoneless spelling is UTC, the reading every
4
+ * datetime in a Minnow database has; `undefined` for text in any other shape.
6
5
  */
6
+ export declare function parseSqlTimestampText(text: string): Date | undefined;
7
+ /**
8
+ * PostgreSQL reads an untyped string constant beside a typed value in that value's type:
9
+ * `joined >= '2026-01-01'`, `id = '5'`, `active = 't'`. Catalog-backed plans coerce such literals
10
+ * before execution; this runtime reading covers the schema-less row executor and anything the
11
+ * plan rewrite could not see. Text that does not parse in the other side's type keeps the
12
+ * comparable-types error below, so a genuine mismatch still fails.
13
+ */
14
+ export declare function coercedComparable(text: string, other: unknown): unknown;
15
+ /**
16
+ * Applies the untyped-literal reading to a comparison's two operands: a plain string beside a
17
+ * typed value (datetime, DATE, number, boolean) is read in that value's type when it parses.
18
+ * Both executors call this before their own comparisons, so the reading is one decision.
19
+ */
20
+ export declare function coerceComparisonOperands(left: unknown, right: unknown): [unknown, unknown];
7
21
  /**
8
22
  * Deterministic SQL ordering. Strings use Unicode codepoint order rather than host locale data,
9
23
  * and signed zero compares equal because SQL numeric equality does not distinguish it.
@@ -24,6 +38,13 @@ interface SqlPatternMatcher {
24
38
  }
25
39
  /** Compiles SQL LIKE without exposing input to the host regular-expression engine. */
26
40
  export declare function compileLikePattern(pattern: string, caseInsensitive?: boolean, escape?: string): SqlPatternMatcher;
41
+ /**
42
+ * PostgreSQL's ~ / ~* / !~ / !~* operators and REGEXP_REPLACE, compiled as JavaScript regular
43
+ * expressions. Advanced regular expressions and JavaScript agree on the everyday syntax; the
44
+ * `n` flag makes `.` and anchors newline-sensitive, `i` is case-insensitive, and `g` replaces
45
+ * every match. Patterns are bounded like every other SQL pattern.
46
+ */
47
+ export declare function compileRegexPattern(pattern: string, flags?: string): RegExp;
27
48
  /** PostgreSQL SIMILAR TO compiled to a Thompson NFA with bounded deterministic work. */
28
49
  export declare function compileSimilarPattern(pattern: string, escape?: string): SqlPatternMatcher;
29
50
  /** Defines an own enumerable result-column property, including the special name `__proto__`. */