@dbsp/adapter-pgsql 1.2.0 → 1.2.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
@@ -282,6 +282,7 @@ declare class PlanCompiler {
282
282
  private joinAliasMap;
283
283
  /**
284
284
  * Tracks all join aliases in use for the current query.
285
+ * Entries are stored in emitted database-alias space, after naming.toDatabase().
285
286
  * Ensures no two JOINs share the same alias (DOUBLE-ALIAS prevention).
286
287
  */
287
288
  private usedJoinAliases;
@@ -289,6 +290,8 @@ declare class PlanCompiler {
289
290
  /** Build immutable context for handler-based WHERE compilation */
290
291
  private handlerCtx;
291
292
  private findAliasForLegacySourceTable;
293
+ private emittedJoinAlias;
294
+ private resolvedJoinAliases;
292
295
  /**
293
296
  * Dispatch a PlanDecision through the unified WHERE handler system.
294
297
  * Bridges PlanCompiler's state to handler types, calls dispatcher, syncs back.
@@ -340,7 +343,9 @@ declare class PlanCompiler {
340
343
  * Compile an includeStrategy decision and register its results.
341
344
  * Pushes targets onto targetList, raw joins / CTEs onto instance collections.
342
345
  */
346
+ private registerIncludeCompilationResult;
343
347
  private compileIncludeDecision;
348
+ private compileJoinIncludeAllocationPass;
344
349
  /**
345
350
  * Fold a WHERE-family decision into an existing where expression.
346
351
  * Returns the updated (or new) where node.
@@ -362,6 +367,7 @@ declare class PlanCompiler {
362
367
  * column refs like `project_id` resolve against the joined table, not root.
363
368
  */
364
369
  private compileIncludeWhereConditions;
370
+ private reserveManualJoinAliases;
365
371
  /**
366
372
  * Apply a single join decision to the FROM clause in-place.
367
373
  * Chains multiple joins by wrapping from[0] as the left-arg each time.
@@ -1042,6 +1048,8 @@ interface CompilerContext {
1042
1048
  readonly rootTable: string;
1043
1049
  /** Current table alias (for JOINs) */
1044
1050
  readonly currentAlias?: string;
1051
+ /** Final relation path/name → SQL join alias map for relation-aware expression contexts */
1052
+ readonly aliases?: ReadonlyMap<string, string>;
1045
1053
  /** Maximum recursive depth (default: 100) */
1046
1054
  readonly maxRecursiveDepth: number;
1047
1055
  /** Optional callback for raw SQL audit trail */
package/dist/index.js CHANGED
@@ -1355,7 +1355,9 @@ function compileExpressionIntent(intent, ctx, state) {
1355
1355
  }
1356
1356
  case "relationColumn": {
1357
1357
  const rc = intent;
1358
- const alias = state.aliases.get(rc.relation) ?? rc.relation;
1358
+ const relationSegments = rc.relation.split(".");
1359
+ const leaf = relationSegments[relationSegments.length - 1] ?? rc.relation;
1360
+ const alias = state.aliases.get(rc.relation) ?? state.aliases.get(leaf) ?? leaf;
1359
1361
  return columnRef(rc.column, alias, void 0, ctx.naming);
1360
1362
  }
1361
1363
  case "case": {
@@ -2814,8 +2816,9 @@ var init_param_intent = __esm({
2814
2816
  import { isFieldRef, isParamIntent as isParamIntent3 } from "@dbsp/types";
2815
2817
  function buildColumnRef(column, ctx) {
2816
2818
  if (column.includes(".")) {
2817
- const dotIndex = column.indexOf(".");
2818
- const table = column.substring(0, dotIndex);
2819
+ const dotIndex = column.lastIndexOf(".");
2820
+ const relation = column.substring(0, dotIndex);
2821
+ const table = ctx.aliases?.get(relation) ?? relation;
2819
2822
  const col = column.substring(dotIndex + 1);
2820
2823
  return columnRef(col, table, void 0, ctx.naming);
2821
2824
  }
@@ -6685,7 +6688,7 @@ var init_relation = __esm({
6685
6688
  if (relation.includes(".")) {
6686
6689
  const segments = relation.split(".");
6687
6690
  const leaf = segments[segments.length - 1];
6688
- alias = state.aliases.get(leaf) ?? state.aliases.get(relation) ?? leaf;
6691
+ alias = state.aliases.get(relation) ?? state.aliases.get(leaf) ?? leaf;
6689
6692
  } else {
6690
6693
  alias = state.aliases.get(relation) ?? relation;
6691
6694
  }
@@ -8357,6 +8360,7 @@ var PlanCompiler = class _PlanCompiler {
8357
8360
  joinAliasMap = /* @__PURE__ */ new Map();
8358
8361
  /**
8359
8362
  * Tracks all join aliases in use for the current query.
8363
+ * Entries are stored in emitted database-alias space, after naming.toDatabase().
8360
8364
  * Ensures no two JOINs share the same alias (DOUBLE-ALIAS prevention).
8361
8365
  */
8362
8366
  usedJoinAliases = /* @__PURE__ */ new Set();
@@ -8372,6 +8376,7 @@ var PlanCompiler = class _PlanCompiler {
8372
8376
  return {
8373
8377
  naming: this.naming,
8374
8378
  rootTable: this.currentRootTable,
8379
+ aliases: this.resolvedJoinAliases(),
8375
8380
  maxRecursiveDepth: 100,
8376
8381
  defaultPkColumnName: this.defaultPk,
8377
8382
  deriveFkColumnName: this.deriveFk,
@@ -8386,6 +8391,24 @@ var PlanCompiler = class _PlanCompiler {
8386
8391
  }
8387
8392
  return alias;
8388
8393
  }
8394
+ emittedJoinAlias(alias) {
8395
+ const dbAlias = this.naming.toDatabase(alias);
8396
+ validateIdentifier(dbAlias, "alias");
8397
+ return dbAlias;
8398
+ }
8399
+ resolvedJoinAliases() {
8400
+ const aliases = /* @__PURE__ */ new Map();
8401
+ for (const [relationPath, entry] of this.joinAliasMap) {
8402
+ const isLegacyPath = relationPath.startsWith("__legacy__:");
8403
+ if (!isLegacyPath) {
8404
+ aliases.set(relationPath, entry.alias);
8405
+ }
8406
+ if (entry.relationName && (isLegacyPath || relationPath === entry.relationName)) {
8407
+ aliases.set(entry.relationName, entry.alias);
8408
+ }
8409
+ }
8410
+ return aliases;
8411
+ }
8389
8412
  /**
8390
8413
  * Dispatch a PlanDecision through the unified WHERE handler system.
8391
8414
  * Bridges PlanCompiler's state to handler types, calls dispatcher, syncs back.
@@ -8567,12 +8590,13 @@ var PlanCompiler = class _PlanCompiler {
8567
8590
  const candidateAlias = handlerDecision.relation ?? handlerDecision.targetTable ?? handlerDecision.relationName;
8568
8591
  if (candidateAlias) {
8569
8592
  let alias = candidateAlias;
8593
+ let emittedAlias = this.emittedJoinAlias(alias);
8570
8594
  let counter = 1;
8571
- while (this.usedJoinAliases.has(alias)) {
8595
+ while (this.usedJoinAliases.has(emittedAlias)) {
8572
8596
  alias = `${candidateAlias}_${counter++}`;
8597
+ emittedAlias = this.emittedJoinAlias(alias);
8573
8598
  }
8574
- validateIdentifier(alias, "alias");
8575
- this.usedJoinAliases.add(alias);
8599
+ this.usedJoinAliases.add(emittedAlias);
8576
8600
  finalJoinAlias = alias;
8577
8601
  if (alias !== candidateAlias) {
8578
8602
  handlerDecision.relation = alias;
@@ -8585,7 +8609,10 @@ var PlanCompiler = class _PlanCompiler {
8585
8609
  this.joinAliasMap.set(relationIdentityPath, {
8586
8610
  alias: finalJoinAlias,
8587
8611
  joinType: requestedJoinType,
8588
- ...decision.targetTable && { targetTable: decision.targetTable }
8612
+ ...decision.targetTable && { targetTable: decision.targetTable },
8613
+ ...(decision.relationName ?? decision.relation) && {
8614
+ relationName: decision.relationName ?? decision.relation
8615
+ }
8589
8616
  });
8590
8617
  }
8591
8618
  const out = {};
@@ -8658,6 +8685,7 @@ var PlanCompiler = class _PlanCompiler {
8658
8685
  naming: this.naming,
8659
8686
  rootTable: plan.rootTable,
8660
8687
  currentAlias: currentAlias ?? plan.rootTable,
8688
+ aliases: this.resolvedJoinAliases(),
8661
8689
  maxRecursiveDepth: 100,
8662
8690
  defaultPkColumnName: this.defaultPk,
8663
8691
  deriveFkColumnName: this.deriveFk,
@@ -8673,7 +8701,7 @@ var PlanCompiler = class _PlanCompiler {
8673
8701
  parameters: this.state.parameters,
8674
8702
  paramIndex: this.state.paramIndex,
8675
8703
  ctes: /* @__PURE__ */ new Map(),
8676
- aliases: /* @__PURE__ */ new Map(),
8704
+ aliases: this.resolvedJoinAliases(),
8677
8705
  joins: []
8678
8706
  };
8679
8707
  }
@@ -9131,11 +9159,7 @@ var PlanCompiler = class _PlanCompiler {
9131
9159
  * Compile an includeStrategy decision and register its results.
9132
9160
  * Pushes targets onto targetList, raw joins / CTEs onto instance collections.
9133
9161
  */
9134
- compileIncludeDecision(decision, plan, targetList) {
9135
- const includeResult = this.compileIncludeViaHandler(decision, plan);
9136
- if (includeResult.targets) {
9137
- targetList.push(...includeResult.targets);
9138
- }
9162
+ registerIncludeCompilationResult(includeResult) {
9139
9163
  if (includeResult.rawJoin) {
9140
9164
  this.rawJoins.push(includeResult.rawJoin);
9141
9165
  }
@@ -9146,6 +9170,27 @@ var PlanCompiler = class _PlanCompiler {
9146
9170
  this.pendingCtes.push(includeResult.cte);
9147
9171
  }
9148
9172
  }
9173
+ compileIncludeDecision(decision, plan, targetList, precompiled) {
9174
+ const includeResult = precompiled ?? this.compileIncludeViaHandler(decision, plan);
9175
+ if (includeResult.targets) {
9176
+ targetList.push(...includeResult.targets);
9177
+ }
9178
+ if (!precompiled) {
9179
+ this.registerIncludeCompilationResult(includeResult);
9180
+ }
9181
+ }
9182
+ compileJoinIncludeAllocationPass(decisions, plan) {
9183
+ const includeResults = /* @__PURE__ */ new Map();
9184
+ for (const decision of decisions) {
9185
+ if (decision.type !== "includeStrategy" || decision.choice !== "join") {
9186
+ continue;
9187
+ }
9188
+ const includeResult = this.compileIncludeViaHandler(decision, plan);
9189
+ includeResults.set(decision, includeResult);
9190
+ this.registerIncludeCompilationResult(includeResult);
9191
+ }
9192
+ return includeResults;
9193
+ }
9149
9194
  /**
9150
9195
  * Fold a WHERE-family decision into an existing where expression.
9151
9196
  * Returns the updated (or new) where node.
@@ -9279,6 +9324,14 @@ var PlanCompiler = class _PlanCompiler {
9279
9324
  }
9280
9325
  return where;
9281
9326
  }
9327
+ reserveManualJoinAliases(decisions) {
9328
+ for (const decision of decisions) {
9329
+ if (decision.type !== "join") continue;
9330
+ const alias = decision.alias ?? decision.targetTable;
9331
+ if (!alias) continue;
9332
+ this.usedJoinAliases.add(this.emittedJoinAlias(alias));
9333
+ }
9334
+ }
9282
9335
  /**
9283
9336
  * Apply a single join decision to the FROM clause in-place.
9284
9337
  * Chains multiple joins by wrapping from[0] as the left-arg each time.
@@ -9343,14 +9396,11 @@ var PlanCompiler = class _PlanCompiler {
9343
9396
  */
9344
9397
  compileGroupByDecision(decision) {
9345
9398
  const gbCol = decision.column;
9346
- const gbDot = gbCol.indexOf(".");
9399
+ const gbDot = gbCol.lastIndexOf(".");
9347
9400
  if (gbDot !== -1) {
9348
- return columnRef(
9349
- gbCol.slice(gbDot + 1),
9350
- gbCol.slice(0, gbDot),
9351
- void 0,
9352
- this.naming
9353
- );
9401
+ const relation = gbCol.slice(0, gbDot);
9402
+ const alias = this.resolvedJoinAliases().get(relation) ?? relation;
9403
+ return columnRef(gbCol.slice(gbDot + 1), alias, void 0, this.naming);
9354
9404
  }
9355
9405
  return columnRef(gbCol, decision.table, void 0, this.naming);
9356
9406
  }
@@ -9400,10 +9450,17 @@ var PlanCompiler = class _PlanCompiler {
9400
9450
  plan.decisions,
9401
9451
  plan.rootTable
9402
9452
  );
9453
+ this.reserveManualJoinAliases(decisions);
9454
+ const includeJoinResults = this.compileJoinIncludeAllocationPass(
9455
+ decisions,
9456
+ plan
9457
+ );
9458
+ this.state.aliases = this.resolvedJoinAliases();
9403
9459
  const targetList = [];
9404
9460
  const from = this.compileFromClause(plan);
9405
9461
  let where;
9406
9462
  const orderBy = [];
9463
+ const orderByDecisions = [];
9407
9464
  const groupBy = [];
9408
9465
  let having;
9409
9466
  let limit;
@@ -9423,7 +9480,12 @@ var PlanCompiler = class _PlanCompiler {
9423
9480
  this.compileSelectTarget(decision, plan, targetList);
9424
9481
  break;
9425
9482
  case "includeStrategy":
9426
- this.compileIncludeDecision(decision, plan, targetList);
9483
+ this.compileIncludeDecision(
9484
+ decision,
9485
+ plan,
9486
+ targetList,
9487
+ includeJoinResults.get(decision)
9488
+ );
9427
9489
  where = this.compileIncludeWhereConditions(decision, where);
9428
9490
  break;
9429
9491
  case "where":
@@ -9436,8 +9498,7 @@ var PlanCompiler = class _PlanCompiler {
9436
9498
  this.compileJoinDecision(decision, plan, from);
9437
9499
  break;
9438
9500
  case "orderBy": {
9439
- const obNode = this.compileOrderByDecision(decision, plan);
9440
- if (obNode) orderBy.push(obNode);
9501
+ orderByDecisions.push(decision);
9441
9502
  break;
9442
9503
  }
9443
9504
  case "groupBy":
@@ -9484,6 +9545,10 @@ var PlanCompiler = class _PlanCompiler {
9484
9545
  break;
9485
9546
  }
9486
9547
  }
9548
+ for (const decision of orderByDecisions) {
9549
+ const obNode = this.compileOrderByDecision(decision, plan);
9550
+ if (obNode) orderBy.push(obNode);
9551
+ }
9487
9552
  this.flushPendingJoins(from, plan);
9488
9553
  return this.buildSelectStmt(
9489
9554
  targetList,