@vibeorm/sql 5.5.0 → 5.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast.d.ts +30 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +46 -10
- package/dist/index.js.map +4 -4
- package/dist/query/index.js.map +1 -1
- package/package.json +2 -2
package/dist/ast.d.ts
CHANGED
|
@@ -1103,6 +1103,14 @@ export type OnConflictClause = OnConflictUpdate | OnConflictDoNothing;
|
|
|
1103
1103
|
export type UpdateStatement = {
|
|
1104
1104
|
readonly kind: "update";
|
|
1105
1105
|
readonly table: TableRef;
|
|
1106
|
+
/** The target's alias; required with {@link UpdateStatement.from}, where two relations are in scope. */
|
|
1107
|
+
readonly alias?: string;
|
|
1108
|
+
/**
|
|
1109
|
+
* A joined source: `UPDATE … FROM` on PostgreSQL/SQLite (its `on` AND-ed
|
|
1110
|
+
* before `where`), `UPDATE … JOIN … ON` on MySQL. A
|
|
1111
|
+
* {@link SourceColumnRef} set value reads its columns.
|
|
1112
|
+
*/
|
|
1113
|
+
readonly from?: UpdateSource;
|
|
1106
1114
|
/**
|
|
1107
1115
|
* Column → parameter value, or an atomic {@link SetOperation}. As a
|
|
1108
1116
|
* {@link ChainStep} only (statement-maxx lane C3), a value may be a
|
|
@@ -1227,6 +1235,23 @@ export declare function stepColumnRef(params: {
|
|
|
1227
1235
|
step: string;
|
|
1228
1236
|
column: string;
|
|
1229
1237
|
}): StepColumnRef;
|
|
1238
|
+
/** The joined relation of an {@link UpdateStatement}: its table, alias and join condition. */
|
|
1239
|
+
export type UpdateSource = {
|
|
1240
|
+
readonly table: TableRef;
|
|
1241
|
+
readonly alias: string;
|
|
1242
|
+
readonly on: SqlExpr;
|
|
1243
|
+
};
|
|
1244
|
+
/** An UPDATE set value read from the joined source's `column` (`UPDATE … FROM`). */
|
|
1245
|
+
export type SourceColumnRef = {
|
|
1246
|
+
readonly __sourceColumn: true;
|
|
1247
|
+
readonly column: string;
|
|
1248
|
+
};
|
|
1249
|
+
/** Read `column` of an {@link UpdateStatement}'s joined source as a set value. */
|
|
1250
|
+
export declare function sourceColumnRef(params: {
|
|
1251
|
+
column: string;
|
|
1252
|
+
}): SourceColumnRef;
|
|
1253
|
+
/** Is this UPDATE set value a {@link SourceColumnRef}? */
|
|
1254
|
+
export declare function isSourceColumnRef(value: unknown): value is SourceColumnRef;
|
|
1230
1255
|
/** Is this INSERT … SELECT cell a {@link StepColumnRef}? */
|
|
1231
1256
|
export declare function isStepColumnRef(value: unknown): value is StepColumnRef;
|
|
1232
1257
|
/**
|
|
@@ -1368,7 +1393,10 @@ export type ChainResult = {
|
|
|
1368
1393
|
* array_agg("__vibe_i")::text FROM (SELECT DISTINCT ARRAY["c0", "c1"] AS
|
|
1369
1394
|
* "__vibe_i" FROM "step" LIMIT $n) AS "__vibe_d")` — a two-dimensional text
|
|
1370
1395
|
* array literal of at most `limit` distinct images, NULL when the step
|
|
1371
|
-
* returned no row.
|
|
1396
|
+
* returned no row. With `inserted`, both read the update arm's rows only
|
|
1397
|
+
* (`WHERE NOT` the marker), and `_a` is left out with `insertedOnly`;
|
|
1398
|
+
* - `<alias>_ia` (with `inserted` and `after`): the insert arm's after images
|
|
1399
|
+
* (`WHERE` the marker), so an upsert's after images arrive per arm.
|
|
1372
1400
|
*
|
|
1373
1401
|
* `before` / `after` name columns the step RETURNS (its
|
|
1374
1402
|
* {@link CaptureReturningColumn} aliases), in image order. `limit` is bound once.
|
|
@@ -1378,7 +1406,7 @@ export type ChainCapture = {
|
|
|
1378
1406
|
readonly alias: string;
|
|
1379
1407
|
/** The step's `"inserted"` arm-marker column, for an `INSERT … ON CONFLICT DO UPDATE` step. */
|
|
1380
1408
|
readonly inserted?: string;
|
|
1381
|
-
/** With `inserted`: images of inserted rows only —
|
|
1409
|
+
/** With `inserted`: images of inserted rows only — `<alias>_ia`, no `<alias>_a`. */
|
|
1382
1410
|
readonly insertedOnly?: true;
|
|
1383
1411
|
readonly before?: readonly string[];
|
|
1384
1412
|
readonly after?: readonly string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -40,8 +40,8 @@ export type { ResultDecoder, ResultReadDecoder, ResultParameterEncoder, ResultSc
|
|
|
40
40
|
* lives in this package; see the root sql-catalog.md for the reviewable surface.
|
|
41
41
|
*/
|
|
42
42
|
export { compileExclusion, renderExclusionSetup, renderExclusionDdl, renderExclusionCatalog, renderExclusionProbe } from "./exclusion.ts";
|
|
43
|
-
export type { AdvisoryLockKey, AdvisoryLockStatement, AdvisoryLocksStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainCapture, CaptureReturningColumn, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, TableRef, UpdateStatement, } from "./ast.ts";
|
|
44
|
-
export { ADVISORY_LOCK_RESULT_COLUMN, CHAIN_VETO_PREFIX, CHAIN_VETO_TOKEN_PATTERN, SQL_DEFAULT_CELL, SQL_KEEP_CELL, chainVetoToken, dbNowMarker, excludedRef, isDbNowMarker, isExcludedRef, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, isSqlKeepCell, isStepColumnRef, isCaptureReturningColumn, jsonParamCell, returningColumnName, stepColumnRef, } from "./ast.ts";
|
|
43
|
+
export type { AdvisoryLockKey, AdvisoryLockStatement, AdvisoryLocksStatement, AggFn, AggRef, AggSelect, ChainResult, ChainRowSource, ChainCapture, CaptureReturningColumn, ChainStatement, ChainStep, ChainStepStatement, ChainTally, ChainVeto, ColRef, ComparisonOp, DateTruncation, CountSubquery, ScalarSubquery, DeleteStatement, ExcludedRef, InnerJoin, KeyListMember, KeyPage, KeyRows, KeyTableJoin, KeyTableMember, InsertSelectStatement, InsertStatement, ReturningColumn, JsonFilterOp, LateralJoin, LeftJoin, ListSetOperation, OnConflictClause, OnConflictDoNothing, OnConflictUpdate, OrderByAggregate, OrderByColumn, OrderBySubquery, OrderTerm, RowLock, RowNumberProjection, DbNowMarker, JsonParamCell, SelectExpr, SelectStatement, SetOperation, SetOperator, SqlExpr, SqlStatement, StepColumnRef, SourceColumnRef, UpdateSource, TableRef, UpdateStatement, } from "./ast.ts";
|
|
44
|
+
export { ADVISORY_LOCK_RESULT_COLUMN, CHAIN_VETO_PREFIX, CHAIN_VETO_TOKEN_PATTERN, SQL_DEFAULT_CELL, SQL_KEEP_CELL, chainVetoToken, dbNowMarker, excludedRef, isDbNowMarker, isExcludedRef, isJsonParamCell, isListSetOperation, isSetOperation, isSqlDefaultCell, isSqlKeepCell, isStepColumnRef, isSourceColumnRef, sourceColumnRef, isCaptureReturningColumn, jsonParamCell, returningColumnName, stepColumnRef, } from "./ast.ts";
|
|
45
45
|
export type { AdvisoryLockFunctions, AdvisoryLockModeFunctions, RowLockSyntax, EmptyInsertSyntax, SqlDialect, } from "./dialect.ts";
|
|
46
46
|
export { ADVISORY_KEY_BOUNDS, describeRowLock, renderAdvisoryLock, renderAdvisoryLocks, renderRowLockClause } from "./locks.ts";
|
|
47
47
|
export { JSON_TRANSPORT, projectionOutputName } from "./json-transport.ts";
|
package/dist/index.js
CHANGED
|
@@ -2903,6 +2903,15 @@ var ADVISORY_LOCK_RESULT_COLUMN = "acquired";
|
|
|
2903
2903
|
function stepColumnRef(params) {
|
|
2904
2904
|
return { __stepColumn: true, step: params.step, column: params.column };
|
|
2905
2905
|
}
|
|
2906
|
+
function sourceColumnRef(params) {
|
|
2907
|
+
return Object.freeze({ __sourceColumn: true, column: params.column });
|
|
2908
|
+
}
|
|
2909
|
+
function isSourceColumnRef(value) {
|
|
2910
|
+
if (typeof value !== "object" || value === null)
|
|
2911
|
+
return false;
|
|
2912
|
+
const candidate = value;
|
|
2913
|
+
return candidate.__sourceColumn === true && typeof candidate.column === "string" && Object.keys(value).length === 2;
|
|
2914
|
+
}
|
|
2906
2915
|
function isStepColumnRef(value) {
|
|
2907
2916
|
return typeof value === "object" && value !== null && value.__stepColumn === true;
|
|
2908
2917
|
}
|
|
@@ -4960,17 +4969,18 @@ function applyReturning(params) {
|
|
|
4960
4969
|
renderCaptureReturning({ dialect, column: capture });
|
|
4961
4970
|
return { suffix: "", status: "omitted" };
|
|
4962
4971
|
}
|
|
4972
|
+
const read = (name) => params.qualify === undefined ? name : `${params.qualify}.${name}`;
|
|
4963
4973
|
const columns = requested.map((column) => {
|
|
4964
4974
|
if (typeof column === "string")
|
|
4965
|
-
return dialect.quoteIdent({ name: column });
|
|
4975
|
+
return read(dialect.quoteIdent({ name: column }));
|
|
4966
4976
|
if ("capture" in column)
|
|
4967
4977
|
return renderCaptureReturning({ dialect, column });
|
|
4968
4978
|
if ("transform" in column) {
|
|
4969
4979
|
const name = dialect.quoteIdent({ name: column.name });
|
|
4970
|
-
return `${dialect.jsonTextProjection({ expression: name })} AS ${name}`;
|
|
4980
|
+
return `${dialect.jsonTextProjection({ expression: read(name) })} AS ${name}`;
|
|
4971
4981
|
}
|
|
4972
4982
|
const name = dialect.quoteIdent({ name: column.name });
|
|
4973
|
-
return `${textProjection({ dialect, expression: name })} AS ${name}`;
|
|
4983
|
+
return `${textProjection({ dialect, expression: read(name) })} AS ${name}`;
|
|
4974
4984
|
}).join(", ");
|
|
4975
4985
|
return { suffix: ` RETURNING ${columns}`, status: "native" };
|
|
4976
4986
|
}
|
|
@@ -5404,6 +5414,18 @@ function renderUpdate(params) {
|
|
|
5404
5414
|
if (assignments.length === 0) {
|
|
5405
5415
|
throw internalError4({ message: "update must set at least one column" });
|
|
5406
5416
|
}
|
|
5417
|
+
const source = statement.from;
|
|
5418
|
+
if (source !== undefined) {
|
|
5419
|
+
if (statement.alias === undefined || statement.alias === source.alias)
|
|
5420
|
+
throw internalError4({ message: "UPDATE \u2026 FROM needs distinct target and source aliases" });
|
|
5421
|
+
const target = dialect.quoteIdent({ name: statement.alias });
|
|
5422
|
+
const joined = dialect.quoteIdent({ name: source.alias });
|
|
5423
|
+
const assign = () => renderAssignments({ dialect, entries: assignments, collector, selfRef: target, source: joined, ...dialect.name === "mysql" ? { qualifyWrite: target } : {}, ...params.earlier === undefined ? {} : { steps: params.earlier } });
|
|
5424
|
+
const where = () => statement.where === undefined ? "" : ` AND ${renderExpr({ dialect, expr: statement.where, collector })}`;
|
|
5425
|
+
const text = dialect.name === "mysql" ? `UPDATE ${renderTable(dialect, statement.table)} AS ${target} JOIN ${renderTable(dialect, source.table)} AS ${joined} ON ${renderExpr({ dialect, expr: source.on, collector })} SET ${assign()}${statement.where === undefined ? "" : ` WHERE ${renderExpr({ dialect, expr: statement.where, collector })}`}` : `UPDATE ${renderTable(dialect, statement.table)} AS ${target} SET ${assign()} FROM ${renderTable(dialect, source.table)} AS ${joined} WHERE ${renderExpr({ dialect, expr: source.on, collector })}${where()}`;
|
|
5426
|
+
const returning = applyReturning({ dialect, requested: statement.returning, ...dialect.name === "postgres" ? { qualify: target } : {} });
|
|
5427
|
+
return { text: text + returning.suffix, values: collector.values, returning: returning.status };
|
|
5428
|
+
}
|
|
5407
5429
|
const setSql = renderAssignments({ dialect, entries: assignments, collector, ...params.earlier === undefined ? {} : { steps: params.earlier } });
|
|
5408
5430
|
let text = `UPDATE ${renderTable(dialect, statement.table)} SET ${setSql}`;
|
|
5409
5431
|
if (statement.where !== undefined) {
|
|
@@ -5423,6 +5445,11 @@ function renderAssignments(params) {
|
|
|
5423
5445
|
return entries.map(([name, value]) => {
|
|
5424
5446
|
const column = dialect.quoteIdent({ name });
|
|
5425
5447
|
const read = selfRef === undefined ? column : `${selfRef}.${column}`;
|
|
5448
|
+
if (isSourceColumnRef(value)) {
|
|
5449
|
+
if (params.source === undefined)
|
|
5450
|
+
throw internalError4({ message: `an UPDATE set value reads the joined source's column ${value.column}, but the statement joins no source` });
|
|
5451
|
+
return `${column} = ${params.source}.${dialect.quoteIdent({ name: value.column })}`;
|
|
5452
|
+
}
|
|
5426
5453
|
if (isStepColumnRef(value)) {
|
|
5427
5454
|
if (params.steps === undefined || !params.steps.has(value.step)) {
|
|
5428
5455
|
throw internalError4({ message: `an UPDATE set value reads step "${value.step}", which is not an earlier chain step` });
|
|
@@ -5466,7 +5493,7 @@ function renderAssignments(params) {
|
|
|
5466
5493
|
return `${column} = ${read} || ${collector.add(value.value)}`;
|
|
5467
5494
|
}
|
|
5468
5495
|
return `${column} = ${collector.add(value)}`;
|
|
5469
|
-
}).join(", ");
|
|
5496
|
+
}).map((assignment) => params.qualifyWrite === undefined ? assignment : `${params.qualifyWrite}.${assignment}`).join(", ");
|
|
5470
5497
|
}
|
|
5471
5498
|
function renderDelete(params) {
|
|
5472
5499
|
const { dialect, statement, collector } = params;
|
|
@@ -5569,8 +5596,12 @@ function captureAliases(params) {
|
|
|
5569
5596
|
out.push(`${entry.alias}_i`);
|
|
5570
5597
|
if (entry.before !== undefined && entry.before.length > 0)
|
|
5571
5598
|
out.push(`${entry.alias}_b`);
|
|
5572
|
-
if (entry.after !== undefined && entry.after.length > 0)
|
|
5573
|
-
|
|
5599
|
+
if (entry.after !== undefined && entry.after.length > 0) {
|
|
5600
|
+
if (entry.inserted === undefined || entry.insertedOnly !== true)
|
|
5601
|
+
out.push(`${entry.alias}_a`);
|
|
5602
|
+
if (entry.inserted !== undefined)
|
|
5603
|
+
out.push(`${entry.alias}_ia`);
|
|
5604
|
+
}
|
|
5574
5605
|
}
|
|
5575
5606
|
return out;
|
|
5576
5607
|
}
|
|
@@ -5595,10 +5626,13 @@ function renderChainCaptures(params) {
|
|
|
5595
5626
|
const limit = collector.add(entry.limit);
|
|
5596
5627
|
const item = quote("__vibe_i");
|
|
5597
5628
|
const image = (columns, filter) => `(SELECT array_agg(${item})::text FROM (SELECT DISTINCT ARRAY[${columns.map(quote).join(", ")}] AS ${item} FROM ${step}${filter} LIMIT ${limit}) AS ${quote("__vibe_d")})`;
|
|
5629
|
+
const updatedRows = marker === undefined ? "" : ` WHERE NOT ${marker}`;
|
|
5598
5630
|
if (before.length > 0)
|
|
5599
|
-
out.push(`${image(before,
|
|
5600
|
-
if (after.length > 0)
|
|
5601
|
-
out.push(`${image(after,
|
|
5631
|
+
out.push(`${image(before, updatedRows)} AS ${quote(`${entry.alias}_b`)}`);
|
|
5632
|
+
if (after.length > 0 && (marker === undefined || entry.insertedOnly !== true))
|
|
5633
|
+
out.push(`${image(after, updatedRows)} AS ${quote(`${entry.alias}_a`)}`);
|
|
5634
|
+
if (after.length > 0 && marker !== undefined)
|
|
5635
|
+
out.push(`${image(after, ` WHERE ${marker}`)} AS ${quote(`${entry.alias}_ia`)}`);
|
|
5602
5636
|
}
|
|
5603
5637
|
return out;
|
|
5604
5638
|
}
|
|
@@ -6413,6 +6447,7 @@ export {
|
|
|
6413
6447
|
isReusableSqlCommand,
|
|
6414
6448
|
isReusableSqlQuery,
|
|
6415
6449
|
isSetOperation,
|
|
6450
|
+
isSourceColumnRef,
|
|
6416
6451
|
isSqlBindingCollector,
|
|
6417
6452
|
isSqlCommand,
|
|
6418
6453
|
isSqlDefaultCell,
|
|
@@ -6532,6 +6567,7 @@ export {
|
|
|
6532
6567
|
sealSqlInputScope,
|
|
6533
6568
|
shortestFloat32,
|
|
6534
6569
|
snapshotSqlValue,
|
|
6570
|
+
sourceColumnRef,
|
|
6535
6571
|
sql,
|
|
6536
6572
|
sqlInputContract,
|
|
6537
6573
|
sqlParamContract,
|
|
@@ -6551,4 +6587,4 @@ export {
|
|
|
6551
6587
|
toPgArrayLiteral
|
|
6552
6588
|
};
|
|
6553
6589
|
|
|
6554
|
-
//# debugId=
|
|
6590
|
+
//# debugId=0EA38AD633C52F8C64756E2164756E21
|