qubu 0.6.0 → 0.6.2

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 (95) hide show
  1. package/README.md +112 -0
  2. package/dist/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
  3. package/dist/codegen.d.mts +2 -2
  4. package/dist/codegen.mjs +180 -90
  5. package/dist/column-Cyc2CMnG.mjs +116 -0
  6. package/dist/column-DDRvD7SF.mjs +721 -0
  7. package/dist/{constraints-YGyNPQ_z.mjs → constraints-CAmi18Uk.mjs} +8 -3
  8. package/dist/core.d.mts +3 -3
  9. package/dist/core.mjs +4 -5
  10. package/dist/diagnostics-I9vVtXkc.mjs +40 -0
  11. package/dist/diff.d.mts +9 -9
  12. package/dist/diff.mjs +152 -102
  13. package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
  14. package/dist/expressions-_6JF_J77.mjs +130 -0
  15. package/dist/index-CaxrMD1A.d.mts +1 -0
  16. package/dist/index.d.mts +2 -2
  17. package/dist/index.mjs +414 -77
  18. package/dist/introspection/mysql.d.mts +26 -0
  19. package/dist/introspection/mysql.mjs +1278 -0
  20. package/dist/introspection/postgres.d.mts +43 -0
  21. package/dist/introspection/postgres.mjs +1889 -0
  22. package/dist/introspection/sqlite.d.mts +15 -0
  23. package/dist/introspection/sqlite.mjs +1172 -0
  24. package/dist/introspection.d.mts +26 -87
  25. package/dist/introspection.mjs +3 -4351
  26. package/dist/mysql.d.mts +3 -3
  27. package/dist/mysql.mjs +8 -7
  28. package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
  29. package/dist/{on-conflict-DZQ85f1t.mjs → on-conflict-B2rFyHGF.mjs} +78 -8
  30. package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
  31. package/dist/postgres-hFhd0I9n.mjs +68 -0
  32. package/dist/postgres.d.mts +3 -3
  33. package/dist/postgres.mjs +3 -52
  34. package/dist/registry-BXE_4M9P.mjs +127 -0
  35. package/dist/{relational-CxnLCqZQ.mjs → relational-CoPBETjI.mjs} +3 -3
  36. package/dist/schema.d.mts +2 -2
  37. package/dist/schema.mjs +8 -7
  38. package/dist/{serialize-BN07IK0v.mjs → serialize-CyobNEx-.mjs} +174 -30
  39. package/dist/serialize-Du2UPZMt.d.mts +92 -0
  40. package/dist/snapshot/mysql.d.mts +5 -5
  41. package/dist/snapshot/mysql.mjs +32 -32
  42. package/dist/snapshot/postgres.d.mts +5 -5
  43. package/dist/snapshot/postgres.mjs +25 -25
  44. package/dist/snapshot/sqlite.d.mts +5 -5
  45. package/dist/snapshot/sqlite.mjs +30 -30
  46. package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
  47. package/dist/snapshot.d.mts +4 -5
  48. package/dist/snapshot.mjs +3 -4
  49. package/dist/{source-SqrKWjFJ.mjs → source-DYSUqzvb.mjs} +2 -2
  50. package/dist/sqlite.d.mts +2 -2
  51. package/dist/sqlite.mjs +10 -10
  52. package/dist/{table-BwflqeAj.mjs → table-B8zEq0az.mjs} +4 -4
  53. package/dist/{types-BIJsj2fJ.mjs → types-CYHpSPwj.mjs} +10 -7
  54. package/dist/{types-CTCqtFlS.d.mts → types-CiMvKi5V.d.mts} +14 -4
  55. package/dist/{types-C0VkiwpR.d.mts → types-Dqr4o2I1.d.mts} +640 -189
  56. package/dist/value-CpaUFtjw.mjs +45 -0
  57. package/dist/vite/ambient.d.ts +2 -0
  58. package/dist/vite.d.mts +1 -1
  59. package/dist/vite.mjs +2 -0
  60. package/docs/dialects-and-execution.md +61 -11
  61. package/docs/getting-started.md +1 -1
  62. package/docs/guides/compose-queries.md +22 -0
  63. package/docs/guides/drizzle.md +11 -11
  64. package/docs/guides/extensions/typed-expressions.md +5 -3
  65. package/docs/guides/json.md +95 -2
  66. package/docs/guides/mutations.md +125 -0
  67. package/docs/guides/valtio-sync.md +113 -0
  68. package/docs/index.md +1 -1
  69. package/docs/migrations/adapters.md +58 -21
  70. package/docs/migrations/index.md +50 -12
  71. package/docs/migrations/operations.md +20 -6
  72. package/docs/migrations/recovery.md +7 -1
  73. package/docs/query-model/fragments.md +21 -1
  74. package/docs/reference/introspection-support.md +16 -18
  75. package/docs/reference/supported-surface.md +23 -11
  76. package/docs/schema/catalog-model.md +20 -7
  77. package/docs/schema/code-generation.md +4 -3
  78. package/docs/schema/diff.md +2 -2
  79. package/docs/schema/introspection.md +24 -16
  80. package/docs/schema/snapshots.md +18 -8
  81. package/docs/schema/storage-and-schema-sql.md +7 -2
  82. package/docs/sql-semantic-types.md +8 -0
  83. package/package.json +14 -1
  84. package/dist/canonical-DMvR9yBe.mjs +0 -972
  85. package/dist/column-Da37jYSD.mjs +0 -309
  86. package/dist/column-r1Y4ivwt.mjs +0 -327
  87. package/dist/complete-types-CY0KbzNw.d.mts +0 -371
  88. package/dist/index-B2rZf3-2.d.mts +0 -32
  89. package/dist/json-Db7XRD91.mjs +0 -169
  90. package/dist/omit-OxV58AwX.mjs +0 -5
  91. package/dist/registry-BRcUuazJ.mjs +0 -256
  92. package/dist/serialize-CEIIlWhC.d.mts +0 -66
  93. package/dist/snapshot-Xam8-q0j.mjs +0 -392
  94. package/dist/standard-DfcZEVOj.mjs +0 -12
  95. package/dist/value-D14I_XgL.mjs +0 -29
