TML-2783: Restrict MTI results to explicitly selected fields#984
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
💤 Files with no reviewable changes (1)
📝 WalkthroughWalkthroughPolymorphic SQL planning now limits MTI projections to selected fields, carries hidden discriminator aliases through distinct and nested queries, and maps aliased discriminators at runtime. Tests cover query plans, row mapping, dispatch, integration behavior, and upgrade documentation. ChangesPolymorphic projection selection
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
1e510bc to
0874b7e
Compare
size-limit report 📦
|
@prisma-next/extension-author-tools
@prisma-next/mongo-runtime
@prisma-next/family-mongo
@prisma-next/sql-runtime
@prisma-next/family-sql
@prisma-next/extension-arktype-json
@prisma-next/middleware-cache
@prisma-next/mongo
@prisma-next/extension-paradedb
@prisma-next/extension-pgvector
@prisma-next/extension-postgis
@prisma-next/postgres
@prisma-next/sql-orm-client
@prisma-next/sqlite
@prisma-next/extension-supabase
@prisma-next/target-mongo
@prisma-next/adapter-mongo
@prisma-next/driver-mongo
@prisma-next/contract
@prisma-next/utils
@prisma-next/config
@prisma-next/errors
@prisma-next/framework-components
@prisma-next/operations
@prisma-next/ts-render
@prisma-next/contract-authoring
@prisma-next/ids
@prisma-next/psl-parser
@prisma-next/psl-printer
@prisma-next/cli
@prisma-next/cli-telemetry
@prisma-next/config-loader
@prisma-next/emitter
@prisma-next/language-server
@prisma-next/migration-tools
prisma-next
@prisma-next/vite-plugin-contract-emit
@prisma-next/mongo-codec
@prisma-next/mongo-contract
@prisma-next/mongo-value
@prisma-next/mongo-contract-psl
@prisma-next/mongo-contract-ts
@prisma-next/mongo-emitter
@prisma-next/mongo-schema-ir
@prisma-next/mongo-query-ast
@prisma-next/mongo-orm
@prisma-next/mongo-query-builder
@prisma-next/mongo-lowering
@prisma-next/mongo-wire
@prisma-next/sql-contract
@prisma-next/sql-errors
@prisma-next/sql-operations
@prisma-next/sql-schema-ir
@prisma-next/sql-contract-psl
@prisma-next/sql-contract-ts
@prisma-next/sql-contract-emitter
@prisma-next/sql-lane-query-builder
@prisma-next/sql-relational-core
@prisma-next/sql-builder
@prisma-next/target-postgres
@prisma-next/target-sqlite
@prisma-next/adapter-postgres
@prisma-next/adapter-sqlite
@prisma-next/driver-postgres
@prisma-next/driver-sqlite
commit: |
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
0abafe3 to
af12c00
Compare
Signed-off-by: Alexey Orlenko's AI Agent <robot@aqrln.net>
Linked issue
Refs TML-2783
Prerequisite PR (merged): #976 / TML-2980
At a glance
Previously, multi-table inheritance (MTI) columns were projected regardless of the child selection, so unselected variant fields could appear in these task objects.
Decision
This PR ships selection-aware MTI result shaping for both root polymorphic queries and correlated includes: explicit
.select(...)controls visible base, STI, and MTI fields; selected MTI fields appear only on matching variants; omitted selection keeps the existing full default shape; and SQL-only joins, discriminators, and relation keys remain available internally wherever query execution needs them.Notes for the reviewer
query-plan-select.ts: the key distinction is between columns visible because the user selected them and columns carried only for execution or mapping. Selection narrows projection, not MTI join availability.__prisma_polymorphic_discriminatoralias is deliberate when an MTI field is selected withouttype.mapPolymorphicRow()uses it to choose the variant, then drops it because it has no model-field mapping.variant-include.collection-dispatch.test.tsproves the nestedassigneestill maps while unselected MTI scalar and relation-key fields stay out of the result.variant-include.query-plan-nested.test.ts.acquireRuntimeScope()edit is convert-on-touch cast cleanup with no intended behavior change; existing direct/scoped release tests cover it. The first post-rebase integration typecheck failure was stale workspace linking aftermainadded dependencies;pnpm install --frozen-lockfilechanged no tracked or lockfile content, and the exact typecheck then passed.Summary
SQL ORM explicit selection already restricted base-table fields, but MTI variant-table fields were projected unconditionally and could leak into root and include result shapes. This change makes the projection contract consistent across inheritance storage while preserving the joined data needed for query semantics and variant mapping.
How it fits together
resolvePolymorphicProjectionSelection()resolves selected domain fields and storage columns into a base/STI list plus a per-MTI-table column set.selectedFields === undefinedremains the signal for the complete implicit projection.buildMtiJoins()and the root compilers keep the required left or inner joins while adding only selected MTI columns to the visible projection. The same partition feeds ordinary root queries, roots with includes, and correlated include children.buildHiddenDiscriminatorProjection()adds a private alias andmapPolymorphicRow()consumes it without exposing it.buildDistinctNonLeafChildRowsSelect()separates the inner query projection from the outer visible projection. Selected fields, private mapping data, and MTI-local nested-relation keys cross only the SQL scope boundaries that need them; the outer JSON/result shape follows the original selection.Behavior changes & evidence
priorityappears only on matching Feature rows. The planner partition and root/include wiring live inquery-plan-select.tsandquery-plan-select.ts; exact PGlite result arrays are asserted for includes and root collections..select(...)preserves the complete polymorphic default: base, STI, and matching MTI fields still map as before. Planner evidence covers root implicit versus explicit projections and correlated includes; the PGlite controls assert the unchanged implicit include shape and implicit root shape.collection-runtime.ts, with focused evidence incollection-runtime.test.tsand whole-result evidence in the include MTI-field case.buildMtiJoins(), while required wrapper-local keys are assembled inquery-plan-select.tsandquery-plan-select.ts. Evidence covers variant-field filtering with no leakedpriority, variant-declared relation dispatch, and distinct/composite M:N boundaries.Compatibility / migration / risk
Explicit selections on polymorphic roots and includes intentionally return fewer fields when MTI columns were not selected; queries without an explicit selection retain their previous full shape. MTI joins remain in the SQL plan because predicates, ordering, narrowing, nested relations, distinct wrappers, and M:N correlations can depend on them, while selected column lists become narrower. Internal discriminator and relation-key aliases are stripped before the user-visible result boundary. No public API, contract or emitted artifact, extension-authoring surface, adapter API, or downstream source translation changed, so no consumer migration is required.
Testing performed
pnpm --filter @prisma-next/sql-orm-client test— 61 files, 663 tests passedpnpm --filter @prisma-next/integration-tests test test/sql-orm-client/polymorphism-include.test.ts— pretest build 68/68 tasks passed; PGlite 9/9 tests passedpnpm --filter @prisma-next/sql-orm-client typecheckandpnpm --filter @prisma-next/integration-tests typecheck— passedpnpm --filter @prisma-next/sql-orm-client lintandpnpm --filter @prisma-next/integration-tests lint— passedpnpm lint:deps— 1,197 modules and 2,730 dependencies passedpnpm lint:casts— 934 casts versus 936 onorigin/main, delta-2pnpm fixtures:check— passedpnpm check:upgrade-coverage --mode pr— passedpnpm lint:skills— passedpnpm check:release-notes --mode pr— passedgit diff --check origin/main...HEAD— passedThese are local final-HEAD results; this draft does not claim that GitHub CI has run.
Skill update
The extension upgrade transition at
skills/extension-author/prisma-next-extension-upgrade/upgrades/0.15-to-0.16/recordschanges: []. This is an incidental internal SQL ORM projection fix with no extension-author SPI, contract shape, syntax, configuration, adapter API, or downstream source translation to migrate.Alternatives considered
Checklist
git commit -s) per the DCO. The DCO status check will block merge if any commit is missing aSigned-off-by:trailer.n/aif the change is doc-only / refactor with no behavioural delta).TML-NNNN: <sentence-case title>form (Linear ticket prefix + concise title naming the concrete deliverable). See.claude/skills/create-pr/SKILL.mdfor the full convention.n/a — internal only).Summary by CodeRabbit
distinctqueries.