@dbsp/adapter-pgsql 1.8.0 → 1.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ExpressionRef, IndexInfo, TruncateOptions, VacuumOptions, AlterColumnOptions, CreateIndexOptions, DropIndexOptions, ModelIR as ModelIR$1 } from '@dbsp/core';
2
2
  export { normalizeSQL } from '@dbsp/core';
3
3
  import * as _dbsp_types from '@dbsp/types';
4
- import { ColumnListInput, ParamIntent, JsonAggOrderByEntry, DialectCapabilities, ModelIR, DbCasing, ColumnIR, HierarchyIR, WhereIntent, Adapter, AdapterLogger, AdapterCapabilities, PlanReport, CompiledNqlQuery, CompileOptions, CompiledQuery, CompileResultWithIncludes, SubqueryIncludeInfo, ExpressionIntent, InsertIntent, InsertFromIntent, UpdateIntent, BatchUpdateIntent, DeleteIntent, UpsertIntent, UpsertFromIntent, RecursivePlanReport, CteQueryIntent, SetOperationIntent, DumpMeta, Dump, AdapterStreamOptions, CompileOnlyAdapter, QueryIntent } from '@dbsp/types';
4
+ import { ColumnListInput, ParamIntent, JsonAggOrderByEntry, DialectCapabilities, ModelIR, DbCasing, ColumnIR, HierarchyIR, MutationReturningItem, WhereIntent, Adapter, AdapterLogger, AdapterCapabilities, PlanReport, CompiledNqlQuery, CompileOptions, CompiledQuery, CompileResultWithIncludes, SubqueryIncludeInfo, ExpressionIntent, InsertIntent, InsertFromIntent, UpdateIntent, BatchUpdateIntent, DeleteIntent, UpsertIntent, UpsertFromIntent, RecursivePlanReport, CteQueryIntent, SetOperationIntent, DumpMeta, Dump, AdapterStreamOptions, CompileOnlyAdapter, QueryIntent } from '@dbsp/types';
5
5
  import * as _pgsql_types from '@pgsql/types';
6
6
  import { Node, OnConflictClause, ParamRef } from '@pgsql/types';
7
7
  import { Pool, PoolClient } from 'pg';