package/dist/index.mjs CHANGED
@@ -1,58 +1,47 @@
1
- import { a as assertDialectCapability } from "./json-Db7XRD91.mjs";
2
- import { c as render, n as call, o as cast, r as schemaCall, t as createClause } from "./types-BIJsj2fJ.mjs";
3
- import { n as queryValidationError, t as QueryValidationError } from "./errors-Dxv73YJu.mjs";
4
- import { A as dateResultDecoder, C as fragment, D as ResultDecodingError, F as resultValueOf, I as timestampResultDecoder, M as jsonTextResultDecoder, N as resultShapeValue, O as booleanResultDecoder, P as resultValue, T as parenthesize, _ as isSchemaExpression, b as markExpressionCategory, g as isExpression, h as snakeCaseIdentifier, i as identifier, j as decodeResultRow, k as createResultShape, m as resolveSqlNames, t as createColumnReference, v as makeExpression, w as isFragment, x as markSchemaExpression, y as makeSchemaExpression } from "./column-r1Y4ivwt.mjs";
5
- import { C as identityColumn, S as generatedColumn, _ as uuid, b as externalDefault, c as integer, d as nativeStorage, f as nullable, g as timestamp, h as text, i as column, l as json, m as portableStorage, n as binary, o as date, p as numeric, r as boolean, s as encodeColumnParameter, t as bigint, u as nativeColumn, x as externalGeneratedColumn } from "./column-Da37jYSD.mjs";
6
- import { i as value, t as asValue } from "./value-D14I_XgL.mjs";
7
- import { a as isDistinctFrom, c as lt, d as notLike, f as expressionOperand, i as gte, l as lte, m as renderOperands, n as eq, o as isNotDistinctFrom, p as isNullOperand, r as gt, s as like, u as ne } from "./relational-CxnLCqZQ.mjs";
8
- import { t as omit } from "./omit-OxV58AwX.mjs";
9
- import { r as exposeColumns, t as createSource } from "./source-SqrKWjFJ.mjs";
10
- import { n as alias, r as lateral, t as table } from "./table-BwflqeAj.mjs";
11
- import { a as primaryKey, c as uniqueConstraint, i as foreignKey, n as catalogForeignKey, o as references, r as check, s as unique, t as catalogCheck, u as index } from "./constraints-YGyNPQ_z.mjs";
12
- import { i as schema, p as unsafeSchemaSql } from "./registry-BRcUuazJ.mjs";
1
+ import { A as fragment, B as decodeResultRow, C as isExpression, D as markExpressionCategory, E as makeSchemaExpression, F as attachResultValue, G as timestampResultDecoder, H as resultShapeValue, I as bigintResultDecoder, L as booleanResultDecoder, M as parenthesize, O as markSchemaExpression, P as ResultDecodingError, R as createResultShape, S as snakeCaseIdentifier, T as makeExpression, U as resultValue, V as jsonTextResultDecoder, W as resultValueOf, X as assertDialectCapability, c as externalDefault, d as identityColumn, i as identifier, j as isFragment, l as externalGeneratedColumn, t as createColumnReference, u as generatedColumn, w as isSchemaExpression, x as resolveSqlNames, z as dateResultDecoder } from "./column-DDRvD7SF.mjs";
2
+ import { i as value, t as asValue } from "./value-CpaUFtjw.mjs";
3
+ import { c as render, n as call, o as cast, r as schemaCall, t as createClause } from "./types-CYHpSPwj.mjs";
4
+ import { n as QueryValidationError, r as queryValidationError, t as omit } from "./omit-VEr9Ydux.mjs";
5
+ import { _ as timestamp, c as encodeColumnParameter, d as nativeColumn, f as nativeStorage, g as text, h as portableStorage, i as column, l as integer, m as numeric, n as binary, o as columnSqlType, p as nullable, r as boolean, s as date, t as bigint, u as json, v as uuid } from "./column-Cyc2CMnG.mjs";
6
+ import { a as isDistinctFrom, c as lt, d as notLike, f as expressionOperand, i as gte, l as lte, m as renderOperands, n as eq, o as isNotDistinctFrom, p as isNullOperand, r as gt, s as like, u as ne } from "./relational-CoPBETjI.mjs";
7
+ import { r as exposeColumns, t as createSource } from "./source-DYSUqzvb.mjs";
8
+ import { n as alias, r as lateral, t as table } from "./table-B8zEq0az.mjs";
9
+ import { a as primaryKey, c as uniqueConstraint, i as foreignKey, n as catalogForeignKey, o as references, r as check, s as unique, t as catalogCheck, u as index } from "./constraints-CAmi18Uk.mjs";
10
+ import { c as unsafeSchemaSql } from "./expressions-_6JF_J77.mjs";
11
+ import { i as schema } from "./registry-BXE_4M9P.mjs";
12
+ import { i as renderDuplicateKeyUpdate, n as incomingAlias } from "./on-duplicate-key-update-Czsw1Yq-.mjs";
13
13
  //#region src/execution.ts
14
14
  function qubu(adapter, options = {}) {
15
- const observation = createObservation(options.hooks);
16
- const client = createClient(adapter, observation);
17
- if (!isTransactionalQueryAdapter(adapter)) return client;
18
- return Object.freeze({
19
- ...client,
20
- async transaction(callback, transactionOptions) {
21
- const active = startTransactionOperation(observation, transactionOptions?.hookMetadata);
22
- try {
23
- const result = await adapter.transaction(async (transactionAdapter) => callback(createClient(transactionAdapter, observation, active?.operation.id)), adapterTransactionOptions(transactionOptions));
24
- active?.finish({ status: "success" });
25
- return result;
26
- } catch (error) {
27
- active?.finish({
28
- status: "error",
29
- error
30
- });
31
- throw error;
32
- }
33
- }
34
- });
15
+ return createClient(adapter, createObservation(options.hooks));
35
16
  }
