qubu 0.6.1 → 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.
- package/dist/{complete-DP7pliuY.mjs → canonical-B5_ouh-c.mjs} +466 -241
- package/dist/codegen.d.mts +2 -2
- package/dist/codegen.mjs +180 -90
- package/dist/column-Cyc2CMnG.mjs +116 -0
- package/dist/column-DDRvD7SF.mjs +721 -0
- package/dist/{constraints-DM_tarXc.mjs → constraints-CAmi18Uk.mjs} +8 -3
- package/dist/core.d.mts +3 -3
- package/dist/core.mjs +4 -4
- package/dist/diff.d.mts +9 -9
- package/dist/diff.mjs +152 -102
- package/dist/{explain-CkIK13L_.mjs → explain-BIqEmZha.mjs} +1 -1
- package/dist/{expressions-BCjc08zw.mjs → expressions-_6JF_J77.mjs} +2 -1
- package/dist/index-CaxrMD1A.d.mts +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +368 -74
- package/dist/introspection/mysql.d.mts +1 -1
- package/dist/introspection/mysql.mjs +156 -23
- package/dist/introspection/postgres.d.mts +6 -3
- package/dist/introspection/postgres.mjs +388 -53
- package/dist/introspection/sqlite.d.mts +1 -1
- package/dist/introspection/sqlite.mjs +198 -12
- package/dist/introspection.d.mts +26 -12
- package/dist/introspection.mjs +2 -672
- package/dist/mysql.d.mts +3 -3
- package/dist/mysql.mjs +6 -5
- package/dist/{errors-Dxv73YJu.mjs → omit-VEr9Ydux.mjs} +5 -1
- package/dist/{on-conflict-CnaY5qso.mjs → on-conflict-B2rFyHGF.mjs} +6 -8
- package/dist/on-duplicate-key-update-Czsw1Yq-.mjs +95 -0
- package/dist/{postgres-Dey7QXPL.mjs → postgres-hFhd0I9n.mjs} +4 -5
- package/dist/postgres.d.mts +2 -2
- package/dist/postgres.mjs +2 -2
- package/dist/{registry-oWDiqD7i.mjs → registry-BXE_4M9P.mjs} +1 -1
- package/dist/{relational-DSAJ-l58.mjs → relational-CoPBETjI.mjs} +3 -2
- package/dist/schema.d.mts +2 -2
- package/dist/schema.mjs +8 -8
- package/dist/{serialize-CE-gw5_s.mjs → serialize-CyobNEx-.mjs} +174 -30
- package/dist/serialize-Du2UPZMt.d.mts +92 -0
- package/dist/snapshot/mysql.d.mts +5 -5
- package/dist/snapshot/mysql.mjs +8 -8
- package/dist/snapshot/postgres.d.mts +3 -3
- package/dist/snapshot/postgres.mjs +9 -9
- package/dist/snapshot/sqlite.d.mts +3 -3
- package/dist/snapshot/sqlite.mjs +7 -7
- package/dist/snapshot-mIb-Zzb5.mjs +1489 -0
- package/dist/snapshot.d.mts +4 -5
- package/dist/snapshot.mjs +3 -4
- package/dist/{source-BDuUXmAk.mjs → source-DYSUqzvb.mjs} +2 -2
- package/dist/sqlite.d.mts +2 -2
- package/dist/sqlite.mjs +6 -6
- package/dist/{table-C1QGNe4P.mjs → table-B8zEq0az.mjs} +4 -4
- package/dist/{types-BLNRatG_.mjs → types-CYHpSPwj.mjs} +10 -5
- package/dist/{types-BEn0N_al.d.mts → types-CiMvKi5V.d.mts} +14 -4
- package/dist/{types-DUe6eeI0.d.mts → types-Dqr4o2I1.d.mts} +590 -168
- package/dist/value-CpaUFtjw.mjs +45 -0
- package/dist/vite/ambient.d.ts +2 -0
- package/dist/vite.d.mts +1 -1
- package/dist/vite.mjs +2 -0
- package/docs/dialects-and-execution.md +61 -11
- package/docs/getting-started.md +1 -1
- package/docs/guides/extensions/typed-expressions.md +5 -3
- package/docs/guides/json.md +95 -2
- package/docs/guides/mutations.md +36 -0
- package/docs/index.md +1 -1
- package/docs/migrations/adapters.md +58 -21
- package/docs/migrations/recovery.md +7 -1
- package/docs/query-model/fragments.md +21 -1
- package/docs/reference/introspection-support.md +16 -18
- package/docs/reference/supported-surface.md +8 -7
- package/docs/schema/catalog-model.md +20 -7
- package/docs/schema/code-generation.md +1 -1
- package/docs/schema/diff.md +2 -2
- package/docs/schema/introspection.md +21 -14
- package/docs/schema/snapshots.md +18 -8
- package/docs/schema/storage-and-schema-sql.md +7 -2
- package/package.json +2 -1
- package/dist/canonical-DMvR9yBe.mjs +0 -972
- package/dist/column-BzN8KFJa.mjs +0 -364
- package/dist/column-CFvSbil0.mjs +0 -309
- package/dist/complete-types-CNMWBWap.d.mts +0 -371
- package/dist/index-CGui70hi.d.mts +0 -32
- package/dist/json-Db7XRD91.mjs +0 -169
- package/dist/omit-OxV58AwX.mjs +0 -5
- package/dist/serialize-OvXCLzjm.d.mts +0 -66
- package/dist/snapshot-DgsOhf_8.mjs +0 -354
package/dist/index.mjs
CHANGED
|
@@ -1,58 +1,47 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { c as render, n as call, o as cast, r as schemaCall, t as createClause } from "./types-
|
|
4
|
-
import { n as queryValidationError, t as
|
|
5
|
-
import {
|
|
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-
|
|
7
|
-
import { t as
|
|
8
|
-
import { r as
|
|
9
|
-
import { n as
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { i as
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
...
|
|
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
|
|
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
|
|
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
386
|
function lower(input) {
|
|
395
|
-
return schemaCall("LOWER", input);
|
|
387
|
+
return attachResultValue(schemaCall("LOWER", input), resultValue(void 0, void 0, "text"));
|
|
396
388
|
}
|
|
397
389
|
function upper(input) {
|
|
398
|
-
return schemaCall("UPPER", input);
|
|
390
|
+
return attachResultValue(schemaCall("UPPER", input), resultValue(void 0, void 0, "text"));
|
|
399
391
|
}
|
|
400
392
|
function coalesce(first, ...rest) {
|
|
401
|
-
return schemaCall("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
|
-
|
|
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
|
-
|
|
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
|
};
|
|
@@ -1241,6 +1292,30 @@ function insertSelect(query, columns) {
|
|
|
1241
1292
|
function insertInto(table, source, ...clauses) {
|
|
1242
1293
|
validateInsert(table, source);
|
|
1243
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
|
+
}
|
|
1244
1319
|
validateMutationWithClauses("INSERT", insertClauses);
|
|
1245
1320
|
const withClause = insertClauses.find((clause) => clause.clauseKind === "with");
|
|
1246
1321
|
return createMutation("insert", insertClauses.find((clause) => clause.clauseKind === "returning")?.row ?? {}, insertClauses.find((clause) => clause.clauseKind === "returning")?.resultShape ?? { fields: [] }, (context) => {
|
|
@@ -1255,7 +1330,7 @@ function insertInto(table, source, ...clauses) {
|
|
|
1255
1330
|
const explicitColumns = Object.keys(rows[0] ?? {});
|
|
1256
1331
|
const runtimeDefaultColumns = Object.entries(table.definitions).filter(([columnName, definition]) => !explicitColumns.includes(columnName) && definition.defaultFn !== void 0).map(([columnName]) => columnName);
|
|
1257
1332
|
const columns = [...explicitColumns, ...runtimeDefaultColumns];
|
|
1258
|
-
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");
|
|
1259
1334
|
else {
|
|
1260
1335
|
renderTargetColumns(context, table, columns);
|
|
1261
1336
|
context.append(" VALUES ");
|
|
@@ -1272,7 +1347,7 @@ function insertInto(table, source, ...clauses) {
|
|
|
1272
1347
|
}
|
|
1273
1348
|
} else if (source.insertKind === "default-values") {
|
|
1274
1349
|
const runtimeDefaults = Object.entries(table.definitions).filter(([, definition]) => definition.defaultFn !== void 0);
|
|
1275
|
-
if (runtimeDefaults.length === 0) context.append(" DEFAULT VALUES");
|
|
1350
|
+
if (runtimeDefaults.length === 0) context.append(context.dialect.name === "mysql" ? " () VALUES ()" : " DEFAULT VALUES");
|
|
1276
1351
|
else {
|
|
1277
1352
|
renderTargetColumns(context, table, runtimeDefaults.map(([columnName]) => columnName));
|
|
1278
1353
|
context.append(" VALUES (");
|
|
@@ -1285,12 +1360,41 @@ function insertInto(table, source, ...clauses) {
|
|
|
1285
1360
|
} else {
|
|
1286
1361
|
renderTargetColumns(context, table, source.columns);
|
|
1287
1362
|
context.append(" ");
|
|
1288
|
-
|
|
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)));
|
|
1289
1392
|
}
|
|
1290
1393
|
for (const clause of insertClauses) {
|
|
1291
1394
|
if (clause.clauseKind === "with") continue;
|
|
1292
1395
|
context.append(" ");
|
|
1293
|
-
|
|
1396
|
+
if (clause.clauseKind === "on-duplicate-key-update") renderDuplicateKeyUpdate(context, clause, source.insertKind === "select" ? source.columns : void 0);
|
|
1397
|
+
else context.render(clause);
|
|
1294
1398
|
}
|
|
1295
1399
|
});
|
|
1296
1400
|
}
|
|
@@ -1304,7 +1408,7 @@ function renderTargetColumns(context, table, columns) {
|
|
|
1304
1408
|
}
|
|
1305
1409
|
function renderInsertValue(context, input, definition) {
|
|
1306
1410
|
if (isExpression(input)) context.render(input);
|
|
1307
|
-
else context.parameter(encodeColumnParameter(definition, input));
|
|
1411
|
+
else context.parameter(encodeColumnParameter(definition, input), columnSqlType(definition));
|
|
1308
1412
|
}
|
|
1309
1413
|
function validateInsert(table, source) {
|
|
1310
1414
|
const definitions = table.definitions;
|
|
@@ -1457,7 +1561,7 @@ function update(table, assignments, ...clauses) {
|
|
|
1457
1561
|
}
|
|
1458
1562
|
function renderAssignmentValue(context, value, definition) {
|
|
1459
1563
|
if (isExpression(value)) context.render(value);
|
|
1460
|
-
else context.parameter(encodeColumnParameter(definition, value));
|
|
1564
|
+
else context.parameter(encodeColumnParameter(definition, value), columnSqlType(definition));
|
|
1461
1565
|
}
|
|
1462
1566
|
function validateUpdate(table, assignments) {
|
|
1463
1567
|
const definitions = table.definitions;
|
|
@@ -1529,4 +1633,194 @@ function returning(selection) {
|
|
|
1529
1633
|
});
|
|
1530
1634
|
}
|
|
1531
1635
|
//#endregion
|
|
1532
|
-
|
|
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 };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ft as IntrospectionOptions, jt as CatalogConnection, lt as IntrospectionCatalog } from "../types-CiMvKi5V.mjs";
|
|
2
2
|
//#region src/introspection/mysql.d.ts
|
|
3
3
|
declare const mysqlServerQuery = "SELECT VERSION() AS version, @@version_comment AS version_comment";
|
|
4
4
|
declare const mysqlTablesQuery = "\n SELECT TABLE_NAME AS table_name, TABLE_TYPE AS table_type,\n ENGINE AS engine, TABLE_COLLATION AS table_collation,\n CREATE_OPTIONS AS create_options, TABLE_COMMENT AS table_comment\n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_SCHEMA = ?\n ORDER BY TABLE_NAME\n";
|