@@ -1368,6 +1368,8 @@ interface InsertConfig {
1368
1368
  values: unknown[][];
1369
1369
  /** Columns to return (RETURNING clause) */
1370
1370
  returning?: string[];
1371
+ /** Alias-aware RETURNING projection items */
1372
+ returningItems?: readonly MutationReturningItem[];
1371
1373
  /** Subquery for INSERT ... SELECT */
1372
1374
  selectQuery?: Node;
1373
1375
  /** Column database types for type-cast emission (e.g. range types) */
@@ -1388,6 +1390,8 @@ interface UpdateConfig {
1388
1390
  where?: Decision[];
1389
1391
  /** Columns to return (RETURNING clause) */
1390
1392
  returning?: string[];
1393
+ /** Alias-aware RETURNING projection items */
1394
+ returningItems?: readonly MutationReturningItem[];
1391
1395
  /** Column database types for type-cast emission (e.g. range types) */
1392
1396
  columnTypes?: Record<string, string>;
1393
1397
  }
@@ -1401,6 +1405,8 @@ interface DeleteConfig {
1401
1405
  where?: Decision[];
1402
1406
  /** Columns to return (RETURNING clause) */
1403
1407
  returning?: string[];
1408
+ /** Alias-aware RETURNING projection items */
1409
+ returningItems?: readonly MutationReturningItem[];
1404
1410
  }
1405
1411
  /**
1406
1412
  * Compile an INSERT statement from configuration.
@@ -1469,6 +1475,8 @@ interface UpsertConfig {
1469
1475
  useExcluded?: boolean;
1470
1476
  /** Columns to return (RETURNING clause) */
1471
1477
  returning?: string[];
1478
+ /** Alias-aware RETURNING projection items */
1479
+ returningItems?: readonly MutationReturningItem[];
1472
1480
  /** Optional column type hints for unnest casting (schema-driven) */
1473
1481
  columnTypes?: Record<string, string>;
1474
1482
  /**
package/dist/index.js CHANGED
@@ -14033,12 +14033,48 @@ init_handlers();
14033
14033
  init_param_intent();
14034
14034
  init_param_ref();
14035
14035
  import { isSqlRaw } from "@dbsp/core";
14036
- import { isParamIntent as isParamIntent7 } from "@dbsp/types";
14037
- function buildReturningList(columns, tableRef, ctx) {
14038
- if (!columns || columns.length === 0) return void 0;
14036
+ import {
14037
+ isParamIntent as isParamIntent7
14038
+ } from "@dbsp/types";
14039
+ function buildReturningList(columns, tableRef, ctx, returningItems) {
14039
14040
  const { naming } = ctx;
14041
+ if (returningItems !== void 0) {
14042
+ const returning = columns ?? [];
14043
+ if (returningItems.length !== returning.length) {
14044
+ throw new Error(
14045
+ `Invalid mutation RETURNING items: returningItems length (${returningItems.length}) must match returning length (${returning.length}).`
14046
+ );
14047
+ }
14048
+ if (returning.includes("*") || returningItems.some((item) => item.output === "*" || item.source === "*")) {
14049
+ throw new Error(
14050
+ "Invalid mutation RETURNING items: star RETURNING cannot carry alias-aware returningItems."
14051
+ );
14052
+ }
14053
+ if (returningItems.length === 0) return void 0;
14054
+ const emittedOutputs = /* @__PURE__ */ new Map();
14055
+ return returningItems.map((item, index) => {
14056
+ if (item.output !== returning[index]) {
14057
+ throw new Error(
14058
+ `Invalid mutation RETURNING items: returningItems[${index}].output '${item.output}' must match returning[${index}] '${returning[index]}'.`
14059
+ );
14060
+ }
14061
+ const emittedOutput = naming.toDatabase(item.output);
14062
+ const previousOutput = emittedOutputs.get(emittedOutput);
14063
+ if (previousOutput !== void 0) {
14064
+ throw new Error(
14065
+ `Duplicate mutation RETURNING output after database naming: '${emittedOutput}' from '${previousOutput}' and '${item.output}'.`
14066
+ );
14067
+ }
14068
+ emittedOutputs.set(emittedOutput, item.output);
14069
+ return resTarget(
14070
+ columnRef(item.source, tableRef, ctx.schema, naming),
14071
+ emittedOutput
14072
+ );
14073
+ });
14074
+ }
14075
+ if (!columns || columns.length === 0) return void 0;
14040
14076
  return columns.map(
14041
- (col) => resTarget(
14077
+ (col) => col === "*" ? starTarget() : resTarget(
14042
14078
  columnRef(col, tableRef, ctx.schema, naming),
14043
14079
  naming.toDatabase(col)
14044
14080
  )
@@ -14057,7 +14093,12 @@ function compileInsert(config, ctx, state) {
14057
14093
  return valueToNode(val, state, dbType);
14058
14094
  })
14059
14095
  );
14060
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14096
+ const returningList = buildReturningList(
14097
+ config.returning,
14098
+ dbTable,
14099
+ ctx,
14100
+ config.returningItems
14101
+ );
14061
14102
  const options = {
14062
14103
  table: config.table,
14063
14104
  columns: dbColumns,
@@ -14096,7 +14137,12 @@ function compileUnnestInsert(config, ctx, state) {
14096
14137
  targetList
14097
14138
  }
14098
14139
  };
14099
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14140
+ const returningList = buildReturningList(
14141
+ config.returning,
14142
+ dbTable,
14143
+ ctx,
14144
+ config.returningItems
14145
+ );
14100
14146
  const options = {
14101
14147
  table: config.table,
14102
14148
  columns: columns.map((c) => naming.toDatabase(c)),
@@ -14135,7 +14181,12 @@ function compileUpdate(config, ctx, state) {
14135
14181
  };
14136
14182
  }
14137
14183
  }
14138
- const returningList = buildReturningList(config.returning, tableAlias, ctx);
14184
+ const returningList = buildReturningList(
14185
+ config.returning,
14186
+ tableAlias,
14187
+ ctx,
14188
+ config.returningItems
14189
+ );
14139
14190
  const options = {
14140
14191
  table: config.table,
14141
14192
  set: setClause,
@@ -14205,7 +14256,12 @@ function compileUnnestUpdate(config, ctx, state) {
14205
14256
  args: [matchWhere, config.whereGuard]
14206
14257
  }
14207
14258
  } : matchWhere;
14208
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14259
+ const returningList = buildReturningList(
14260
+ config.returning,
14261
+ dbTable,
14262
+ ctx,
14263
+ config.returningItems
14264
+ );
14209
14265
  const options = {
14210
14266
  table,
14211
14267
  set: setClause,
@@ -14238,7 +14294,12 @@ function compileDelete(config, ctx, state) {
14238
14294
  };
14239
14295
  }
14240
14296
  }
