Skip to content

fix(postgres-adapter): keep table alias on UPDATE and DELETE - #30217

Closed
lazerg wants to merge 2 commits into
prisma:mainfrom
lazerg:fix/issue-30211-update-alias
Closed

fix(postgres-adapter): keep table alias on UPDATE and DELETE#30217
lazerg wants to merge 2 commits into
prisma:mainfrom
lazerg:fix/issue-30211-update-alias

Conversation

@lazerg

@lazerg lazerg commented Sep 6, 2026

Copy link
Copy Markdown

Linked issue

Fixes #30211

Summary

The Postgres renderer qualified an UPDATE/DELETE target through qualifyTableFromNamespaceCoordinate directly, which only resolves the bare table name and ignores TableSource.alias. SELECT already went through renderTableSource, which appends AS alias when present, so an aliased UPDATE or DELETE rendered a WHERE/RETURNING clause referencing the alias against a FROM target that never declared it, and Postgres rejected the statement. Both statements now render through renderTableSource so the target keeps its alias.

Follow-up (self-review): the renderer-level fix alone didn't cover the query builder path. UpdateQueryImpl/DeleteQueryImpl in sql-builder always built their RETURNING projection from the table's physical name, not from TableSource.alias. An aliased UPDATE/DELETE built via .as('p').update(...).returning(...) (not just the raw-AST path from the issue's repro) still produced RETURNING "table"."col" against a FROM "table" AS "p" target — the same class of Postgres error. Added a small returningTableRef() helper so RETURNING prefers the alias when present, with regression tests in builders.test.ts (verified fail-then-pass). INSERT was left unchanged in both passes: it never renders a target alias (its ON CONFLICT ... excluded semantics don't need one), so there was nothing for its RETURNING to get wrong.

Testing performed

  • pnpm --filter @internal/adapter-postgres test (added a case asserting UPDATE "post" AS "p" ... and DELETE FROM "post" AS "p" ... with realistic literals and RETURNING on both statements; fails against the pre-fix code with the alias silently dropped, passes after)
  • pnpm --filter @internal/sql-builder test (added builder-level regression tests asserting RETURNING projections use the alias, not the table name, for both UPDATE and DELETE; verified fail-then-pass)
  • pnpm test:packages (full suite): 15715 passed, 3 expected fail, 3 skipped; one unrelated pnpm pack/module-identity environment flake, reproduced identically on pristine main
  • pnpm typecheck && pnpm lint

Skill update

n/a — internal only

Checklist

  • All commits are signed off (git commit -s)
  • Read CONTRIBUTING.md; scoped to one logical concern
  • Tests are updated
  • PR title is in conventional-commit form
  • Skill update section filled in

Summary by CodeRabbit

  • Bug Fixes

    • PostgreSQL UPDATE and DELETE statements now correctly preserve explicit table aliases in generated SQL.
    • RETURNING clauses now reference the correct table alias when one is provided.
  • Tests

    • Added coverage for aliased UPDATE and DELETE statements, including RETURNING clauses.

Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com>
@lazerg
lazerg requested a review from a team as a code owner September 6, 2026 18:07
@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Team

Run ID: 3492114b-1074-4f10-a3d8-ff937c7c6a0a

📥 Commits

Reviewing files that changed from the base of the PR and between 3e91e1c and 5669c7f.

📒 Files selected for processing (3)
  • packages/2-sql/4-lanes/sql-builder/src/runtime/mutation-impl.ts
  • packages/2-sql/4-lanes/sql-builder/test/runtime/builders.test.ts
  • packages/3-targets/6-adapters/postgres/test/adapter.test.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 4 remain after this review.


📝 Walkthrough

Walkthrough

PostgreSQL mutation construction and rendering now preserve explicit table aliases for UPDATE and DELETE statements. RETURNING projections also use the alias. Tests cover generated SQL and aliased returned-column references.

Changes

PostgreSQL DML alias rendering

Layer / File(s) Summary
Mutation RETURNING alias resolution
packages/2-sql/4-lanes/sql-builder/src/runtime/mutation-impl.ts, packages/2-sql/4-lanes/sql-builder/test/runtime/builders.test.ts
UPDATE and DELETE RETURNING projections now use the source alias when available. Tests verify aliased returned-column references.
PostgreSQL DML target alias rendering
packages/3-targets/6-adapters/postgres/src/core/sql-renderer.ts, packages/3-targets/6-adapters/postgres/test/adapter.test.ts
renderUpdate and renderDelete now use renderTableSource, which includes explicit aliases. Tests verify aliased UPDATE and DELETE SQL with RETURNING clauses.

Estimated code review effort: 2 (Simple) | ~10 minutes

Merge Risk: ⚪ Minimal · up to 5669c

Aliased PostgreSQL UPDATE and DELETE statements now retain their target alias and use it in RETURNING projections, preventing invalid SQL references. The supplied coverage supports merge readiness.

Suggested reviewers: wmadden-electric

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes address issue [#30211] by preserving target aliases during PostgreSQL UPDATE and DELETE rendering and by using aliases in RETURNING projections. Regression tests cover aliased UPDATE and D…
Out of Scope Changes check ✅ Passed All production and test changes directly support aliased PostgreSQL UPDATE and DELETE lowering and consistent RETURNING references. No unrelated changes are present.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: preserving table aliases for PostgreSQL UPDATE and DELETE statements.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Review of prisma#30217 found the sql-renderer fix alone was incomplete: the
query builder's UpdateQueryImpl/DeleteQueryImpl always built RETURNING
projections from the table's physical name, ignoring an alias set via
.as(). An aliased UPDATE/DELETE built through the fluent builder (not
just the raw AST path from the original issue) still produced RETURNING
"table"."col" against a FROM target rendered as "table" AS "alias",
which Postgres rejects the same way as the original bug.

Adds a small returningTableRef() helper so RETURNING prefers the alias
when present, and regression tests in builders.test.ts confirming it
(verified fail-then-pass against the pre-fix code). Also tightens the
adapter.test.ts regression test added for the original fix: realistic
literal values instead of placeholder strings, and RETURNING added to
the DELETE case so it exercises the same alias path as UPDATE.

Signed-off-by: Lazizbek Ergashev <lazerg2@gmail.com>
@pkg-pr-new

pkg-pr-new Bot commented Sep 7, 2026

Copy link
Copy Markdown

Open in StackBlitz

@prisma/orm-extension-arktype-json

npm i https://pkg.pr.new/@prisma/orm-extension-arktype-json@30217

@prisma/orm-extension-middleware-cache

npm i https://pkg.pr.new/@prisma/orm-extension-middleware-cache@30217

@prisma/orm-extension-paradedb

npm i https://pkg.pr.new/@prisma/orm-extension-paradedb@30217

@prisma/orm-extension-pgvector

npm i https://pkg.pr.new/@prisma/orm-extension-pgvector@30217

@prisma/orm-extension-postgis

npm i https://pkg.pr.new/@prisma/orm-extension-postgis@30217

@prisma/orm-extension-supabase

npm i https://pkg.pr.new/@prisma/orm-extension-supabase@30217

@prisma/orm-family-mongo

npm i https://pkg.pr.new/@prisma/orm-family-mongo@30217

@prisma/orm-family-sql

npm i https://pkg.pr.new/@prisma/orm-family-sql@30217

@prisma/orm-framework

npm i https://pkg.pr.new/@prisma/orm-framework@30217

@prisma/orm-mongo

npm i https://pkg.pr.new/@prisma/orm-mongo@30217

@prisma/orm-postgres

npm i https://pkg.pr.new/@prisma/orm-postgres@30217

@prisma/orm-sqlite

npm i https://pkg.pr.new/@prisma/orm-sqlite@30217

@prisma/orm-target-mongo

npm i https://pkg.pr.new/@prisma/orm-target-mongo@30217

@prisma/orm-target-postgres

npm i https://pkg.pr.new/@prisma/orm-target-postgres@30217

@prisma/orm-target-sqlite

npm i https://pkg.pr.new/@prisma/orm-target-sqlite@30217

@prisma/orm-toolchain

npm i https://pkg.pr.new/@prisma/orm-toolchain@30217

commit: 5669c7f

@lazerg

lazerg commented Sep 10, 2026

Copy link
Copy Markdown
Author

Closing this. The linked issue (#30211) got closed as not planned for the same reason as the rest of this batch: the reporter said these Codex-found reproductions might not hold up.

@lazerg lazerg closed this Sep 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PostgreSQL UPDATE lowering drops the public AST target alias

2 participants