Skip to content

fix: fix accidental query plan mutation#29262

Merged
jacek-prisma merged 6 commits intomainfrom
fix/fix-query-plan-mutation
Feb 27, 2026
Merged

fix: fix accidental query plan mutation#29262
jacek-prisma merged 6 commits intomainfrom
fix/fix-query-plan-mutation

Conversation

@jacek-prisma
Copy link
Copy Markdown
Contributor

@jacek-prisma jacek-prisma commented Feb 26, 2026

TML-1946

Fixes a bug where the query interpreter would unintentionally mutate the query plan. I've marked all of the query plan bits as readonly in the query interpreter to prevent similar issues.

Fixes #29254

Summary by CodeRabbit

  • Tests

    • Added functional tests, a test matrix and a dynamic schema to cover query-plan cache mutation and paging scenarios.
  • Refactor

    • Enforced immutability across the query runtime and rendering pipeline by using DeepReadonly/DeepUnreadonly and safer cloning where needed.
    • Introduced deep readonly/unreadonly type utilities.
  • Bug Fixes

    • Made parameter and field collections readonly in public signatures to prevent accidental mutations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5586903 and 8eac6d9.

📒 Files selected for processing (3)
  • packages/client-engine-runtime/src/interpreter/in-memory-processing.ts
  • packages/client-engine-runtime/src/interpreter/query-interpreter.ts
  • packages/client-engine-runtime/src/interpreter/validation.ts

Walkthrough

Applied recursive DeepReadonly/DeepUnreadonly types across client-engine-runtime, tightened multiple public/internal function signatures to accept readonly inputs, added cloneObject(), adjusted array mutability for params/fields, and added a functional test suite reproducing query-plan cache mutation (cursor pagination) behavior.

Changes

Cohort / File(s) Summary
Type utilities
packages/client-engine-runtime/src/utils.ts
Added DeepReadonly<T> and DeepUnreadonly<T> type utilities.
Events
packages/client-engine-runtime/src/events.ts
QueryEvent.params changed from unknown[] to readonly unknown[].
Interpreter: core & helpers
packages/client-engine-runtime/src/interpreter/query-interpreter.ts, packages/client-engine-runtime/src/interpreter/in-memory-processing.ts
Many interpreter signatures tightened to accept DeepReadonly<...>; run, interpretNode, and other internals updated; added cloneObject<T>(); getRecordKey() now accepts readonly string[].
Query rendering
packages/client-engine-runtime/src/interpreter/render-query.ts
Render and fragment helper APIs now accept/return DeepReadonly types and readonly parameter arrays (e.g., renderQuery, renderRawSql, pairFragmentsWithParams).
Validation & tracing
packages/client-engine-runtime/src/interpreter/validation.ts, packages/client-engine-runtime/src/tracing.ts
performValidation() and withQuerySpanAndEvent() signatures updated to accept DeepReadonly variants; added DeepReadonly imports.
Functional tests: query-plan cache mutation
packages/client/tests/functional/issues/29254-query-plan-cache-mutation/_matrix.ts, packages/client/tests/functional/issues/29254-query-plan-cache-mutation/prisma/_schema.ts, packages/client/tests/functional/issues/29254-query-plan-cache-mutation/tests.ts
Added test matrix, dynamic Prisma schema generator, and tests that exercise sequential cursor pagination to detect query-plan cache mutation regressions.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: fix accidental query plan mutation' directly and clearly describes the main change: preventing unintended mutations to query plans via readonly type constraints.
Linked Issues check ✅ Passed All code requirements from issue #29254 are met: query plan integrity protection via DeepReadonly/DeepUnreadonly types prevents mutation, per-request cursor parameters are preserved, and a regression test with the failing scenario is included.
Out of Scope Changes check ✅ Passed All changes directly address the root cause (query plan mutations) and requirements: type safety enhancements, immutability utilities, and regression test suite are all within scope of fixing accidental query plan mutation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/fix-query-plan-mutation

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 and usage tips.

@jacek-prisma jacek-prisma force-pushed the fix/fix-query-plan-mutation branch from a0d8e5a to c808dd5 Compare February 26, 2026 18:06
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 76bb95b and c808dd5.

📒 Files selected for processing (10)
  • packages/client-engine-runtime/src/events.ts
  • packages/client-engine-runtime/src/interpreter/in-memory-processing.ts
  • packages/client-engine-runtime/src/interpreter/query-interpreter.ts
  • packages/client-engine-runtime/src/interpreter/render-query.ts
  • packages/client-engine-runtime/src/interpreter/validation.ts
  • packages/client-engine-runtime/src/tracing.ts
  • packages/client-engine-runtime/src/utils.ts
  • packages/client/tests/functional/issues/29254-query-plan-cache-mutation/_matrix.ts
  • packages/client/tests/functional/issues/29254-query-plan-cache-mutation/prisma/_schema.ts
  • packages/client/tests/functional/issues/29254-query-plan-cache-mutation/tests.ts

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Feb 26, 2026

size-limit report 📦

Path Size
packages/client/runtime/index-browser.js 2.23 KB (0%)
packages/client/runtime/index-browser.d.ts 3.28 KB (0%)
packages/cli/build/index.js 2.5 MB (0%)
packages/client/prisma-client-0.0.0.tgz 26.81 MB (+0.01% 🔺)
packages/cli/prisma-0.0.0.tgz 12.84 MB (0%)
packages/bundle-size/da-workers-libsql/output.tgz 1.33 MB (+0.01% 🔺)
packages/bundle-size/da-workers-neon/output.tgz 1.39 MB (+0.01% 🔺)
packages/bundle-size/da-workers-pg/output.tgz 1.38 MB (+0.01% 🔺)
packages/bundle-size/da-workers-planetscale/output.tgz 1.33 MB (+0.01% 🔺)
packages/bundle-size/da-workers-d1/output.tgz 1.3 MB (+0.01% 🔺)

@jacek-prisma jacek-prisma requested a review from aqrln February 27, 2026 11:48
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a943513 and 5586903.

📒 Files selected for processing (1)
  • packages/client-engine-runtime/src/utils.ts

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Feb 27, 2026
@jacek-prisma jacek-prisma merged commit 6586972 into main Feb 27, 2026
250 of 252 checks passed
@jacek-prisma jacek-prisma deleted the fix/fix-query-plan-mutation branch February 27, 2026 14:00
jacek-prisma added a commit that referenced this pull request Feb 27, 2026
[TML-1946](https://linear.app/prisma-company/issue/TML-1946/investigate-and-fix-null-cursor-regression)

Fixes a bug where the query interpreter would unintentionally mutate the
query plan. I've marked all of the query plan bits as readonly in the
query interpreter to prevent similar issues.

Fixes #29254

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Tests**
* Added functional tests, a test matrix and a dynamic schema to cover
query-plan cache mutation and paging scenarios.

* **Refactor**
* Enforced immutability across the query runtime and rendering pipeline
by using DeepReadonly/DeepUnreadonly and safer cloning where needed.
  * Introduced deep readonly/unreadonly type utilities.

* **Bug Fixes**
* Made parameter and field collections readonly in public signatures to
prevent accidental mutations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prisma 7.4 breaks cursor pagination when sorted by a nullable field

2 participants