36
17
  function createClient(adapter, observation, parentId) {
37
- const client = {
18
+ return Object.freeze({
38
19
  adapter,
39
20
  execute(query, options) {
40
21
  return executeInternal(query, adapter, options ?? {}, observation, parentId);
41
22
  },
42
23
  rows(query, options) {
43
24
  return executeRowsInternal(query, adapter, options ?? {}, observation, parentId);
44
- }
45
- };
46
- const streaming = isStreamingQueryAdapter(adapter);
47
- const explainable = isExplainableQueryAdapter(adapter);
48
- if (!streaming && !explainable) return Object.freeze(client);
49
- return Object.freeze({
50
- ...client,
51
- ...streaming ? { stream(query, options) {
25
+ },
26
+ ...isStreamingQueryAdapter(adapter) ? { stream(query, options) {
52
27
  return streamInternal(query, adapter, options ?? {}, observation, parentId);
53
28
  } } : {},
54
- ...explainable ? { explain(query, options) {
29
+ ...isExplainableQueryAdapter(adapter) ? { explain(query, options) {
55
30
  return explainInternal(query, adapter, options ?? {}, observation, parentId);
31
+ } } : {},
32
+ ...isTransactionalQueryAdapter(adapter) ? { async transaction(callback, options) {
33
+ const active = startTransactionOperation(observation, options?.hookMetadata, parentId);
34
+ try {
35
+ const result = await adapter.transaction(async (scoped) => callback(createClient(scoped, observation, active?.operation.id)), adapterTransactionOptions(options));
36
+ active?.finish({ status: "success" });
37
+ return result;
38
+ } catch (error) {
39
+ active?.finish({
40
+ status: "error",
41
+ error
42
+ });
43
+ throw error;
44
+ }
56
45
  } } : {}
57
46
  });
58
47
  }
@@ -83,11 +72,11 @@ function startQueryOperation(observation, kind, request, dialect, metadata, pare
83
72
  parentId
84
73
  });
85
74
  }
86
- function startTransactionOperation(observation, metadata) {
75
+ function startTransactionOperation(observation, metadata, parentId) {
87
76
  return startOperation(observation, {
88
77
  kind: "transaction",
89
78
  metadata,
90
- parentId: void 0
79
+ parentId
91
80
  });
92
81
  }
93
82
  function startOperation(observation, input) {
@@ -278,7 +267,8 @@ function createExplainRequest(query, adapter, options) {
278
267
  });
279
268
  const statement = Object.freeze({
280
269
  text: dialect.explain.render(request.statement.text, query.queryKind, explainRenderOptions(options)),
281
- parameters: request.statement.parameters
270
+ parameters: request.statement.parameters,
271
+ ...request.statement.parameterSqlTypes === void 0 ? {} : { parameterSqlTypes: request.statement.parameterSqlTypes }
282
272
  });
283
273
  return Object.freeze({
284
274
  ...request,
@@ -307,7 +297,8 @@ function isQuery(value) {
307
297
  //#region src/expressions/map-result.ts
308
298
  /** Attach an application decoder to an expression without changing its SQL. */
309
299
  function mapResult(expression, decoder) {
310
- const mapped = makeExpression(expression.expressionKind, (context) => context.render(expression), expression.expressionCategory, resultValue(resultValueOf(expression)?.type, decoder));
300
+ const metadata = resultValueOf(expression);
301
+ const mapped = makeExpression(expression.expressionKind, (context) => context.render(expression), expression.expressionCategory, resultValue(metadata?.type, decoder, metadata?.sqlType));
311
302
  return isSchemaExpression(expression) ? markSchemaExpression(mapped) : mapped;
312
303
  }
313
304
  //#endregion
@@ -315,6 +306,7 @@ function mapResult(expression, decoder) {
315
306
  function caseWhen(condition, thenValue, elseValue) {
316
307
  const thenExpression = asValue(thenValue);
317
308
  const elseExpression = asValue(elseValue);
309
+ const domain = resultValueOf(thenExpression)?.sqlType ?? resultValueOf(elseExpression)?.sqlType;
318
310
  return makeSchemaExpression("operator", (context) => {
319
311
  context.append("CASE WHEN ");
320
312
  context.render(condition);
@@ -323,7 +315,7 @@ function caseWhen(condition, thenValue, elseValue) {
323
315
  context.append(" ELSE ");
324
316
  context.render(elseExpression);
325
317
  context.append(" END");
326
- });
318
+ }, resultValue(void 0, void 0, domain === "integer" ? "decimal" : domain));
327
319
  }
328
320
  //#endregion
329
321
  //#region src/expressions/sql.ts
@@ -368,40 +360,40 @@ function count(expression) {
368
360
  if (expression) context.render(expression);
369
361
  else context.append("*");
370
362
  context.append(")");
371
- }, "aggregate");
363
+ }, "aggregate", resultValue(void 0, void 0, "integer"));
372
364
  }
373
365
  function countDistinct(expression) {
374
366
  return makeExpression("function", (context) => {
375
367
  context.append("COUNT(DISTINCT ");
376
368
  context.render(expression);
377
369
  context.append(")");
378
- }, "aggregate");
370
+ }, "aggregate", resultValue(void 0, void 0, "integer"));
379
371
  }
380
372
  function sum(expression) {
381
- return markExpressionCategory(call("SUM", expression), "aggregate");
373
+ return markExpressionCategory(attachResultValue(call("SUM", expression), resultValueOf(expression)), "aggregate");
382
374
  }
383
375
  function avg(expression) {
384
- return markExpressionCategory(call("AVG", expression), "aggregate");
376
+ return markExpressionCategory(attachResultValue(call("AVG", expression), resultValue(void 0, void 0, "decimal")), "aggregate");
385
377
  }
386
378
  function min(expression) {
387
- return markExpressionCategory(call("MIN", expression), "aggregate");
379
+ return markExpressionCategory(attachResultValue(call("MIN", expression), resultValueOf(expression)), "aggregate");
388
380
  }
389
381
  function max(expression) {
390
- return markExpressionCategory(call("MAX", expression), "aggregate");
382
+ return markExpressionCategory(attachResultValue(call("MAX", expression), resultValueOf(expression)), "aggregate");
391
383
  }
392
384
  //#endregion
393
385
  //#region src/expressions/functions/string.ts
394
- function lower(expression) {
395
- return schemaCall("LOWER", expression);
386
+ function lower(input) {
387
+ return attachResultValue(schemaCall("LOWER", input), resultValue(void 0, void 0, "text"));
396
388
  }
397
- function upper(expression) {
398
- return schemaCall("UPPER", expression);
389
+ function upper(input) {
390
+ return attachResultValue(schemaCall("UPPER", input), resultValue(void 0, void 0, "text"));
399
391
  }
400
- function coalesce(...expressions) {
401
- return schemaCall("COALESCE", ...expressions);
392
+ function coalesce(first, ...rest) {
393
+ return attachResultValue(schemaCall("COALESCE", first, ...rest), resultValueOf(first));
402
394
  }
403
395
  function concat(...argumentsToConcat) {
404
- return schemaCall("CONCAT", ...argumentsToConcat);
396
+ return attachResultValue(schemaCall("CONCAT", ...argumentsToConcat), resultValue(void 0, void 0, "text"));
405
397
  }
406
398
  //#endregion
407
399
  //#region src/expressions/functions/window.ts
@@ -427,16 +419,16 @@ function over(expression, window) {
427
419
  });
428
420
  }
429
421
  context.append(")");
430
- }, "window");
422
+ }, "window", resultValueOf(expression));
431
423
  }
432
424
  function rowNumber() {
433
- return markExpressionCategory(call("ROW_NUMBER"), "window");
425
+ return markExpressionCategory(attachResultValue(call("ROW_NUMBER"), resultValue(void 0, void 0, "integer")), "window");
434
426
  }
435
427
  function rank() {
436
- return markExpressionCategory(call("RANK"), "window");
428
+ return markExpressionCategory(attachResultValue(call("RANK"), resultValue(void 0, void 0, "integer")), "window");
437
429
  }
