@vibeorm/sql 5.5.0 → 5.6.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 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
  /**
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;
@@ -6413,6 +6440,7 @@ export {
6413
6440
  isReusableSqlCommand,
6414
6441
  isReusableSqlQuery,
6415
6442
  isSetOperation,
6443
+ isSourceColumnRef,
6416
6444
  isSqlBindingCollector,
6417
6445
  isSqlCommand,
6418
6446
  isSqlDefaultCell,
@@ -6532,6 +6560,7 @@ export {
6532
6560
  sealSqlInputScope,
6533
6561
  shortestFloat32,
6534
6562
  snapshotSqlValue,
6563
+ sourceColumnRef,
6535
6564
  sql,
6536
6565
  sqlInputContract,
6537
6566
  sqlParamContract,
@@ -6551,4 +6580,4 @@ export {
6551
6580
  toPgArrayLiteral
6552
6581
  };
6553
6582
 
6554
- //# debugId=98E9DEF83EE89CED64756E2164756E21
6583
+ //# debugId=FBE116988ABE557464756E2164756E21