add support for partial indexes based on the Prisma syntax#2622
add support for partial indexes based on the Prisma syntax#2622lsmith77 wants to merge 1 commit intozenstackhq:devfrom
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:
📝 WalkthroughWalkthroughAdds support for partial indexes/uniques: language model accepts an optional Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/sdk/src/prisma/prisma-schema-generator.ts (1)
351-380:⚠️ Potential issue | 🟠 MajorString literals passed as
wherewill produce invalid Prisma output.A user writing
@@index([id], where: "id > 0")reaches theisLiteralExprbranch (line 352) and is emitted aswhere: "id > 0". Prisma'swhereonly acceptsraw("…")or{ field: value }object literals, so a bare quoted string is a syntax error in the generated Prisma schema — even though the regression test intests/regression/test/prisma-schema-generator.test.ts(lines 6–22, 43–60) currently asserts this output is produced.Two reasonable options:
- Reject
String/non-object/non-raw()values onwhereat validation time, so the user is steered toraw("…").- Auto-wrap a string literal
wherevalue withraw(...)in the generator (e.g. producewhere: raw("id > 0")) so the emitted Prisma is valid.If string-shaped
whereis intentional for ZModel ergonomics, option 2 is the least surprising; otherwise option 1 keeps things explicit.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/sdk/src/prisma/prisma-schema-generator.ts` around lines 351 - 380, The generator currently emits raw string literals for attribute args (in makeAttributeArgValue) which produces invalid Prisma for a `where` arg; change makeAttributeArgValue to accept an optional argName (e.g. add parameter argName?: string) and when isLiteralExpr(node) && node.$type === StringLiteral && argName === 'where' return a PrismaAttributeArgValue('Raw', this.exprToText(node)) or construct a raw(...) FunctionCall equivalent instead of emitting a plain String; update all callers that create attribute args (where attribute parsing site(s)) to pass the arg name so the function can auto-wrap `where` string literals into Raw (or alternatively throw a validation error there if you prefer rejection).
🧹 Nitpick comments (1)
packages/language/res/stdlib.zmodel (1)
253-253: Document the newwhereparameter and broadenraw()expression context to include@@unique.Two small follow-ups for the new
where: Any?parameter on@@unique(line 253) and@@index(line 356):
- The JSDoc above each attribute (lines 244–252 and 345–355) doesn't describe the new
whereparameter. Adding a one-liner clarifying it's used for partial indexes (PrismapartialIndexespreview) and accepts eitherraw("SQL")or an object literal would help schema authors discover it.- The
raw()helper is declared with@@@expressionContext([Index])(line 634). Now thatwhereis also valid on@@unique,raw(...)used inside@@unique(..., where: raw("..."))is technically outside the declared expression context. Consider widening that context (e.g. introduce a newUniquecontext or reuseIndex) so language-level validation stays consistent.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/language/res/stdlib.zmodel` at line 253, Update the JSDoc for the @@unique and @@index attributes to document the new where: Any? parameter with a one-line description stating it is for partial indexes (Prisma partialIndexes preview) and accepts either raw("SQL") or an object literal; then broaden the raw() expression context declaration (the raw symbol/@@@expressionContext) to include Unique (or both Index and Unique) so raw(...) used inside @@unique(..., where: raw("...")) is recognized by the language-level validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/sdk/src/prisma/prisma-schema-generator.ts`:
- Around line 372-373: The generator currently neither adds previewFeatures =
["partialIndexes"] when index/constraint args use a where predicate nor properly
emits string literal predicates, so update generateDefaultGenerator to scan
index/unique definitions (where the code constructs @@index/@@unique and `@unique`
attributes) and if any PrismaAttributeArg with name "where" is present mark the
generator previewFeatures to include "partialIndexes"; additionally, change the
handling in exprToText/isLiteralExpr (the branch that returns
PrismaAttributeArgValue('Raw', this.exprToText(node)) and the branch emitting
bare quoted strings for literals) so that string literal `where` values are
either rejected with a clear validation error or automatically wrapped as
raw("...") (prefer wrapping to preserve compatibility), ensuring object
expressions remain emitted as before; reference the affected symbols:
generateDefaultGenerator, PrismaAttributeArgValue('Raw'), isLiteralExpr,
isObjectExpr, and exprToText.
In `@tests/e2e/orm/partial-index.e2e.test.ts`:
- Around line 1-21: This e2e test is brittle and redundant; remove this test
file (tests/e2e/orm/partial-index.e2e.test.ts) or rewrite it to use the
programmatic API: replace the execSync-based runGenerate()/npx invocation with a
call to loadSchema from `@zenstackhq/testtools` and invoke PrismaSchemaGenerator
directly (or the existing regression helper used in
tests/regression/test/prisma-schema-generator.test.ts), assert on the generated
schema string instead of reading/writing SCHEMA_FILE/GENERATED_PRISMA, and if
you must write files use a tmpdir or add cleanup in afterAll to avoid polluting
the source tree.
In `@tests/e2e/orm/schemas/partial-index/schema.zmodel`:
- Around line 1-13: The fixture is missing the generator preview feature for
partial indexes, so update the schema to include an explicit generator block
that sets previewFeatures = ["partialIndexes"] (so Prisma accepts the
model-level @@index and @@unique with where clauses); add this generator (using
the same generator name pattern produced by
PrismaSchemaGenerator.generateDefaultGenerator if you want parity) near the top
of the schema (above or below the datasource block) so the Post model's
@@index([title], where: { published: true }) and @@unique([title], where: {
published: true }) validate correctly.
In `@tests/regression/test/prisma-schema-generator.test.ts`:
- Around line 6-22: Tests currently expect the generator to emit bare quoted
string values for index `where`, which is invalid Prisma syntax; update the
PrismaSchemaGenerator so that when it encounters a string literal for an index
`where` it emits it wrapped in raw(...), e.g. `where: raw("...")`, and then
update the failing tests in
tests/regression/test/prisma-schema-generator.test.ts to assert for
`@@index([id], where: raw("id > 0"))` and `@@index([email], where: raw("email IS
NOT NULL"))` instead of the bare quoted strings; locate logic inside
PrismaSchemaGenerator.generate() that serializes index attributes and alter the
serializer for Index/@@index where-value handling to detect string nodes and
emit raw("...") accordingly.
---
Outside diff comments:
In `@packages/sdk/src/prisma/prisma-schema-generator.ts`:
- Around line 351-380: The generator currently emits raw string literals for
attribute args (in makeAttributeArgValue) which produces invalid Prisma for a
`where` arg; change makeAttributeArgValue to accept an optional argName (e.g.
add parameter argName?: string) and when isLiteralExpr(node) && node.$type ===
StringLiteral && argName === 'where' return a PrismaAttributeArgValue('Raw',
this.exprToText(node)) or construct a raw(...) FunctionCall equivalent instead
of emitting a plain String; update all callers that create attribute args (where
attribute parsing site(s)) to pass the arg name so the function can auto-wrap
`where` string literals into Raw (or alternatively throw a validation error
there if you prefer rejection).
---
Nitpick comments:
In `@packages/language/res/stdlib.zmodel`:
- Line 253: Update the JSDoc for the @@unique and @@index attributes to document
the new where: Any? parameter with a one-line description stating it is for
partial indexes (Prisma partialIndexes preview) and accepts either raw("SQL") or
an object literal; then broaden the raw() expression context declaration (the
raw symbol/@@@expressionContext) to include Unique (or both Index and Unique) so
raw(...) used inside @@unique(..., where: raw("...")) is recognized by the
language-level validation.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 008b5d0b-0d7c-4e01-bf01-577bd8d2229a
📒 Files selected for processing (6)
packages/language/res/stdlib.zmodelpackages/sdk/src/prisma/prisma-builder.tspackages/sdk/src/prisma/prisma-schema-generator.tstests/e2e/orm/partial-index.e2e.test.tstests/e2e/orm/schemas/partial-index/schema.zmodeltests/regression/test/prisma-schema-generator.test.ts
c641029 to
57d82e2
Compare
| * @param where: Filters rows included in the partial unique constraint; accepts a Prisma filter object or raw("SQL"). | ||
| */ | ||
| attribute @@unique(_ fields: FieldReference[], name: String?, map: String?, length: Int?, sort: SortOrder?, clustered: Boolean?) @@@prisma | ||
| attribute @@unique(_ fields: FieldReference[], name: String?, map: String?, length: Int?, sort: SortOrder?, clustered: Boolean?, where: Any?) @@@prisma |
There was a problem hiding this comment.
I guess there is no support for union types to be able to be more strict here.
57d82e2 to
87ea867
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (2)
packages/sdk/src/prisma/prisma-schema-generator.ts (1)
192-205:⚠️ Potential issue | 🟠 MajorApply
partialIndexesto explicit generator blocks too.This only updates the synthetic default client generator. Any schema that already declares
generator clientwill still misspreviewFeatures = ["partialIndexes"], so partial indexes remain broken there.Please reuse the same detection when serializing declared generators as well.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/sdk/src/prisma/prisma-schema-generator.ts` around lines 192 - 205, The partial-index detection (using partialIndexAttrs, zmodel.declarations and getAllAttributes) currently only pushes 'partialIndexes' into the synthetic previewFeatures array; update the code that serializes declared generator blocks (the generator serialization logic that writes each generator's previewFeatures) to reuse the same detection and add 'partialIndexes' to that generator's previewFeatures when applicable, merging/deduplicating with any existing previewFeatures value rather than replacing it so existing generator client blocks gain the flag as well.packages/language/res/stdlib.zmodel (1)
255-257:⚠️ Potential issue | 🟠 MajorConstrain the
whereparameter to valid Prisma forms and validate explicitly.The
where: Any?type annotation in@@unique(line 257) and@@index(line 361) admits expressions beyond what Prisma's partial index predicates accept. Current validation only rejects plain string literals, allowing expressions like arithmetic or boolean operations to pass validation and fail later during schema generation with a generic "Unsupported attribute argument expression type" error.Valid forms are object predicates (
{ published: true }) and raw SQL (raw("...")). Tighten the type annotation or add explicit validation to reject invalid expression types during schema analysis rather than codegen.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/language/res/stdlib.zmodel` around lines 255 - 257, The where parameter for the attribute definitions @@unique and @@index is currently typed as Any? (symbol: attribute @@unique(... where: Any?) and the @@index analog) which permits invalid expressions; update the model and analyzer to restrict accepted forms to either an object predicate or raw("SQL") by changing the type/annotation from Any? to a union of the allowed expression types (e.g., ObjectExpression | RawCall) and add explicit validation in the attribute parsing/analysis code (the @@unique/@@index attribute handler) to reject any other expression kinds (arithmetic, boolean ops, string literal without raw, etc.) with a clear error during schema analysis rather than deferring to codegen.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@packages/language/res/stdlib.zmodel`:
- Around line 255-257: The where parameter for the attribute definitions
@@unique and @@index is currently typed as Any? (symbol: attribute @@unique(...
where: Any?) and the @@index analog) which permits invalid expressions; update
the model and analyzer to restrict accepted forms to either an object predicate
or raw("SQL") by changing the type/annotation from Any? to a union of the
allowed expression types (e.g., ObjectExpression | RawCall) and add explicit
validation in the attribute parsing/analysis code (the @@unique/@@index
attribute handler) to reject any other expression kinds (arithmetic, boolean
ops, string literal without raw, etc.) with a clear error during schema analysis
rather than deferring to codegen.
In `@packages/sdk/src/prisma/prisma-schema-generator.ts`:
- Around line 192-205: The partial-index detection (using partialIndexAttrs,
zmodel.declarations and getAllAttributes) currently only pushes 'partialIndexes'
into the synthetic previewFeatures array; update the code that serializes
declared generator blocks (the generator serialization logic that writes each
generator's previewFeatures) to reuse the same detection and add
'partialIndexes' to that generator's previewFeatures when applicable,
merging/deduplicating with any existing previewFeatures value rather than
replacing it so existing generator client blocks gain the flag as well.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: eaa2cb4e-8cbc-4e13-ace6-2fe2b793a648
📒 Files selected for processing (7)
packages/language/res/stdlib.zmodelpackages/language/src/validators/attribute-application-validator.tspackages/sdk/src/prisma/prisma-builder.tspackages/sdk/src/prisma/prisma-schema-generator.tspackages/sdk/src/ts-schema-generator.tstests/e2e/orm/partial-index.e2e.test.tstests/regression/test/prisma-schema-generator.test.ts
✅ Files skipped from review due to trivial changes (1)
- tests/regression/test/prisma-schema-generator.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/language/src/validators/attribute-application-validator.ts
- tests/e2e/orm/partial-index.e2e.test.ts
87ea867 to
ef76539
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
packages/sdk/src/prisma/prisma-schema-generator.ts (1)
169-207: Extract the partial-index preview-feature merge.Both generator paths now duplicate the same
partialIndexesdetection/update logic. A small helper would keep the JSON parsing and append behavior in one place and reduce drift.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/sdk/src/prisma/prisma-schema-generator.ts` around lines 169 - 207, Extract the duplicated logic that ensures the 'partialIndexes' preview feature is present into a single helper (e.g., addPartialIndexPreviewFeature) and call it from both locations: the generator-creation block that builds gen via prisma.addGenerator(...) and the generateDefaultGenerator method after building the previewFeatures array; the helper should detect/merge into an existing 'previewFeatures' JSON field on a Generator (updating parsed array and re-stringifying) or accept the previewFeatures array and push 'partialIndexes' if missing, and reuse the existing hasPartialIndex() check to decide when to invoke it.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/language/res/stdlib.zmodel`:
- Around line 638-639: The stdlib declares raw(...) supports ExpressionContext
Unique, but the language layer is missing it; add a Unique member to the
ExpressionContext enum in packages/language/src/constants.ts and update the
mapping in packages/language/src/validators/function-invocation-validator.ts to
map the @@unique directive to ExpressionContext.Unique (in the same style as the
existing @@index -> ExpressionContext.Index mapping) so functions used inside
@@unique constraints are accepted; ensure any related switch/validation logic
that inspects ExpressionContext also recognizes the new Unique value.
In `@packages/language/src/validators/attribute-application-validator.ts`:
- Around line 313-318: The validator currently only rejects string literals for
the `where` attribute but allows other invalid shapes (numbers, booleans, null,
etc.); update the check in the block that grabs whereArg (using
getAttributeArg(attr, 'where')) to only accept object literal filter shapes or a
raw(...) call: i.e., replace the isStringLiteral check with logic that verifies
whereArg is either an ObjectLiteralExpression (the filter object) or a
CallExpression whose callee is the identifier "raw" with a single string arg;
for any other node type call accept('error', "`where` expects a filter object or
raw(\"SQL\"), not a plain literal/expression", { node: whereArg }); keep
references to getAttributeArg, whereArg, isStringLiteral (remove/replace), and
accept to locate the code.
---
Nitpick comments:
In `@packages/sdk/src/prisma/prisma-schema-generator.ts`:
- Around line 169-207: Extract the duplicated logic that ensures the
'partialIndexes' preview feature is present into a single helper (e.g.,
addPartialIndexPreviewFeature) and call it from both locations: the
generator-creation block that builds gen via prisma.addGenerator(...) and the
generateDefaultGenerator method after building the previewFeatures array; the
helper should detect/merge into an existing 'previewFeatures' JSON field on a
Generator (updating parsed array and re-stringifying) or accept the
previewFeatures array and push 'partialIndexes' if missing, and reuse the
existing hasPartialIndex() check to decide when to invoke it.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 0f07d0c1-0ee8-4c43-8e20-a31865c9aac3
📒 Files selected for processing (7)
packages/language/res/stdlib.zmodelpackages/language/src/validators/attribute-application-validator.tspackages/sdk/src/prisma/prisma-builder.tspackages/sdk/src/prisma/prisma-schema-generator.tspackages/sdk/src/ts-schema-generator.tstests/e2e/orm/partial-index.e2e.test.tstests/regression/test/prisma-schema-generator.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
- tests/e2e/orm/partial-index.e2e.test.ts
- packages/sdk/src/ts-schema-generator.ts
- tests/regression/test/prisma-schema-generator.test.ts
- packages/sdk/src/prisma/prisma-builder.ts
ef76539 to
0896bbd
Compare
0896bbd to
bcab5e0
Compare
https://www.prisma.io/docs/orm/prisma-schema/data-model/indexes#configuring-partial-indexes-with-where
fix #2621
I wasn't quite sure where to place the test.
Summary by CodeRabbit
New Features
@@indexand@@uniquenow accept an optionalwhereparameter (Prisma filter object or raw SQL)partialIndexessection automatically when partial constraints are presentBug Fixes / Validation
wheremust be a filter object or raw SQL; plain string literals are rejected with a validation errorTests