Skip to content

fix(policy): compact relation subquery aliases to avoid PostgreSQL identifier truncation - #2849

Merged
ymc9 merged 1 commit into
devfrom
fix/policy-self-relation-alias
Sep 22, 2026
Merged

ymc9 merged 1 commit into
devfrom
fix/policy-self-relation-alias

Conversation

@ymc9

@ymc9 ymc9 commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

Follow-up to #2845, addressing a CodeRabbit finding.

Relation subquery aliases in the policy expression transformer were built as ${field}$${counter} without the temp alias prefix, so the executor's existing TempAliasTransformer left them untouched. On PostgreSQL a relation field name of 62+ chars made every alias derived from it truncate to the same 63-byte identifier, producing table name ... specified more than once or, across nested subqueries, re-introducing the self-relation shadowing that #2845 fixed.

newRelationAlias now routes through QueryUtils.tmpAlias(), so the existing transformer compacts the aliases (or shortens only over-long ones when useCompactAliasNames is off). No new shortening scheme is introduced.

Tests

Added a PostgreSQL regression test in tests/e2e/orm/policy/self-relation.test.ts with a 70-char self many-to-many relation field and a nested collection predicate, run with useCompactAliasNames: false to exercise the length guard. It fails before this change with the truncation error and passes after.

Ran tests/e2e/orm/policy, tests/regression, and packages/orm suites on SQLite, plus policy plugin lint.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Prevented long relation aliases from being incorrectly truncated into identical identifiers in PostgreSQL queries.
    • Improved reliability for multi-hop self-relation filters involving lengthy field names.
  • Tests

    • Added coverage for long-name self-relations and two-hop predicates in PostgreSQL.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: zenstackhq/zenstack/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 6cf4adc6-d0de-43cd-a45a-e9ff2e8eba89

📥 Commits

Reviewing files that changed from the base of the PR and between 0efd7ae and 9040abf.

📒 Files selected for processing (2)
  • packages/plugins/policy/src/expression-transformer.ts
  • tests/e2e/orm/policy/self-relation.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/plugins/policy/src/expression-transformer.ts

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


📝 Walkthrough

Walkthrough

The policy transformer now marks generated relation aliases as temporary. New PostgreSQL end-to-end tests cover self-relations, nested predicates, tenant enforcement, many-to-many access, and long relation names.

Changes

Relation alias isolation

Layer / File(s) Summary
Temporary relation alias generation
packages/plugins/policy/src/expression-transformer.ts
newRelationAlias wraps generated aliases with QueryUtils.tmpAlias so the query executor can shorten long aliases.
Self-relation policy validation
tests/e2e/orm/policy/self-relation.test.ts
End-to-end tests cover tenant-bound self-relation reads and writes, nested predicates, multi-hop access, many-to-many relations, and long PostgreSQL identifiers.

Priority: ⬇️ Low

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

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 9040a

No concrete merge-blocking defect was identified in the changed alias handling or its regression coverage.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: compacting policy relation subquery aliases to prevent PostgreSQL identifier truncation and collisions.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

…et compacted

Relation aliases were built as `${field}$${counter}` without the temp alias
prefix, so the executor's `TempAliasTransformer` left them untouched. On
PostgreSQL a relation field name of 62+ chars made every alias derived
from it truncate to the same 63-byte identifier, producing either a
"table name specified more than once" error or, across nested subqueries,
the very self-relation shadowing this branch set out to fix.

Route the aliases through `QueryUtils.tmpAlias()` so the existing
transformer compacts them (or shortens them when they exceed the
identifier limit if `useCompactAliasNames` is off). Add a PostgreSQL
regression test with an over-long self many-to-many relation field.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ymc9 ymc9 changed the title fix(policy): alias relation subquery tables to prevent self-relation shadowing fix(policy): compact relation subquery aliases to avoid PostgreSQL identifier truncation Sep 22, 2026
@ymc9
ymc9 force-pushed the fix/policy-self-relation-alias branch from 0efd7ae to 9040abf Compare September 22, 2026 20:50
@ymc9
ymc9 merged commit 38840d3 into dev Sep 22, 2026
8 checks passed
@ymc9
ymc9 deleted the fix/policy-self-relation-alias branch September 22, 2026 21:21
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.

1 participant