14241
- const returningList = buildReturningList(config.returning, tableAlias, ctx);
14297
+ const returningList = buildReturningList(
14298
+ config.returning,
14299
+ tableAlias,
14300
+ ctx,
14301
+ config.returningItems
14302
+ );
14242
14303
  const options = {
14243
14304
  table: config.table,
14244
14305
  naming
@@ -14318,7 +14379,8 @@ function compileInsertFrom(config, ctx, state) {
14318
14379
  const returningList = buildReturningList(
14319
14380
  config.returning,
14320
14381
  config.targetTable,
14321
- ctx
14382
+ ctx,
14383
+ config.returningItems
14322
14384
  );
14323
14385
  const options = {
14324
14386
  table: config.targetTable,
@@ -14399,7 +14461,8 @@ function compileUpsertFrom(config, ctx, state) {
14399
14461
  const returningList = buildReturningList(
14400
14462
  config.returning,
14401
14463
  config.targetTable,
14402
- ctx
14464
+ ctx,
14465
+ config.returningItems
14403
14466
  );
14404
14467
  const conflictInfer = {
14405
14468
  indexElems: config.conflictColumns.map((col) => ({
@@ -14636,7 +14699,12 @@ function compileUpsert(config, ctx, state) {
14636
14699
  }
14637
14700
  }));
14638
14701
  const onConflict = buildOnConflictClause(config, ctx, state);
14639
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14702
+ const returningList = buildReturningList(
14703
+ config.returning,
14704
+ dbTable,
14705
+ ctx,
14706
+ config.returningItems
14707
+ );
14640
14708
  return {
14641
14709
  InsertStmt: {
14642
14710
  relation: {
@@ -14686,7 +14754,12 @@ function compileUnnestUpsert(config, ctx, state) {
14686
14754
  }
14687
14755
  };
14688
14756
  const onConflict = buildOnConflictClause(config, ctx, state);
14689
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14757
+ const returningList = buildReturningList(
14758
+ config.returning,
14759
+ dbTable,
14760
+ ctx,
14761
+ config.returningItems
14762
+ );
14690
14763
  return {
14691
14764
  InsertStmt: {
14692
14765
  relation: {
@@ -16563,6 +16636,7 @@ function compileInsert2(intent, options, deps) {
16563
16636
  columns,
16564
16637
  values,
16565
16638
  ...intent.returning && { returning: [...intent.returning] },
16639
+ ...intent.returningItems && { returningItems: intent.returningItems },
16566
16640
  ...columnTypes && { columnTypes }
16567
16641
  };
16568
16642
  const maxBatchSize = options?.maxBatchSize;
@@ -16609,7 +16683,8 @@ function compileInsertFrom2(intent, options, deps) {
16609
16683
  ...intent.columns && { columns: [...intent.columns] },
16610
16684
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16611
16685
  ...intent.limit !== void 0 && { limit: intent.limit },
16612
- ...intent.returning && { returning: [...intent.returning] }
16686
+ ...intent.returning && { returning: [...intent.returning] },
16687
+ ...intent.returningItems && { returningItems: intent.returningItems }
16613
16688
  };
16614
16689
  const ast = compileInsertFrom(config, ctx, state);
16615
16690
  const sql = deparseQuoted(ast);
@@ -16647,6 +16722,7 @@ function compileUpdate2(intent, options, deps) {
16647
16722
  })),
16648
16723
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16649
16724
  ...intent.returning && { returning: [...intent.returning] },
16725
+ ...intent.returningItems && { returningItems: intent.returningItems },
16650
16726
  ...columnTypes && { columnTypes }
16651
16727
  };
16652
16728
  const ast = compileUpdate(config, ctx, state);
@@ -16728,6 +16804,7 @@ function compileBatchUpdate(intent, _options, deps) {
16728
16804
  columnArrays,
16729
16805
  ...scalarSet && { scalarSet },
16730
16806
  ...intent.returning && { returning: [...intent.returning] },
16807
+ ...intent.returningItems && { returningItems: intent.returningItems },
16731
16808
  ...columnTypes && { columnTypes },
16732
16809
  ...whereGuard !== void 0 && { whereGuard }
16733
16810
  };
@@ -16757,7 +16834,8 @@ function compileDelete2(intent, options, deps) {
16757
16834
  const config = {
16758
16835
  table: intent.table,
16759
16836
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16760
- ...intent.returning && { returning: [...intent.returning] }
16837
+ ...intent.returning && { returning: [...intent.returning] },
16838
+ ...intent.returningItems && { returningItems: intent.returningItems }
16761
16839
  };
16762
16840
  const ast = compileDelete(config, ctx, state);
16763
16841
  const sql = deparseQuoted(ast);
@@ -16827,6 +16905,7 @@ function compileUpsert2(intent, options, deps) {
16827
16905
  conflictAction,
16828
16906
  ...updateColumns && { updateColumns },
16829
16907
  ...intent.returning && { returning: [...intent.returning] },
16908
+ ...intent.returningItems && { returningItems: intent.returningItems },
16830
16909
  ...columnTypes && { columnTypes },
16831
16910
  ...hasRawExprs && { updateExpressions: rawExprs },
16832
16911
  ...resolvedActionWhere && {
@@ -16894,7 +16973,8 @@ function compileUpsertFrom2(intent, options, deps) {
16894
16973
  ...columns && { columns },
16895
16974
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16896
16975
  ...intent.limit !== void 0 && { limit: intent.limit },
16897
- ...intent.returning && { returning: [...intent.returning] }
16976
+ ...intent.returning && { returning: [...intent.returning] },
16977
+ ...intent.returningItems && { returningItems: intent.returningItems }
16898
16978
  };
16899
16979
  const ast = compileUpsertFrom(config, ctx, state);
16900
16980
  const sql = deparseQuoted(ast);
@@ -18550,13 +18630,29 @@ function compileTypedNqlRuntimeBindingCte(name, binding, naming, parameterOffset
18550
18630
  parameters
18551
18631
  };
18552
18632
  }
18553
- function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sourceTable, schemaName, model) {
18633
+ function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sourceTable, schemaName, model, returningItems) {
18634
+ if (returningItems !== void 0) {
18635
+ if (returningItems.length !== binding.columns.length || returningItems.some((item, i) => item.output !== binding.columns[i])) {
18636
+ throw new Error(
18637
+ `NQL runtime binding '${name}' has returningItems desynced from its projected columns.`
18638
+ );
18639
+ }
18640
+ }
18641
+ const sourceColumnFor = (output) => returningItems?.find((item) => item.output === output)?.source ?? output;
18554
18642
  if (binding.columns.length === 0) {
18555
18643
  throw new Error(
18556
18644
  `NQL runtime binding '${name}' cannot be materialized without projected columns.`
18557
18645
  );
18558
18646
  }
18559
18647
  const cteName = quoteIdent2(emittedBindName(name, naming), "alias");
18648
+ const emittedColumnNames = binding.columns.map(
18649
+ (column) => naming.toDatabase(column)
18650
+ );
18651
+ if (new Set(emittedColumnNames).size !== emittedColumnNames.length) {
18652
+ throw new Error(
18653
+ `NQL runtime binding '${name}' emits duplicate column names after database naming.`
18654
+ );
18655
+ }
18560
18656
  const columnSql = binding.columns.map((column) => quoteIdent2(naming.toDatabase(column), "column")).join(", ");
18561
18657
  if (binding.columnTypes !== void 0) {
18562
18658
  return compileTypedNqlRuntimeBindingCte(
@@ -18573,7 +18669,9 @@ function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sou
18573
18669
  `NQL runtime binding '${name}' cannot materialize a typed relation because its source table is unavailable.`
18574
18670
  );
18575
18671
  }
18576
- const projectedColumns = binding.columns.map((column) => quoteIdent2(naming.toDatabase(column), "column")).join(", ");
18672
+ const projectedColumns = binding.columns.map(
18673
+ (column) => quoteIdent2(naming.toDatabase(sourceColumnFor(column)), "column")
18674
+ ).join(", ");
18577
18675
  const sourceAnchorSql = `SELECT ${projectedColumns} FROM ${qualifyTableIdent(sourceTable, schemaName, naming)} WHERE false`;
18578
18676
  if (binding.rows.length === 0) {
18579
18677
  return {
@@ -18584,7 +18682,7 @@ function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sou
18584
18682
  assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset);
18585
18683
  const columnTypes = resolveRuntimeBindingColumnTypes(
18586
18684
  name,
18587
- binding,
18685
+ { ...binding, columns: binding.columns.map(sourceColumnFor) },
18588
18686
  model,
18589
18687
  sourceTable
18590
18688
  );
@@ -18847,7 +18945,8 @@ var PgsqlAdapter = class _PgsqlAdapter {
18847
18945
  parameters.length,
18848
18946
  runtimeBindingSourceTable(bundle, name),
18849
18947
  deps.schemaName,
18850
- deps.model
18948
+ deps.model,
18949
+ bundle.mutationBindings?.get(name)?.returningItems
18851
18950
  );
18852
18951
  ctes.push(compiledRuntimeBinding.cte);
18853
18952
  parameters.push(...compiledRuntimeBinding.parameters);