438
430
  function denseRank() {
439
- return markExpressionCategory(call("DENSE_RANK"), "window");
431
+ return markExpressionCategory(attachResultValue(call("DENSE_RANK"), resultValue(void 0, void 0, "integer")), "window");
440
432
  }
441
433
  //#endregion
442
434
  //#region src/expressions/subquery.ts
@@ -481,7 +473,7 @@ function jsonScalar(document, path, kind) {
481
473
  assertDialectCapability(context.dialect, "json");
482
474
  if (!context.dialect.json) throw new Error(`Dialect "${context.dialect.name}" advertises JSON support without a JSON renderer`);
483
475
  context.dialect.json.renderScalar(context, document, path.segments, kind);
484
- }, kind === "boolean" ? resultValue("boolean") : void 0);
476
+ }, kind === "boolean" ? resultValue("boolean") : resultValue(void 0, void 0, kind === "number" ? "decimal" : "text"));
485
477
  }
486
478
  /** Extract a JSON string, returning SQL NULL for missing, null, or non-string values. */
487
479
  function jsonText(document, path) {
@@ -513,7 +505,7 @@ function arithmetic(operator, left, right) {
513
505
  context.append(` ${operator} `);
514
506
  context.render(rightExpression);
515
507
  context.append(")");
516
- });
508
+ }, resultValue(void 0, void 0, resultValueOf(left)?.sqlType === "integer" ? "decimal" : resultValueOf(left)?.sqlType));
517
509
  }
518
510
  const add = (left, right) => arithmetic("+", left, right);
519
511
  const subtract = (left, right) => arithmetic("-", left, right);
@@ -686,11 +678,11 @@ function renderPagination(context, clauses) {
686
678
  if (index > 0) context.append(" ");
687
679
  if (part.kind === "offset") {
688
680
  context.append("OFFSET ");
689
- context.parameter(part.rows);
681
+ context.parameter(part.rows, "integer");
690
682
  context.append(" ROWS");
691
683
  } else {
692
684
  context.append(`FETCH ${part.direction} `);
693
- context.parameter(part.rows);
685
+ context.parameter(part.rows, "integer");
694
686
  context.append(" ROWS ONLY");
695
687
  }
696
688
  });
@@ -824,7 +816,9 @@ function select(selection, ...parts) {
824
816
  clause,
825
817
  index
826
818
  })).sort((left, right) => left.clause.order - right.clause.order || left.index - right.index).map(({ clause }) => clause);
827
- return createQuery("select", selectionRow(selection), selectionResultShape(selection), (context) => {
819
+ const row = selectionRow(selection);
820
+ const query = createQuery("select", row, selectionResultShape(selection), renderBody);
821
+ function renderBody(context, extraOrdering) {
828
822
  const beforeSelect = orderedClauses.filter((clause) => clause.placement === "before-select");
829
823
  const afterSelect = orderedClauses.filter((clause) => clause.placement === "after-select");
830
824
  const paginationClauses = afterSelect.filter((clause) => clause.clauseKind === "offset" || clause.clauseKind === "fetch");
@@ -841,6 +835,12 @@ function select(selection, ...parts) {
841
835
  context.append(" ");
842
836
  }
843
837
  renderSelection(selection, context);
838
+ extraOrdering?.terms.forEach((term, index) => {
839
+ if (!extraOrdering.hidden[index]) return;
840
+ context.append(", ");
841
+ context.render(term.expression);
842
+ context.append(" AS " + context.dialect.quoteIdentifier(extraOrdering.names[index]));
843
+ });
844
844
  for (const clause of afterSelect) {
845
845
  if (clause.clauseKind === "correlate") continue;
846
846
  if (clause === distinctClause) continue;
@@ -852,7 +852,56 @@ function select(selection, ...parts) {
852
852
  continue;
853
853
  }
854
854
  context.append(" ");
855
- context.render(clause);
855
+ if (clause.clauseKind === "order-by" && extraOrdering) {
856
+ context.append("ORDER BY ");
857
+ extraOrdering.terms.forEach((term, index) => {
858
+ if (index) context.append(", ");
859
+ context.append(context.dialect.quoteIdentifier(extraOrdering.names[index]));
860
+ if (term.direction) context.append(` ${term.direction}`);
861
+ if (term.nulls) context.append(` NULLS ${term.nulls}`);
862
+ });
863
+ } else context.render(clause);
864
+ }
865
+ }
866
+ return Object.freeze({
867
+ ...query,
868
+ cardinality: normalizedClauses.some((clause) => clause.clauseKind === "fetch" && clause.rows <= 1) ? "zero-or-one" : normalizedClauses.every((clause) => [
869
+ "distinct",
870
+ "order-by",
871
+ "row-lock",
872
+ "with"
873
+ ].includes(clause.clauseKind)) ? "exactly-one" : "many",
874
+ renderJsonRows(context, ordinal) {
875
+ const terms = orderedClauses.find((clause) => clause.clauseKind === "order-by")?.terms ?? [];
876
+ if (orderedClauses.some((clause) => clause.clauseKind === "distinct") && terms.some((term) => !Object.values(selection).includes(term.expression))) throw new TypeError("Nested JSON DISTINCT ordering must use selected expressions");
877
+ const occupied = new Set(Object.keys(row).map(snakeCaseIdentifier));
878
+ occupied.add(ordinal);
879
+ const hidden = [];
880
+ const names = terms.map((term, index) => {
881
+ const selected = Object.entries(selection).find(([, expression]) => expression === term.expression);
882
+ hidden.push(selected === void 0);
883
+ if (selected) return snakeCaseIdentifier(selected[0]);
884
+ let name = `__qubu_json_sort_${index}`;
885
+ while (occupied.has(name)) name += "_";
886
+ occupied.add(name);
887
+ return name;
888
+ });
889
+ const quote = context.dialect.quoteIdentifier;
890
+ context.append(`SELECT ${quote("__qubu_ordered")}.*, DENSE_RANK() OVER (`);
891
+ if (terms.length) context.append("ORDER BY ");
892
+ terms.forEach((term, index) => {
893
+ if (index) context.append(", ");
894
+ context.append(`${quote("__qubu_ordered")}.${quote(names[index])}`);
895
+ if (term.direction) context.append(` ${term.direction}`);
896
+ if (term.nulls) context.append(` NULLS ${term.nulls}`);
897
+ });
898
+ context.append(`) AS ${quote(ordinal)} FROM (`);
899
+ renderBody(context, {
900
+ terms,
901
+ names,
902
+ hidden
903
+ });
904
+ context.append(`) AS ${quote("__qubu_ordered")}`);
856
905
  }
857
906
  });
858
907
  }
@@ -864,8 +913,10 @@ function setOperation(operator, left, right) {
864
913
  row: left.row,
865
914
  resultShape: left.resultShape,
866
915
  render: (context) => {
916
+ if (context.dialect.name === "sqlite") context.append("SELECT * FROM ");
867
917
  context.render(parenthesize(left));
868
918
  context.append(` ${operator} `);
919
+ if (context.dialect.name === "sqlite") context.append("SELECT * FROM ");
869
920
  context.render(parenthesize(right));
870
921
  }
871
922
  };
@@ -1165,6 +1216,7 @@ function validateMutationClauses(kind, clauses) {
1165
1216
  let whereSeen = false;
1166
1217
  let returningSeen = false;
1167
1218
  let allowAllSeen = false;
1219
+ let updateFromSeen = false;
1168
1220
  for (const clause of clauses) if (clause.clauseKind === "where") {
1169
1221
  if (whereSeen) throw queryValidationError({
1170
1222
  code: "duplicate-clause",
@@ -1192,6 +1244,15 @@ function validateMutationClauses(kind, clauses) {
1192
1244
  hint: "Keep one allowAll() marker when the mutation is intentionally unrestricted."
1193
1245
  });
1194
1246
  allowAllSeen = true;
1247
+ } else if (clause.clauseKind === "update-from") {
1248
+ if (updateFromSeen) throw queryValidationError({
1249
+ code: "duplicate-clause",
1250
+ context: "mutation.update.clauses",
1251
+ path: ["clauses", "updateFrom"],
1252
+ message: "UPDATE accepts only one FROM clause",
1253
+ hint: "Pass every source to one updateFrom() call."
1254
+ });
1255
+ updateFromSeen = true;
1195
1256
  }
1196
1257
  if (!whereSeen && !allowAllSeen) throw queryValidationError({
1197
1258
  code: "unsafe-mutation",
@@ -1201,6 +1262,15 @@ function validateMutationClauses(kind, clauses) {
1201
1262
  hint: "Add where(...) to target rows, or add allowAll() to make the unrestricted intent explicit."
1202
1263
  });
1203
1264
  }
1265
+ function validateMutationWithClauses(kind, clauses) {
1266
+ if (clauses.filter((clause) => clause.clauseKind === "with").length > 1) throw queryValidationError({
1267
+ code: "duplicate-clause",
1268
+ context: `mutation.${kind.toLowerCase()}.clauses`,
1269
+ path: ["clauses", "with"],
1270
+ message: `${kind} accepts only one WITH clause`,
1271
+ hint: "Pass every CTE to one withCte() clause."
1272
+ });
1273
+ }
1204
1274
  //#endregion
1205
1275
  //#region src/query/mutation/insert.ts
1206
1276
  function values(...rows) {
@@ -1222,7 +1292,37 @@ function insertSelect(query, columns) {
1222
1292
  function insertInto(table, source, ...clauses) {
1223
1293
  validateInsert(table, source);
1224
1294
  const insertClauses = clauses;
1295
+ const duplicate = insertClauses.find((clause) => clause.clauseKind === "on-duplicate-key-update");
1296
+ if (duplicate) {
1297
+ if (insertClauses.some((clause) => clause.clauseKind === "returning")) throw queryValidationError({
1298
+ code: "invalid-mutation",
1299
+ context: "insert.duplicate-key",
1300
+ path: ["returning"],
1301
+ message: "MySQL duplicate-key updates do not support RETURNING",
1302
+ hint: "Read the row in a separate query."
1303
+ });
1304
+ if (duplicate.table !== table) throw queryValidationError({
1305
+ code: "invalid-mutation",
1306
+ context: "insert.duplicate-key",
1307
+ path: ["onDuplicateKeyUpdate"],
1308
+ message: "Duplicate-key updates require the same INSERT target table",
1309
+ hint: "Pass the INSERT table to onDuplicateKeyUpdate()."
1310
+ });
1311
+ if (insertClauses.filter((clause) => clause.clauseKind === "on-duplicate-key-update" || clause.clauseKind === "on-conflict").length !== 1) throw queryValidationError({
1312
+ code: "duplicate-clause",
1313
+ context: "insert.duplicate-key",
1314
+ path: ["clauses"],
1315
+ message: "INSERT accepts one conflict clause",
1316
+ hint: "Use one onDuplicateKeyUpdate() clause."
1317
+ });
1318
+ }
1319
+ validateMutationWithClauses("INSERT", insertClauses);
1320
+ const withClause = insertClauses.find((clause) => clause.clauseKind === "with");
1225
1321
  return createMutation("insert", insertClauses.find((clause) => clause.clauseKind === "returning")?.row ?? {}, insertClauses.find((clause) => clause.clauseKind === "returning")?.resultShape ?? { fields: [] }, (context) => {
1322
+ if (withClause) {
1323
+ context.render(withClause);
1324
+ context.append(" ");
1325
+ }
1226
1326
  context.append("INSERT INTO ");
1227
1327
  context.render(table.reference);
1228
1328
  if (source.insertKind === "values") {
@@ -1230,7 +1330,7 @@ function insertInto(table, source, ...clauses) {
1230
1330
  const explicitColumns = Object.keys(rows[0] ?? {});
1231
1331
  const runtimeDefaultColumns = Object.entries(table.definitions).filter(([columnName, definition]) => !explicitColumns.includes(columnName) && definition.defaultFn !== void 0).map(([columnName]) => columnName);
1232
1332
  const columns = [...explicitColumns, ...runtimeDefaultColumns];
1233
- if (columns.length === 0) context.append(" DEFAULT VALUES");
1333
+ if (columns.length === 0) context.append(context.dialect.name === "mysql" ? ` () VALUES ${rows.map(() => "()").join(", ")}` : " DEFAULT VALUES");
1234
1334
  else {
1235
1335
  renderTargetColumns(context, table, columns);
1236
1336
  context.append(" VALUES ");
@@ -1247,7 +1347,7 @@ function insertInto(table, source, ...clauses) {
1247
1347
  }
1248
1348
  } else if (source.insertKind === "default-values") {
1249
1349
  const runtimeDefaults = Object.entries(table.definitions).filter(([, definition]) => definition.defaultFn !== void 0);
1250
- if (runtimeDefaults.length === 0) context.append(" DEFAULT VALUES");
1350
+ if (runtimeDefaults.length === 0) context.append(context.dialect.name === "mysql" ? " () VALUES ()" : " DEFAULT VALUES");
1251
1351
  else {
1252
1352
  renderTargetColumns(context, table, runtimeDefaults.map(([columnName]) => columnName));
1253
1353
  context.append(" VALUES (");
@@ -1260,11 +1360,41 @@ function insertInto(table, source, ...clauses) {
1260
1360
  } else {
1261
1361
  renderTargetColumns(context, table, source.columns);
1262
1362
  context.append(" ");
1263
- context.renderRelation(source.query);
1363
+ if (duplicate) {
1364
+ const fields = Object.keys(source.query.row);
1365
+ if (fields.length !== source.columns.length) throw queryValidationError({
1366
+ code: "invalid-insert",
1367
+ context: "insert.select.columns",
1368
+ path: ["insertSelect", "columns"],
1369
+ message: "INSERT SELECT target and projection lengths must match",
1370
+ hint: "Map every projected field to one insert column."
1371
+ });
1372
+ context.append("SELECT * FROM (SELECT ");
1373
+ fields.forEach((field, index) => {
1374
+ if (index) context.append(", ");
1375
+ context.render(identifier("__qubu_insert_source"));
1376
+ context.append(".");
1377
+ context.render(identifier(snakeCaseIdentifier(field)));
1378
+ context.append(" AS ");
1379
+ context.render(identifier(table.sqlNames[source.columns[index]] ?? source.columns[index]));
1380
+ });
1381
+ context.append(" FROM (");
1382
+ context.renderRelation(source.query);
1383
+ context.append(") AS ");
1384
+ context.render(identifier("__qubu_insert_source"));
1385
+ context.append(") AS ");
1386
+ context.render(identifier(incomingAlias(table)));
1387
+ } else context.renderRelation(source.query);
1388
+ }
1389
+ if (duplicate && source.insertKind !== "select") {
1390
+ context.append(" AS ");
1391
+ context.render(identifier(incomingAlias(table)));
1264
1392
  }
1265
1393
  for (const clause of insertClauses) {
1394
+ if (clause.clauseKind === "with") continue;
1266
1395
  context.append(" ");
1267
- context.render(clause);
1396
+ if (clause.clauseKind === "on-duplicate-key-update") renderDuplicateKeyUpdate(context, clause, source.insertKind === "select" ? source.columns : void 0);
1397
+ else context.render(clause);
1268
1398
  }
1269
1399
  });
1270
1400
  }
@@ -1278,7 +1408,7 @@ function renderTargetColumns(context, table, columns) {
1278
1408
  }
1279
1409
  function renderInsertValue(context, input, definition) {
1280
1410
  if (isExpression(input)) context.render(input);
1281
- else context.parameter(encodeColumnParameter(definition, input));
1411
+ else context.parameter(encodeColumnParameter(definition, input), columnSqlType(definition));
1282
1412
  }
1283
1413
  function validateInsert(table, source) {
1284
1414
  const definitions = table.definitions;
@@ -1395,10 +1525,17 @@ function validateInsert(table, source) {
1395
1525
  function update(table, assignments, ...clauses) {
1396
1526
  const normalizedClauses = clauses;
1397
1527
  validateMutationClauses("UPDATE", normalizedClauses);
1528
+ validateMutationWithClauses("UPDATE", normalizedClauses);
1398
1529
  const entries = validateUpdate(table, assignments);
1399
1530
  const whereClause = normalizedClauses.find((clause) => clause.clauseKind === "where");
1531
+ const withClause = normalizedClauses.find((clause) => clause.clauseKind === "with");
1532
+ const fromClause = normalizedClauses.find((clause) => clause.clauseKind === "update-from");
1400
1533
  const returningClause = normalizedClauses.find((clause) => clause.clauseKind === "returning");
1401
1534
  return createMutation("update", returningClause?.row ?? {}, returningClause?.resultShape ?? { fields: [] }, (context) => {
1535
+ if (withClause) {
1536
+ context.render(withClause);
1537
+ context.append(" ");
1538
+ }
1402
1539
  context.append("UPDATE ");
1403
1540
  context.render(table.reference);
1404
1541
  context.append(" SET ");
@@ -1408,6 +1545,10 @@ function update(table, assignments, ...clauses) {
1408
1545
  context.append(" = ");
1409
1546
  renderAssignmentValue(context, value, table.definitions[columnName]);
1410
1547
  });
1548
+ if (fromClause) {
1549
+ context.append(" ");
1550
+ context.render(fromClause);
1551
+ }
1411
1552
  if (whereClause) {
1412
1553
  context.append(" ");
1413
1554
  context.render(whereClause);
@@ -1420,7 +1561,7 @@ function update(table, assignments, ...clauses) {
1420
1561
  }
1421
1562
  function renderAssignmentValue(context, value, definition) {
1422
1563
  if (isExpression(value)) context.render(value);
1423
- else context.parameter(encodeColumnParameter(definition, value));
1564
+ else context.parameter(encodeColumnParameter(definition, value), columnSqlType(definition));
1424
1565
  }
1425
1566
  function validateUpdate(table, assignments) {
1426
1567
  const definitions = table.definitions;
@@ -1456,9 +1597,15 @@ function validateUpdate(table, assignments) {
1456
1597
  function deleteFrom(table, ...clauses) {
1457
1598
  const normalizedClauses = clauses;
1458
1599
  validateMutationClauses("DELETE", normalizedClauses);
1600
+ validateMutationWithClauses("DELETE", normalizedClauses);
1459
1601
  const whereClause = normalizedClauses.find((clause) => clause.clauseKind === "where");
1602
+ const withClause = normalizedClauses.find((clause) => clause.clauseKind === "with");
1460
1603
  const returningClause = normalizedClauses.find((clause) => clause.clauseKind === "returning");
1461
1604
  return createMutation("delete", returningClause?.row ?? {}, returningClause?.resultShape ?? { fields: [] }, (context) => {
1605
+ if (withClause) {
1606
+ context.render(withClause);
1607
+ context.append(" ");
1608
+ }
1462
1609
  context.append("DELETE FROM ");
1463
1610
  context.render(table.reference);
1464
1611
  if (whereClause) {
@@ -1486,4 +1633,194 @@ function returning(selection) {
1486
1633
  });
1487
1634
  }
1488
1635
  //#endregion
1489
- export { QueryValidationError, ResultDecodingError, add, alias, all, allowAll, and, asValue, asc, avg, between, bigint, binary, boolean, booleanResultDecoder, call, caseWhen, cast, catalogCheck, catalogForeignKey, check, coalesce, column, concat, correlate, count, countDistinct, crossJoin, cte, date, dateResultDecoder, defaultValues, deleteFrom, denseRank, desc, distinct, divide, eq, except, execute, executeRows, exists, explain, externalDefault, externalGeneratedColumn, fetchFirst, fetchNext, foreignKey, from, fullJoin, generatedColumn, groupBy, gt, gte, having, identityColumn, inList, inQuery, index, innerJoin, insertInto, insertSelect, integer, intersect, isDistinctFrom, isNotDistinctFrom, isNotNull, isNull, isTrue, json, jsonBoolean, jsonExists, jsonNumber, jsonPath, jsonText, jsonTextResultDecoder, lateral, leftJoin, like, lower, lt, lte, mapResult, max, min, modulo, multiply, nativeColumn, nativeStorage, naturalJoin, ne, not, notExists, notIn, notLike, nullable, nullsFirst, nullsLast, numeric, offset, omit, or, order, orderBy, over, portableStorage, primaryKey, qubu, rank, recursiveCte, references, render, returning, rightJoin, rowLock, rowNumber, scalar, schema, schemaCall, select, sql, stream, subtract, sum, table, text, timestamp, timestampResultDecoder, union, unionAll, unique, uniqueConstraint, unsafeSchemaSql, update, upper, uuid, value, values, where, withCte };
1636
+ //#region src/expressions/nested-json.ts
1637
+ /**
1638
+ * Turn a SELECT or set query into an inferred array expression; empty queries return [].
1639
+ *
1640
+ * Preserves correlation, explicit ordering and pagination on PostgreSQL, MySQL 8.0.21+, and SQLite
1641
+ * 3.45+. Without ORDER BY, element order is unspecified. DISTINCT ordering must use expressions
1642
+ * present in the projection.
1643
+ *
1644
+ * Nested fields require supported runtime SQL domains. Bigints, binary values and serialized JSON
1645
+ * use exact text transport; dates and booleans are normalized without adapter-specific decoders.
1646
+ * Unsupported domains or lossy numeric representations throw. Custom result decoders receive the
1647
+ * transport value (including strings for bigint, decimal, binary hex and JSON), consistent with
1648
+ * their unknown-input contract.
1649
+ */
1650
+ function jsonArrayFrom(query) {
1651
+ return nestedJson(query, true);
1652
+ }
1653
+ /**
1654
+ * Turn a query proven to return at most one row into an inferred object.
1655
+ *
1656
+ * Empty queries return null; exactly-one queries retain a non-null result type. Use an
1657
+ * unconditional fetchFirst(1) to prove the row bound for a table query. Shares dialect, projection
1658
+ * and exact-decoding rules with {@link jsonArrayFrom}.
1659
+ *
1660
+ * @throws {TypeError} When the query lacks a runtime at-most-one-row proof.
1661
+ */
1662
+ function jsonObjectFrom(query) {
1663
+ if (query.cardinality !== "exactly-one" && query.cardinality !== "zero-or-one") throw new TypeError("jsonObjectFrom() requires a query proven to return at most one row");
1664
+ return nestedJson(query, false);
1665
+ }
1666
+ function nestedJson(query, array) {
1667
+ if (query.queryKind !== "select" && query.queryKind !== "set") throw new TypeError("Nested JSON requires a SELECT or set query");
1668
+ return makeExpression("subquery", (context) => renderNestedJson(context, query, array), "subquery", resultValue("json", (value, context) => {
1669
+ const parsed = typeof value === "string" ? parseExactJson(value) : value;
1670
+ if (array) {
1671
+ if (!Array.isArray(parsed)) throw new TypeError("Expected a nested JSON array");
1672
+ return parsed.map((row) => decodeNestedRow(row, query.resultShape, context));
1673
+ }
1674
+ return parsed === null ? null : decodeNestedRow(parsed, query.resultShape, context);
1675
+ }, "json"));
1676
+ }
1677
+ function renderNestedJson(context, query, array) {
1678
+ const dialect = context.dialect.name;
1679
+ if (dialect !== "postgresql" && dialect !== "sqlite" && dialect !== "mysql") throw new TypeError(`Nested JSON queries are not supported by dialect "${dialect}"`);
1680
+ const q = context.dialect.quoteIdentifier;
1681
+ const names = new Set(query.resultShape.fields.map((field) => snakeCaseIdentifier(field.name)));
1682
+ let ordinal = "__qubu_json_order";
1683
+ while (names.has(ordinal)) ordinal += "_";
1684
+ const ordered = array && query.renderJsonRows !== void 0;
1685
+ const reference = (name) => context.append(`${q("__qubu_json")}.${q(name)}`);
1686
+ const renderObject = () => {
1687
+ context.append(dialect === "postgresql" ? "json_build_object(" : "json_object(");
1688
+ query.resultShape.fields.forEach((field, index) => {
1689
+ if (index) context.append(", ");
1690
+ context.parameter(field.name, "text");
1691
+ if (dialect === "postgresql") context.append("::text");
1692
+ context.append(", ");
1693
+ const type = field.sqlType ?? field.type;
1694
+ const ref = () => reference(snakeCaseIdentifier(field.name));
1695
+ if (type === "decimal" && dialect === "sqlite") {
1696
+ context.append("CASE typeof(");
1697
+ ref();
1698
+ context.append(") WHEN 'real' THEN printf('%!.17g', ");
1699
+ ref();
1700
+ context.append(") WHEN 'integer' THEN CAST(");
1701
+ ref();
1702
+ context.append(" AS TEXT) WHEN 'null' THEN NULL ELSE json('invalid numeric storage') END");
1703
+ } else if (type === "bigint" || type === "decimal" || type === "json") {
1704
+ context.append("CAST(");
1705
+ ref();
1706
+ context.append(dialect === "mysql" ? " AS CHAR)" : " AS TEXT)");
1707
+ } else if (type === "binary") {
1708
+ if (dialect === "sqlite") {
1709
+ context.append("CASE WHEN ");
1710
+ ref();
1711
+ context.append(" IS NULL THEN NULL ELSE ");
1712
+ }
1713
+ context.append(dialect === "postgresql" ? "encode(" : "hex(");
1714
+ ref();
1715
+ context.append(dialect === "postgresql" ? ", 'hex')" : ")");
1716
+ if (dialect === "sqlite") context.append(" END");
1717
+ } else if (type === void 0 || type === "unknown" || ![
1718
+ "text",
1719
+ "uuid",
1720
+ "integer",
1721
+ "decimal",
1722
+ "boolean",
1723
+ "date",
1724
+ "timestamp",
1725
+ "json"
1726
+ ].includes(type)) throw new TypeError(`Nested JSON field "${field.name}" requires a supported declared SQL domain`);
1727
+ else ref();
1728
+ });
1729
+ context.append(")");
1730
+ };
1731
+ context.append(array ? "COALESCE((SELECT " : "(SELECT ");
1732
+ if (array) context.append(dialect === "postgresql" ? "json_agg(" : dialect === "sqlite" ? "json_group_array(" : "JSON_ARRAYAGG(");
1733
+ renderObject();
1734
+ if (array) {
1735
+ if (ordered && dialect !== "mysql") {
1736
+ context.append(" ORDER BY ");
1737
+ reference(ordinal);
1738
+ }
1739
+ context.append(")");
1740
+ if (dialect === "mysql") {
1741
+ context.append(" OVER (");
1742
+ if (ordered) {
1743
+ context.append("ORDER BY ");
1744
+ reference(ordinal);
1745
+ context.append(" ");
1746
+ }
1747
+ context.append("ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)");
1748
+ }
1749
+ }
1750
+ context.append(" FROM (");
1751
+ context.renderRelation(fragment((inner) => {
1752
+ if (ordered) query.renderJsonRows(inner, ordinal);
1753
+ else inner.render(query);
1754
+ }));
1755
+ context.append(`) AS ${q("__qubu_json")}`);
1756
+ if (array && dialect === "mysql") context.append(" LIMIT 1");
1757
+ context.append(")");
1758
+ if (array) context.append(dialect === "postgresql" ? ", '[]'::json)" : dialect === "mysql" ? ", JSON_ARRAY())" : ", json('[]'))");
1759
+ }
1760
+ function decodeNestedRow(value, shape, context) {
1761
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw new TypeError("Expected a nested JSON object");
1762
+ const row = value;
1763
+ const entries = shape.fields.map((field) => {
1764
+ if (!Object.hasOwn(row, field.name)) throw new TypeError(`Missing nested JSON field "${field.name}"`);
1765
+ return [field.name, decodeNestedField(row[field.name], field, context)];
1766
+ });
1767
+ return Object.fromEntries(entries);
1768
+ }
1769
+ function decodeNestedField(value, field, context) {
1770
+ if (value === null) return null;
1771
+ if (field.decoder) return field.decoder(value, {
1772
+ ...context,
1773
+ field: `${context.field}.${field.name}`
1774
+ });
1775
+ switch (field.type ?? field.sqlType) {
1776
+ case "bigint": return bigintResultDecoder(value, context);
1777
+ case "boolean": return booleanResultDecoder(value, context);
1778
+ case "date": return dateResultDecoder(value, context);
1779
+ case "timestamp": return timestampResultDecoder(value, context);
1780
+ case "json": return typeof value === "string" ? parseExactJson(value) : value;
1781
+ case "binary":
1782
+ if (typeof value !== "string" || !/^(?:[\da-f]{2})*$/iu.test(value)) throw new TypeError("Expected hexadecimal binary result");
1783
+ return Uint8Array.from(value.match(/../gu) ?? [], (byte) => parseInt(byte, 16));
1784
+ case "integer":
1785
+ if (typeof value !== "number" || !Number.isSafeInteger(value)) throw new TypeError("Expected a safe integer result");
1786
+ return value;
1787
+ case "decimal":
1788
+ if (typeof value !== "string" && typeof value !== "number") throw new TypeError("Expected a numeric result");
1789
+ if (context.dialect.name === "sqlite") {
1790
+ canonicalDecimal(String(value));
1791
+ const number = Number(value);
1792
+ if (!Number.isFinite(number) || Number.isInteger(number) && !Number.isSafeInteger(number)) throw new TypeError("Expected a finite, safely represented SQLite number");
1793
+ return number;
1794
+ }
1795
+ return exactNumber(String(value));
1796
+ case "text":
1797
+ case "uuid":
1798
+ if (typeof value !== "string") throw new TypeError("Expected a text result");
1799
+ return value;
1800
+ default: throw new TypeError(`Unsupported nested JSON field "${field.name}"`);
1801
+ }
1802
+ }
1803
+ function exactNumber(value) {
1804
+ const number = Number(value);
1805
+ if (!Number.isFinite(number) || canonicalDecimal(value) !== canonicalDecimal(String(number))) throw new TypeError("Nested JSON numeric value cannot be represented exactly as a JavaScript number");
1806
+ if (Number.isInteger(number) && !Number.isSafeInteger(number)) throw new TypeError("Nested JSON integer exceeds JavaScript's safe integer range");
1807
+ return number;
1808
+ }
1809
+ function canonicalDecimal(value) {
1810
+ const match = /^([+-]?)(\d+)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/u.exec(value);
1811
+ if (!match) throw new TypeError("Expected a decimal number");
1812
+ let digits = (match[2] + (match[3] ?? "")).replace(/^0+/u, "");
1813
+ if (!digits) return "0";
1814
+ let exponent = Number(match[4] ?? 0) - (match[3]?.length ?? 0);
1815
+ if (!Number.isSafeInteger(exponent)) throw new TypeError("Unsupported decimal exponent");
1816
+ const zeros = /0+$/u.exec(digits)?.[0].length ?? 0;
1817
+ digits = digits.slice(0, digits.length - zeros);
1818
+ exponent += zeros;
1819
+ return `${match[1] === "-" ? "-" : ""}${digits}e${exponent}`;
1820
+ }
1821
+ function parseExactJson(value) {
1822
+ for (const token of value.matchAll(/"(?:[^"\\]|\\.)*"|-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/gu)) if (token[0][0] !== "\"") exactNumber(token[0]);
1823
+ return JSON.parse(value);
1824
+ }
1825
+ //#endregion
1826
+ export { QueryValidationError, ResultDecodingError, add, alias, all, allowAll, and, asValue, asc, avg, between, bigint, bigintResultDecoder, binary, boolean, booleanResultDecoder, call, caseWhen, cast, catalogCheck, catalogForeignKey, check, coalesce, column, concat, correlate, count, countDistinct, crossJoin, cte, date, dateResultDecoder, defaultValues, deleteFrom, denseRank, desc, distinct, divide, eq, except, execute, executeRows, exists, explain, externalDefault, externalGeneratedColumn, fetchFirst, fetchNext, foreignKey, from, fullJoin, generatedColumn, groupBy, gt, gte, having, identityColumn, inList, inQuery, index, innerJoin, insertInto, insertSelect, integer, intersect, isDistinctFrom, isNotDistinctFrom, isNotNull, isNull, isTrue, json, jsonArrayFrom, jsonBoolean, jsonExists, jsonNumber, jsonObjectFrom, jsonPath, jsonText, jsonTextResultDecoder, lateral, leftJoin, like, lower, lt, lte, mapResult, max, min, modulo, multiply, nativeColumn, nativeStorage, naturalJoin, ne, not, notExists, notIn, notLike, nullable, nullsFirst, nullsLast, numeric, offset, omit, or, order, orderBy, over, portableStorage, primaryKey, qubu, rank, recursiveCte, references, render, returning, rightJoin, rowLock, rowNumber, scalar, schema, schemaCall, select, sql, stream, subtract, sum, table, text, timestamp, timestampResultDecoder, union, unionAll, unique, uniqueConstraint, unsafeSchemaSql, update, upper, uuid, value, values, where, withCte };