fix(infer/emit): drop dangling cross-schema relations + emit enum input literals (#783, #788; verify #784/#785)#797
fix(infer/emit): drop dangling cross-schema relations + emit enum input literals (#783, #788; verify #784/#785)#797wmadden-electric wants to merge 3 commits into
Conversation
…rred tables `contract infer` emitted a relation navigation field for every foreign key, even when the referenced table was not part of the inferred schema — e.g. a Supabase `public` → `auth.users` FK with the `auth` schema excluded. That produced `users users @relation(...)` with no `model users`, so `contract emit` failed on the unresolved relation target. Skip relation inference for any FK whose `referencedTable` is absent from the inferred tables. The scalar FK column is preserved (it comes from the column walk); only the dangling navigation field and its back-relation are omitted. Closes #783 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Will Madden <madden@prisma.io>
…for #785) #785 reported boolean `@default(true/false)` from infer not lowering into contract.json on v0.12. It no longer reproduces on v0.13: the interpreter lowers boolean literals to `{ kind: 'literal', value: true|false }` on the storage contract, the infer side emits the PSL attribute, and the Postgres planner renders boolean literal defaults. This adds a regression test pinning the interpreter behavior so it can't silently regress. Closes #785 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Will Madden <madden@prisma.io>
… output `FieldOutputTypes` for an enum column resolved to the precise literal member union (via the codec's `renderOutputType`), but `FieldInputTypes` always fell back to `CodecTypes['pg/enum@1']['input']` (effectively `string`). Create/update call sites therefore weren't exhaustiveness-checked against enum members. Add a symmetric input renderer: - `CodecDescriptor.renderInputType?(params)` (optional) and a matching `CodecLookup.renderInputTypeFor?(id, params)` (optional, so existing lookups need no change). The control stack builds the input-renderer map alongside the output one. - `domain-type-generation`'s `resolveFieldType` renders the input position via `renderInputTypeFor` when present, mirroring the output path; absent renderers keep the `CodecTypes[...]['input']` fallback. - `PgEnumDescriptor.renderInputType` returns the same literal union as its output renderer, since enum writes accept the same members as reads. Only enum opts in; every other codec falls back unchanged. Closes #788 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Will Madden <madden@prisma.io>
|
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 (10)
📝 WalkthroughWalkthroughThis PR extends the codec system to support custom input type rendering for TypeScript type generation, integrates that capability into domain type emission, implements it for PostgreSQL enum codecs, and includes fixes for relation inference with missing tables and boolean literal defaults in PSL contracts. ChangesInput type rendering and PSL contract fixes
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
@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/emitter
@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: |
size-limit report 📦
|
Batches the rest of the Supabase brownfield
infer → emitcluster (A + B + C). Two are live bugs fixed here; two were v0.12 reports already resolved on v0.13 and are pinned/verified.#783 — relation fields to un-inferred tables (fixed)
inferemitted a relation navigation field for every FK, even when the referenced table wasn't inferred — e.g. a Supabasepublic→auth.usersFK with theauthschema excluded. That producedusers users @relation(...)with nomodel users, socontract emitfailed on the unresolved target.inferRelationsnow skips FKs whosereferencedTableis absent from the inferred tables, keeping the scalar FK column and dropping only the dangling navigation field + back-relation. (Design choice: omit the nav field, don't fabricate a stub model.)#788 — enum input types widened to
string(fixed)FieldOutputTypesfor an enum resolved to the literal member union, butFieldInputTypesfell back toCodecTypes['pg/enum@1']['input'](≈string), so create/update weren't exhaustiveness-checked. Added a symmetric input renderer: optionalCodecDescriptor.renderInputType+ optionalCodecLookup.renderInputTypeFor(existing lookups unchanged), wired through the control stack andresolveFieldType.PgEnumDescriptor.renderInputTypereturns the same literal union as its output renderer. Only enum opts in; every other codec falls back unchanged.#785 — boolean defaults not lowered (already fixed on v0.12 → v0.13)
Does not reproduce on v0.13: the interpreter lowers
@default(true/false)to{ kind: 'literal', value: true|false }, infer emits the PSL attribute, and the Postgres planner renders boolean literal defaults. Added a regression test pinning the interpreter behavior.#784 —
types{}alias typeParams break migration plan (already fixed on v0.12 → v0.13)Does not reproduce on v0.13. The named-type subsystem now lowers aliases correctly:
Slug = String @db.VarChar(191)keepstypeParams: { length: 191 }on thestorage.typesentry and the field references it viatypeRef(the planner resolves params from there);AccountId = String @db.Uuidlowers tonativeType: 'uuid'with no params (uuid has none), which is what the planner needs. This is asserted by the existinginterpreter.types.test.tsand the committedpgvector-named-typeparity golden, and the named-type → schema-IR plan path is covered by the pgvector planner tests.Tests / checks
Failing-first tests for #783 and #788; regression test for #785. Full suites pass:
family-sql(368),sql-contract-psl(229),framework-components(396),emitter(171),sql-emitter(101),target-postgres(279). Lint, typecheck, andlint:depsclean.Independent of #791 (the enum storage-coordinate refactor); branched off
main.Closes #783
Closes #784
Closes #785
Closes #788
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes