@dbsp/adapter-pgsql 1.7.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
@@ -4859,10 +4859,7 @@ var init_where = __esm({
4859
4859
  hasRelationHandler,
4860
4860
  hasNoRelationHandler
4861
4861
  ];
4862
- allWhereHandlers = [
4863
- ...simpleWhereHandlers,
4864
- ...complexWhereHandlers
4865
- ];
4862
+ allWhereHandlers = [...simpleWhereHandlers, ...complexWhereHandlers];
4866
4863
  }
4867
4864
  });
4868
4865
 
@@ -5385,10 +5382,6 @@ __export(handlers_exports, {
5385
5382
  LOGICAL_OPERATORS: () => LOGICAL_OPERATORS,
5386
5383
  NULL_OPERATORS: () => NULL_OPERATORS,
5387
5384
  PATTERN_OPERATORS: () => PATTERN_OPERATORS,
5388
- aggregateExpressionHandlers: () => aggregateExpressionHandlers,
5389
- allExpressionHandlers: () => allExpressionHandlers,
5390
- allIncludeHandlers: () => allIncludeHandlers,
5391
- allWhereHandlers: () => allWhereHandlers,
5392
5385
  andHandler: () => andHandler,
5393
5386
  anyHandler: () => anyHandler,
5394
5387
  arithmeticHandler: () => arithmeticHandler,
@@ -5399,12 +5392,9 @@ __export(handlers_exports, {
5399
5392
  clearHandlers: () => clearHandlers,
5400
5393
  coalesceHandler: () => coalesceHandler,
5401
5394
  columnAliasHandler: () => columnAliasHandler,
5402
- columnExpressionHandlers: () => columnExpressionHandlers,
5403
5395
  columnHandler: () => columnHandler,
5404
5396
  comparisonHandler: () => comparisonHandler,
5405
5397
  compileExpressionIntent: () => compileExpressionIntent,
5406
- complexWhereHandlers: () => complexWhereHandlers,
5407
- conditionalExpressionHandlers: () => conditionalExpressionHandlers,
5408
5398
  countDistinctHandler: () => countDistinctHandler,
5409
5399
  countHandler: () => countHandler,
5410
5400
  createCompilerState: () => createCompilerState,
@@ -5441,7 +5431,6 @@ __export(handlers_exports, {
5441
5431
  jsonComparisonHandler: () => jsonComparisonHandler,
5442
5432
  jsonContainsHandler: () => jsonContainsHandler,
5443
5433
  jsonExistsHandler: () => jsonExistsHandler,
5444
- jsonExpressionHandlers: () => jsonExpressionHandlers,
5445
5434
  jsonExtractHandler: () => jsonExtractHandler,
5446
5435
  jsonPathExtractHandler: () => jsonPathExtractHandler,
5447
5436
  lagHandler: () => lagHandler,
@@ -5462,11 +5451,9 @@ __export(handlers_exports, {
5462
5451
  orHandler: () => orHandler,
5463
5452
  prefixedRelationColumnHandler: () => prefixedRelationColumnHandler,
5464
5453
  pseudoColumnHandler: () => pseudoColumnHandler,
5465
- pseudoExpressionHandlers: () => pseudoExpressionHandlers,
5466
5454
  rangeHandler: () => rangeHandler,
5467
5455
  rankHandler: () => rankHandler,
5468
5456
  rawExistsHandler: () => rawExistsHandler,
5469
- rawExpressionHandlers: () => rawExpressionHandlers,
5470
5457
  rawHandler: () => rawHandler,
5471
5458
  registerAllExpressionHandlers: () => registerAllExpressionHandlers,
5472
5459
  registerAllIncludeHandlers: () => registerAllIncludeHandlers,
@@ -5478,7 +5465,6 @@ __export(handlers_exports, {
5478
5465
  relationAliasHandler: () => relationAliasHandler,
5479
5466
  relationColumnHandler: () => relationColumnHandler,
5480
5467
  relationColumnsHandler: () => relationColumnsHandler,
5481
- relationExpressionHandlers: () => relationExpressionHandlers,
5482
5468
  relationFilterHandler: () => relationFilterHandler,
5483
5469
  relationStarHandler: () => relationStarHandler,
5484
5470
  rowNumberHandler: () => rowNumberHandler,
@@ -5488,8 +5474,7 @@ __export(handlers_exports, {
5488
5474
  singleHopPseudoHandler: () => singleHopPseudoHandler,
5489
5475
  sqlFunctionHandler: () => sqlFunctionHandler,
5490
5476
  starHandler: () => starHandler,
5491
- sumHandler: () => sumHandler,
5492
- windowExpressionHandlers: () => windowExpressionHandlers
5477
+ sumHandler: () => sumHandler
5493
5478
  });
5494
5479
  function registerWhereHandler(handler) {
5495
5480
  for (const op3 of handler.operators) {
@@ -6929,6 +6914,14 @@ var init_raw = __esm({
6929
6914
  });
6930
6915
 
6931
6916
  // src/handlers/expression/relation.ts
6917
+ function resolveRelationAlias(relation, state, options = {}) {
6918
+ if (options.resolveDottedLeaf && relation.includes(".")) {
6919
+ const segments = relation.split(".");
6920
+ const leaf = segments[segments.length - 1];
6921
+ return state.aliases.get(relation) ?? state.aliases.get(leaf) ?? leaf;
6922
+ }
6923
+ return state.aliases.get(relation) ?? relation;
6924
+ }
6932
6925
  var relationStarHandler, relationColumnHandler, relationColumnsHandler, relationAliasHandler, prefixedRelationColumnHandler;
6933
6926
  var init_relation = __esm({
6934
6927
  "src/handlers/expression/relation.ts"() {
@@ -6961,14 +6954,9 @@ var init_relation = __esm({
6961
6954
  if (!column) {
6962
6955
  throw new Error("Relation column handler requires column name");
6963
6956
  }
6964
- let alias;
6965
- if (relation.includes(".")) {
6966
- const segments = relation.split(".");
6967
- const leaf = segments[segments.length - 1];
6968
- alias = state.aliases.get(relation) ?? state.aliases.get(leaf) ?? leaf;
6969
- } else {
6970
- alias = state.aliases.get(relation) ?? relation;
6971
- }
6957
+ const alias = resolveRelationAlias(relation, state, {
6958
+ resolveDottedLeaf: true
6959
+ });
6972
6960
  if (column === "*") {
6973
6961
  return columnRefStar(alias, ctx.naming);
6974
6962
  }
@@ -6986,7 +6974,7 @@ var init_relation = __esm({
6986
6974
  if (!columns || columns.length === 0) {
6987
6975
  throw new Error("Relation columns handler requires columns array");
6988
6976
  }
6989
- const alias = state.aliases.get(relation) ?? relation;
6977
+ const alias = resolveRelationAlias(relation, state);
6990
6978
  const column = columns[0];
6991
6979
  const colRef = columnRef(column, alias, void 0, ctx.naming);
6992
6980
  const outputAlias = decision.alias;
@@ -7012,7 +7000,7 @@ var init_relation = __esm({
7012
7000
  if (!column) {
7013
7001
  throw new Error("Relation alias handler requires column name");
7014
7002
  }
7015
- const tableAlias = state.aliases.get(relation) ?? relation;
7003
+ const tableAlias = resolveRelationAlias(relation, state);
7016
7004
  const colRef = columnRef(column, tableAlias, void 0, ctx.naming);
7017
7005
  if (!outputAlias) {
7018
7006
  return colRef;
@@ -7283,15 +7271,8 @@ var init_expression = __esm({
7283
7271
  lastValueHandler,
7284
7272
  genericWindowHandler
7285
7273
  ];
7286
- rawExpressionHandlers = [
7287
- rawHandler,
7288
- sqlFunctionHandler,
7289
- literalHandler
7290
- ];
7291
- jsonExpressionHandlers = [
7292
- jsonExtractHandler,
7293
- jsonPathExtractHandler
7294
- ];
7274
+ rawExpressionHandlers = [rawHandler, sqlFunctionHandler, literalHandler];
7275
+ jsonExpressionHandlers = [jsonExtractHandler, jsonPathExtractHandler];
7295
7276
  pseudoExpressionHandlers = [
7296
7277
  pseudoColumnHandler,
7297
7278
  singleHopPseudoHandler,
@@ -14052,12 +14033,48 @@ init_handlers();
14052
14033
  init_param_intent();
14053
14034
  init_param_ref();
14054
14035
  import { isSqlRaw } from "@dbsp/core";
14055
- import { isParamIntent as isParamIntent7 } from "@dbsp/types";
14056
- function buildReturningList(columns, tableRef, ctx) {
14057
- 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) {
14058
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;
14059
14076
  return columns.map(
14060
- (col) => resTarget(
14077
+ (col) => col === "*" ? starTarget() : resTarget(
14061
14078
  columnRef(col, tableRef, ctx.schema, naming),
14062
14079
  naming.toDatabase(col)
14063
14080
  )
@@ -14076,7 +14093,12 @@ function compileInsert(config, ctx, state) {
14076
14093
  return valueToNode(val, state, dbType);
14077
14094
  })
14078
14095
  );
14079
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14096
+ const returningList = buildReturningList(
14097
+ config.returning,
14098
+ dbTable,
14099
+ ctx,
14100
+ config.returningItems
14101
+ );
14080
14102
  const options = {
14081
14103
  table: config.table,
14082
14104
  columns: dbColumns,
@@ -14115,7 +14137,12 @@ function compileUnnestInsert(config, ctx, state) {
14115
14137
  targetList
14116
14138
  }
14117
14139
  };
14118
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14140
+ const returningList = buildReturningList(
14141
+ config.returning,
14142
+ dbTable,
14143
+ ctx,
14144
+ config.returningItems
14145
+ );
14119
14146
  const options = {
14120
14147
  table: config.table,
14121
14148
  columns: columns.map((c) => naming.toDatabase(c)),
@@ -14154,7 +14181,12 @@ function compileUpdate(config, ctx, state) {
14154
14181
  };
14155
14182
  }
14156
14183
  }
14157
- const returningList = buildReturningList(config.returning, tableAlias, ctx);
14184
+ const returningList = buildReturningList(
14185
+ config.returning,
14186
+ tableAlias,
14187
+ ctx,
14188
+ config.returningItems
14189
+ );
14158
14190
  const options = {
14159
14191
  table: config.table,
14160
14192
  set: setClause,
@@ -14224,7 +14256,12 @@ function compileUnnestUpdate(config, ctx, state) {
14224
14256
  args: [matchWhere, config.whereGuard]
14225
14257
  }
14226
14258
  } : matchWhere;
14227
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14259
+ const returningList = buildReturningList(
14260
+ config.returning,
14261
+ dbTable,
14262
+ ctx,
14263
+ config.returningItems
14264
+ );
14228
14265
  const options = {
14229
14266
  table,
14230
14267
  set: setClause,
@@ -14257,7 +14294,12 @@ function compileDelete(config, ctx, state) {
14257
14294
  };
14258
14295
  }
14259
14296
  }
14260
- const returningList = buildReturningList(config.returning, tableAlias, ctx);
14297
+ const returningList = buildReturningList(
14298
+ config.returning,
14299
+ tableAlias,
14300
+ ctx,
14301
+ config.returningItems
14302
+ );
14261
14303
  const options = {
14262
14304
  table: config.table,
14263
14305
  naming
@@ -14337,7 +14379,8 @@ function compileInsertFrom(config, ctx, state) {
14337
14379
  const returningList = buildReturningList(
14338
14380
  config.returning,
14339
14381
  config.targetTable,
14340
- ctx
14382
+ ctx,
14383
+ config.returningItems
14341
14384
  );
14342
14385
  const options = {
14343
14386
  table: config.targetTable,
@@ -14418,7 +14461,8 @@ function compileUpsertFrom(config, ctx, state) {
14418
14461
  const returningList = buildReturningList(
14419
14462
  config.returning,
14420
14463
  config.targetTable,
14421
- ctx
14464
+ ctx,
14465
+ config.returningItems
14422
14466
  );
14423
14467
  const conflictInfer = {
14424
14468
  indexElems: config.conflictColumns.map((col) => ({
@@ -14655,7 +14699,12 @@ function compileUpsert(config, ctx, state) {
14655
14699
  }
14656
14700
  }));
14657
14701
  const onConflict = buildOnConflictClause(config, ctx, state);
14658
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14702
+ const returningList = buildReturningList(
14703
+ config.returning,
14704
+ dbTable,
14705
+ ctx,
14706
+ config.returningItems
14707
+ );
14659
14708
  return {
14660
14709
  InsertStmt: {
14661
14710
  relation: {
@@ -14705,7 +14754,12 @@ function compileUnnestUpsert(config, ctx, state) {
14705
14754
  }
14706
14755
  };
14707
14756
  const onConflict = buildOnConflictClause(config, ctx, state);
14708
- const returningList = buildReturningList(config.returning, dbTable, ctx);
14757
+ const returningList = buildReturningList(
14758
+ config.returning,
14759
+ dbTable,
14760
+ ctx,
14761
+ config.returningItems
14762
+ );
14709
14763
  return {
14710
14764
  InsertStmt: {
14711
14765
  relation: {
@@ -15960,9 +16014,6 @@ function assertSafeTypeName(typeName, colIndex) {
15960
16014
  }
15961
16015
  }
15962
16016
  }
15963
- function bridgeLegacyDecisions(decisions) {
15964
- return decisions;
15965
- }
15966
16017
  function buildBatchValuesRangeFn(bv, startParamIndex, aliasOverride) {
15967
16018
  const params = [];
15968
16019
  let paramIdx = startParamIndex - 1;
@@ -16369,7 +16420,7 @@ function compileSelect(plan, options, deps) {
16369
16420
  } else {
16370
16421
  simplifiedPlan = {
16371
16422
  rootTable: plan.rootTable,
16372
- decisions: bridgeLegacyDecisions(plan.decisions),
16423
+ decisions: plan.decisions,
16373
16424
  ...schemaName ? { schema: schemaName } : {}
16374
16425
  };
16375
16426
  }
@@ -16585,6 +16636,7 @@ function compileInsert2(intent, options, deps) {
16585
16636
  columns,
16586
16637
  values,
16587
16638
  ...intent.returning && { returning: [...intent.returning] },
16639
+ ...intent.returningItems && { returningItems: intent.returningItems },
16588
16640
  ...columnTypes && { columnTypes }
16589
16641
  };
16590
16642
  const maxBatchSize = options?.maxBatchSize;
@@ -16631,7 +16683,8 @@ function compileInsertFrom2(intent, options, deps) {
16631
16683
  ...intent.columns && { columns: [...intent.columns] },
16632
16684
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16633
16685
  ...intent.limit !== void 0 && { limit: intent.limit },
16634
- ...intent.returning && { returning: [...intent.returning] }
16686
+ ...intent.returning && { returning: [...intent.returning] },
16687
+ ...intent.returningItems && { returningItems: intent.returningItems }
16635
16688
  };
16636
16689
  const ast = compileInsertFrom(config, ctx, state);
16637
16690
  const sql = deparseQuoted(ast);
@@ -16669,6 +16722,7 @@ function compileUpdate2(intent, options, deps) {
16669
16722
  })),
16670
16723
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16671
16724
  ...intent.returning && { returning: [...intent.returning] },
16725
+ ...intent.returningItems && { returningItems: intent.returningItems },
16672
16726
  ...columnTypes && { columnTypes }
16673
16727
  };
16674
16728
  const ast = compileUpdate(config, ctx, state);
@@ -16750,6 +16804,7 @@ function compileBatchUpdate(intent, _options, deps) {
16750
16804
  columnArrays,
16751
16805
  ...scalarSet && { scalarSet },
16752
16806
  ...intent.returning && { returning: [...intent.returning] },
16807
+ ...intent.returningItems && { returningItems: intent.returningItems },
16753
16808
  ...columnTypes && { columnTypes },
16754
16809
  ...whereGuard !== void 0 && { whereGuard }
16755
16810
  };
@@ -16779,7 +16834,8 @@ function compileDelete2(intent, options, deps) {
16779
16834
  const config = {
16780
16835
  table: intent.table,
16781
16836
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16782
- ...intent.returning && { returning: [...intent.returning] }
16837
+ ...intent.returning && { returning: [...intent.returning] },
16838
+ ...intent.returningItems && { returningItems: intent.returningItems }
16783
16839
  };
16784
16840
  const ast = compileDelete(config, ctx, state);
16785
16841
  const sql = deparseQuoted(ast);
@@ -16849,6 +16905,7 @@ function compileUpsert2(intent, options, deps) {
16849
16905
  conflictAction,
16850
16906
  ...updateColumns && { updateColumns },
16851
16907
  ...intent.returning && { returning: [...intent.returning] },
16908
+ ...intent.returningItems && { returningItems: intent.returningItems },
16852
16909
  ...columnTypes && { columnTypes },
16853
16910
  ...hasRawExprs && { updateExpressions: rawExprs },
16854
16911
  ...resolvedActionWhere && {
@@ -16916,7 +16973,8 @@ function compileUpsertFrom2(intent, options, deps) {
16916
16973
  ...columns && { columns },
16917
16974
  ...resolvedWhere && { where: [whereIntentAsDecision(resolvedWhere)] },
16918
16975
  ...intent.limit !== void 0 && { limit: intent.limit },
16919
- ...intent.returning && { returning: [...intent.returning] }
16976
+ ...intent.returning && { returning: [...intent.returning] },
16977
+ ...intent.returningItems && { returningItems: intent.returningItems }
16920
16978
  };
16921
16979
  const ast = compileUpsertFrom(config, ctx, state);
16922
16980
  const sql = deparseQuoted(ast);
@@ -18505,20 +18563,115 @@ function assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset
18505
18563
  `NQL runtime binding '${name}' would materialize ${valueParameterCount} VALUES parameters; limit is ${MAX_NQL_RUNTIME_BINDING_VALUES_PARAMETERS}. Current parameter offset is ${parameterOffset}, which would make ${totalParameterCount} total parameters before compiling the final statement.`
18506
18564
  );
18507
18565
  }
18508
- function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sourceTable, schemaName, model) {
18566
+ function resolvePgTypeForColumnTypeInfo(bindingName, column, info) {
18567
+ if (info.kind === "aggregate" && info.fn !== "count") {
18568
+ throw new Error(
18569
+ `NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${column}': unsupported aggregate kind '${String(info.fn)}'.`
18570
+ );
18571
+ }
18572
+ const rawType = info.kind === "aggregate" ? "bigint" : info.originalDbType?.trim() || mapRuntimeBindingColumnType(info.type);
18573
+ if (rawType === void 0 || rawType.trim() === "") {
18574
+ throw new Error(
18575
+ `NQL runtime binding '${bindingName}' cannot resolve a PostgreSQL type for projected column '${column}'.`
18576
+ );
18577
+ }
18578
+ const typeName = rawType.trim();
18579
+ try {
18580
+ validateTypeName4(typeName);
18581
+ } catch (error) {
18582
+ const reason = error instanceof Error ? error.message : String(error);
18583
+ throw new Error(
18584
+ `NQL runtime binding '${bindingName}' cannot use PostgreSQL cast type for projected column '${column}': ${reason}`
18585
+ );
18586
+ }
18587
+ return typeName;
18588
+ }
18589
+ function resolveRuntimeBindingCteColumnTypes(name, binding) {
18590
+ const columnTypes = binding.columnTypes;
18591
+ if (columnTypes === void 0) {
18592
+ throw new Error(
18593
+ `NQL runtime binding '${name}' cannot resolve typed columns without a columnTypes map.`
18594
+ );
18595
+ }
18596
+ return binding.columns.map((column) => {
18597
+ const info = columnTypes[column];
18598
+ if (info === void 0) {
18599
+ throw new Error(
18600
+ `NQL runtime binding '${name}' is missing type info for projected column '${column}'.`
18601
+ );
18602
+ }
18603
+ return resolvePgTypeForColumnTypeInfo(name, column, info);
18604
+ });
18605
+ }
18606
+ function compileTypedNqlRuntimeBindingCte(name, binding, naming, parameterOffset, cteName, columnSql) {
18607
+ const pgTypes = resolveRuntimeBindingCteColumnTypes(name, binding);
18608
+ const anchorColumns = binding.columns.map(
18609
+ (column, columnIndex) => `CAST(NULL AS ${pgTypes[columnIndex]}) AS ${quoteIdent2(naming.toDatabase(column), "column")}`
18610
+ ).join(", ");
18611
+ const sourceAnchorSql = `SELECT ${anchorColumns} WHERE false`;
18612
+ if (binding.rows.length === 0) {
18613
+ return {
18614
+ cte: `${cteName} (${columnSql}) as (${sourceAnchorSql})`,
18615
+ parameters: []
18616
+ };
18617
+ }
18618
+ assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset);
18619
+ const parameters = [];
18620
+ let nextParam = parameterOffset + 1;
18621
+ const valuesSql = binding.rows.map((row) => {
18622
+ const placeholders = binding.columns.map((column, columnIndex) => {
18623
+ parameters.push(row[column]);
18624
+ return `$${nextParam++}::${pgTypes[columnIndex]}`;
18625
+ });
18626
+ return `(${placeholders.join(", ")})`;
18627
+ }).join(", ");
18628
+ return {
18629
+ cte: `${cteName} (${columnSql}) as (${sourceAnchorSql} UNION ALL VALUES ${valuesSql})`,
18630
+ parameters
18631
+ };
18632
+ }
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;
18509
18642
  if (binding.columns.length === 0) {
18510
18643
  throw new Error(
18511
18644
  `NQL runtime binding '${name}' cannot be materialized without projected columns.`
18512
18645
  );
18513
18646
  }
18514
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
+ }
18515
18656
  const columnSql = binding.columns.map((column) => quoteIdent2(naming.toDatabase(column), "column")).join(", ");
18657
+ if (binding.columnTypes !== void 0) {
18658
+ return compileTypedNqlRuntimeBindingCte(
18659
+ name,
18660
+ binding,
18661
+ naming,
18662
+ parameterOffset,
18663
+ cteName,
18664
+ columnSql
18665
+ );
18666
+ }
18516
18667
  if (sourceTable === void 0) {
18517
18668
  throw new Error(
18518
18669
  `NQL runtime binding '${name}' cannot materialize a typed relation because its source table is unavailable.`
18519
18670
  );
18520
18671
  }
18521
- 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(", ");
18522
18675
  const sourceAnchorSql = `SELECT ${projectedColumns} FROM ${qualifyTableIdent(sourceTable, schemaName, naming)} WHERE false`;
18523
18676
  if (binding.rows.length === 0) {
18524
18677
  return {
@@ -18529,7 +18682,7 @@ function compileNqlRuntimeBindingCte(name, binding, naming, parameterOffset, sou
18529
18682
  assertRuntimeBindingValuesParameterCount(name, binding, parameterOffset);
18530
18683
  const columnTypes = resolveRuntimeBindingColumnTypes(
18531
18684
  name,
18532
- binding,
18685
+ { ...binding, columns: binding.columns.map(sourceColumnFor) },
18533
18686
  model,
18534
18687
  sourceTable
18535
18688
  );
@@ -18792,7 +18945,8 @@ var PgsqlAdapter = class _PgsqlAdapter {
18792
18945
  parameters.length,
18793
18946
  runtimeBindingSourceTable(bundle, name),
18794
18947
  deps.schemaName,
18795
- deps.model
18948
+ deps.model,
18949
+ bundle.mutationBindings?.get(name)?.returningItems
18796
18950
  );
18797
18951
  ctes.push(compiledRuntimeBinding.cte);
18798
18952
  parameters.push(...compiledRuntimeBinding.parameters);