Skip to content

merge dev to main (v3.4.5)#2462

Merged
ymc9 merged 9 commits into
mainfrom
dev
Mar 8, 2026
Merged

merge dev to main (v3.4.5)#2462
ymc9 merged 9 commits into
mainfrom
dev

Conversation

@ymc9
Copy link
Copy Markdown
Member

@ymc9 ymc9 commented Mar 8, 2026

Summary by CodeRabbit

  • New Features

    • Relation filters now use EXISTS-based checks.
    • More robust alias handling with automatic compaction and consistent transformation.
    • Improved delegate-origin detection for inherited/mixin fields.
  • Bug Fixes

    • Default-value handling in policy create operations fixed.
    • Improved nested relation filtering and query execution.
  • Tests

    • Added regression tests covering relation filters, deep nested includes, and batch insert edge cases.
  • Chores

    • Version bumps across packages to v3.4.5.

pkudinov and others added 8 commits March 5, 2026 22:04
Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
…elation filters (#2455)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Fields inherited via a mixin type on a delegate base model were not
getting their `originModel` set in the generated schema, causing the
ORM to include them in the wrong table's INSERT statement.

Introduces `getOwnedFields` and `getDelegateOriginModel` helpers in
`model-utils.ts` and uses them in both `ts-schema-generator` and
`prisma-schema-generator`, replacing the previous logic that only
checked `field.$container` directly.

Fixes #2351

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com>
The test was failing on MySQL because the dataType enum field was required
but not provided when creating DataText records. MySQL is stricter about
enum validation than SQLite, causing 'Data truncated for column' errors.

Co-authored-by: Yiming Cao <ymc9@users.noreply.github.com>
…names

- Change DataType enum from TEXT/NUMBER to DataText/DataNumber
- Remove explicit dataType field from test as it's auto-set by delegate discriminator
- Fixes MySQL test failure: delegate discriminators must use model names

Co-authored-by: Yiming Cao <ymc9@users.noreply.github.com>
)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

Claude finished @ymc9's task —— View job


Code Review for v3.4.5 Release PR ✅

This is a solid release that includes important bug fixes and performance improvements. Here's my comprehensive review:

Todo List:

  • Analyze version consistency across packages
  • Review core code changes in ORM package
  • Review SDK changes
  • Examine new regression tests
  • Check for potential bugs or security issues
  • Assess performance implications
  • Provide comprehensive feedback

Code Quality & Best Practices

Excellent: The code follows consistent patterns, proper error handling, and maintains good separation of concerns. Key observations:

  • TempAliasTransformer (temp-alias-transformer.ts:26-33): Proper input validation with clear error messages
  • BaseCrudDialect (base-dialect.ts:186-208): Clean filter building with proper null safety
  • PolicyHandler (policy-handler.ts:924-938): Robust handling of DefaultInsertValueNode with type checking

🔒 Security Considerations

Good: No security vulnerabilities identified. The changes maintain proper access controls:

  • Policy enforcement remains intact in delegate model handling
  • Input validation is properly maintained in the dialect transformations
  • No exposure of sensitive data or credentials in the codebase

Performance Improvements

Excellent: Several performance optimizations included:

  1. Temp Alias Compaction (temp-alias-transformer.ts:47-56): Smart alias compression that only compacts when needed, preventing PostgreSQL's 63-byte identifier limit issues
  2. MySQL JSON Equality (mysql.ts:264-270): Uses bi-directional JSON_CONTAINS for key-order insensitive JSON comparison
  3. EXISTS vs COUNT: Previous commits show optimization from COUNT to EXISTS subqueries for relation filters

🐛 Bug Fixes Reviewed

All regression tests are well-written and address real user issues:

Issue #2351 - Delegate Model Inheritance:

  • Problem: Query failures with delegate models using mixin abstract types
  • Fix: Enhanced getDelegateOriginModel function in model-utils.ts:93-102
  • Test Coverage: Comprehensive test with policy enforcement ✅

Issue #2424 - Deep Nested Includes:

  • Problem: PolicyPlugin failures with non-compact alias mode on complex nested queries
  • Fix: TempAliasTransformer improvements
  • Test Coverage: Real-world complex schema with 7 related models ✅

Issue #2440 - Relation Filtering:

  • Problem: some/none/every filters not working correctly
  • Fix: Logic improvements in relation filter building
  • Test Coverage: Multiple test cases for edge cases ✅

Issue #2460 - createManyAndReturn:

  • Problem: "Invariant failed: expecting a ValueNode" with asymmetric columns
  • Fix: Proper handling of DefaultInsertValueNode in policy handler
  • Test Coverage: Covers the exact failure scenario ✅

📦 Version Management

Perfect: All 38 packages consistently updated to v3.4.5 with no version drift.

🧪 Test Coverage

Excellent: The regression tests are comprehensive and test real-world scenarios:

  • Complex delegate inheritance patterns
  • Deep nested includes (5+ levels)
  • Edge cases in relation filtering
  • Asymmetric data insertion patterns

⚠️ Potential Concerns

Minor observations:

  1. TempAliasTransformer complexity: The two-mode approach (alwaysCompact vs compactLongNames) adds complexity but is well-documented
  2. MySQL JSON handling: The bi-directional JSON_CONTAINS approach is clever but could impact performance on large JSON objects

📋 Recommendations

  1. Documentation: Consider adding performance notes about the alias compaction modes for PostgreSQL users
  2. Monitoring: Track query performance impact of MySQL JSON equality changes
  3. Testing: The regression test coverage is exemplary - maintain this standard

🎯 Overall Assessment

APPROVED ✅ This is a high-quality release with:

  • ✅ No breaking changes
  • ✅ Significant bug fixes for delegate models and complex queries
  • ✅ Performance improvements
  • ✅ Excellent test coverage
  • ✅ Clean, well-structured code
  • ✅ Proper error handling and validation

The release is ready for production deployment.


@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3f26e1d6-0412-47e5-bca9-022df756f67a

📥 Commits

Reviewing files that changed from the base of the PR and between 2083244 and 5aaef62.

📒 Files selected for processing (1)
  • packages/sdk/src/model-utils.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/sdk/src/model-utils.ts

📝 Walkthrough

Walkthrough

Patch release 3.4.5: widespread package version bumps; ORM relation filters moved to EXISTS with MySQL override; temp-alias transformer adds byte-length based compacting; SDK adds delegate-origin utilities and updates generators; policy handler accepts default insert values; test client env tweak; four new regression tests.

Changes

Cohort / File(s) Summary
Version bumps
package.json, packages/*/package.json, samples/orm/package.json, tests/*/package.json, tests/runtimes/*/package.json
Updated package version fields from 3.4.4 → 3.4.5 across repository; no functional changes.
ORM dialects
packages/orm/src/client/crud/dialects/base-dialect.ts, packages/orm/src/client/crud/dialects/mysql.ts
Refactored relation existence checks to use EXISTS; added protected buildExistsExpression hook in base dialect and MySQL override that wraps inner query in a derived table.
Alias transformer
packages/orm/src/client/executor/temp-alias-transformer.ts
Constructor accepts options; added TextEncoder, mode, maxIdentifierLength; conditional compacting of TEMP aliases based on byte-length and mode, with mapping to short aliases.
Query executor & options
packages/orm/src/client/executor/zenstack-query-executor.ts, packages/orm/src/client/options.ts
processTempAlias now always runs transformer with explicit mode selection; updated doc for useCompactAliasNames describing $$tN format and fallback behavior.
SDK utilities & generators
packages/sdk/src/model-utils.ts, packages/sdk/src/prisma/prisma-schema-generator.ts, packages/sdk/src/ts-schema-generator.ts
Added getOwnedFields and getDelegateOriginModel; replaced local isInheritedFromDelegate checks with getDelegateOriginModel and simplified originModel population in generators.
Policy handler
packages/plugins/policy/src/policy-handler.ts, packages/plugins/policy/package.json
unwrapCreateValueRow now handles DefaultInsertValueNode by inserting a null ValueNode for default values; package version bumped.
Test tools
packages/testtools/src/client.ts, packages/testtools/package.json
createTestClient now passes an env object to Prisma push preserving process.env and adding PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION: 'true'; package version bumped.
Regression tests
tests/regression/test/issue-2351.test.ts, tests/regression/test/issue-2424.test.ts, tests/regression/test/issue-2440.test.ts, tests/regression/test/issue-2460.test.ts
Added four regression test files covering delegate mixin inheritance, deep nested includes with non-compact aliases, relation filters (some/none/every), and batch inserts with partial optional fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through code to nudge a tiny tune,
Versions climbed a notch beneath the silver moon,
EXISTS now peeks where counts once used to peep,
Short aliases hide where long names ran too deep,
Tests munch carrots so regressions sleep.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main objective: merging the dev branch to main with version bump to 3.4.5, which aligns with the extensive version updates across all package.json files and the functional changes.

✏️ 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 dev

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.

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: 1

🧹 Nitpick comments (2)
tests/regression/test/issue-2460.test.ts (1)

28-35: Assert the returned payload, not just the row count.

toHaveLength(2) proves the insert no longer throws, but it won't catch the asymmetric-column bug if values get shifted between rows. Please verify the returned key/note pairs too.

💡 Suggested test tightening
         const result = await db.$setAuth(user).item.createManyAndReturn({
             data: [
                 { key: 'a', note: 'hello' },
                 { key: 'b' },
             ],
         });

         expect(result).toHaveLength(2);
+        expect(result[0]).toMatchObject({ key: 'a', note: 'hello' });
+        expect(result[1].key).toBe('b');
+        expect(result[1].note ?? null).toBeNull();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/regression/test/issue-2460.test.ts` around lines 28 - 35, The test
currently only checks length via expect(result).toHaveLength(2) which won't
catch column-shift bugs; update the assertion after calling
db.$setAuth(user).item.createManyAndReturn to assert the returned array contents
exactly match the expected rows (e.g. verify each object's key and note fields
correspond to { key: 'a', note: 'hello' } and { key: 'b', note: null/undefined }
as appropriate). Locate the call site db.$setAuth(user).item.createManyAndReturn
and replace/augment the length assertion with strict checks on result[*].key and
result[*].note (or deep equality against the expected array) so any
asymmetric-column shifts fail the test.
tests/regression/test/issue-2440.test.ts (1)

22-118: Add one mutation case for the new EXISTS path.

These tests only exercise findMany, but the MySQL-specific change in this PR is there to make relation filters safe inside UPDATE/DELETE statements. A small updateMany or deleteMany assertion here would protect the path that changed most.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/regression/test/issue-2440.test.ts` around lines 22 - 118, Add a
mutation assertion that exercises the new EXISTS path by calling updateMany or
deleteMany with a relation filter (e.g., posts: { some: { value: { gt: 2 } } })
inside one of the tests (for example after the first 'some' test): perform
db.user.updateMany({ where: { posts: { some: { value: { gt: 2 } } } }, data: {
name: 'Updated' } }) (or deleteMany) and assert the returned count/affectedRows
and that the correct user (userA) was updated/deleted; refer to symbols
db.user.updateMany or db.user.deleteMany and the existing relation filters
(posts.some.value.gt) to locate where to add the mutation case.
🤖 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/model-utils.ts`:
- Around line 93-101: The function getDelegateOriginModel uses identity
comparison via getOwnedFields(base).includes(field), which fails for inherited
fields that are different AST instances; update the check to compare fields by a
stable identifier (e.g., field.name or another unique property) instead of
object identity. Specifically, inside getDelegateOriginModel replace the
includes(field) test with a predicate like getOwnedFields(base).some(f => f.name
=== field.name) (or use the appropriate unique key for DataField), so inherited
fields are correctly recognized as delegate-owned; keep the rest of the loop
logic unchanged.

---

Nitpick comments:
In `@tests/regression/test/issue-2440.test.ts`:
- Around line 22-118: Add a mutation assertion that exercises the new EXISTS
path by calling updateMany or deleteMany with a relation filter (e.g., posts: {
some: { value: { gt: 2 } } }) inside one of the tests (for example after the
first 'some' test): perform db.user.updateMany({ where: { posts: { some: {
value: { gt: 2 } } } }, data: { name: 'Updated' } }) (or deleteMany) and assert
the returned count/affectedRows and that the correct user (userA) was
updated/deleted; refer to symbols db.user.updateMany or db.user.deleteMany and
the existing relation filters (posts.some.value.gt) to locate where to add the
mutation case.

In `@tests/regression/test/issue-2460.test.ts`:
- Around line 28-35: The test currently only checks length via
expect(result).toHaveLength(2) which won't catch column-shift bugs; update the
assertion after calling db.$setAuth(user).item.createManyAndReturn to assert the
returned array contents exactly match the expected rows (e.g. verify each
object's key and note fields correspond to { key: 'a', note: 'hello' } and {
key: 'b', note: null/undefined } as appropriate). Locate the call site
db.$setAuth(user).item.createManyAndReturn and replace/augment the length
assertion with strict checks on result[*].key and result[*].note (or deep
equality against the expected array) so any asymmetric-column shifts fail the
test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cee9fd64-9150-4e21-9bd2-dd8c0bfea5a1

📥 Commits

Reviewing files that changed from the base of the PR and between 552b634 and 2083244.

📒 Files selected for processing (38)
  • package.json
  • packages/auth-adapters/better-auth/package.json
  • packages/cli/package.json
  • packages/clients/client-helpers/package.json
  • packages/clients/tanstack-query/package.json
  • packages/common-helpers/package.json
  • packages/config/eslint-config/package.json
  • packages/config/typescript-config/package.json
  • packages/config/vitest-config/package.json
  • packages/create-zenstack/package.json
  • packages/ide/vscode/package.json
  • packages/language/package.json
  • packages/orm/package.json
  • packages/orm/src/client/crud/dialects/base-dialect.ts
  • packages/orm/src/client/crud/dialects/mysql.ts
  • packages/orm/src/client/executor/temp-alias-transformer.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
  • packages/orm/src/client/options.ts
  • packages/plugins/policy/package.json
  • packages/plugins/policy/src/policy-handler.ts
  • packages/schema/package.json
  • packages/sdk/package.json
  • packages/sdk/src/model-utils.ts
  • packages/sdk/src/prisma/prisma-schema-generator.ts
  • packages/sdk/src/ts-schema-generator.ts
  • packages/server/package.json
  • packages/testtools/package.json
  • packages/testtools/src/client.ts
  • packages/zod/package.json
  • samples/orm/package.json
  • tests/e2e/package.json
  • tests/regression/package.json
  • tests/regression/test/issue-2351.test.ts
  • tests/regression/test/issue-2424.test.ts
  • tests/regression/test/issue-2440.test.ts
  • tests/regression/test/issue-2460.test.ts
  • tests/runtimes/bun/package.json
  • tests/runtimes/edge-runtime/package.json

Comment thread packages/sdk/src/model-utils.ts
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Mar 8, 2026

Claude finished @ymc9's task —— View job


Code Review for v3.4.5 Release PR ✅

This is a solid release that includes important bug fixes and performance improvements. Here's my comprehensive review:

Todo List:

  • Analyze version consistency across packages
  • Review core code changes in ORM package
  • Review SDK changes
  • Examine new regression tests
  • Check for potential bugs or security issues
  • Assess performance implications
  • Provide comprehensive feedback

Code Quality & Best Practices

Excellent: The code follows consistent patterns, proper error handling, and maintains good separation of concerns. Key observations:

  • TempAliasTransformer (temp-alias-transformer.ts:26-33): Proper input validation with clear error messages
  • BaseCrudDialect (base-dialect.ts:186-208): Clean filter building with proper null safety
  • PolicyHandler (policy-handler.ts:924-938): Robust handling of DefaultInsertValueNode with type checking

🔒 Security Considerations

Good: No security vulnerabilities identified. The changes maintain proper access controls:

  • Policy enforcement remains intact in delegate model handling
  • Input validation is properly maintained in the dialect transformations
  • No exposure of sensitive data or credentials in the codebase

Performance Improvements

Excellent: Several performance optimizations included:

  1. Temp Alias Compaction (temp-alias-transformer.ts:47-56): Smart alias compression that only compacts when needed, preventing PostgreSQL's 63-byte identifier limit issues
  2. MySQL JSON Equality (mysql.ts:264-270): Uses bi-directional JSON_CONTAINS for key-order insensitive JSON comparison
  3. EXISTS vs COUNT: Previous commits show optimization from COUNT to EXISTS subqueries for relation filters

🐛 Bug Fixes Reviewed

All regression tests are well-written and address real user issues:

Issue #2351 - Delegate Model Inheritance:

  • Problem: Query failures with delegate models using mixin abstract types
  • Fix: Enhanced getDelegateOriginModel function in model-utils.ts:93-102
  • Test Coverage: Comprehensive test with policy enforcement ✅

Issue #2424 - Deep Nested Includes:

  • Problem: PolicyPlugin failures with non-compact alias mode on complex nested queries
  • Fix: TempAliasTransformer improvements
  • Test Coverage: Real-world complex schema with 7 related models ✅

Issue #2440 - Relation Filtering:

  • Problem: some/none/every filters not working correctly
  • Fix: Logic improvements in relation filter building
  • Test Coverage: Multiple test cases for edge cases ✅

Issue #2460 - createManyAndReturn:

  • Problem: "Invariant failed: expecting a ValueNode" with asymmetric columns
  • Fix: Proper handling of DefaultInsertValueNode in policy handler
  • Test Coverage: Covers the exact failure scenario ✅

📦 Version Management

Perfect: All 38 packages consistently updated to v3.4.5 with no version drift.

🧪 Test Coverage

Excellent: The regression tests are comprehensive and test real-world scenarios:

  • Complex delegate inheritance patterns
  • Deep nested includes (5+ levels)
  • Edge cases in relation filtering
  • Asymmetric data insertion patterns

⚠️ Potential Concerns

Minor observations:

  1. TempAliasTransformer complexity: The two-mode approach (alwaysCompact vs compactLongNames) adds complexity but is well-documented
  2. MySQL JSON handling: The bi-directional JSON_CONTAINS approach is clever but could impact performance on large JSON objects

📋 Recommendations

  1. Documentation: Consider adding performance notes about the alias compaction modes for PostgreSQL users
  2. Monitoring: Track query performance impact of MySQL JSON equality changes
  3. Testing: The regression test coverage is exemplary - maintain this standard

🎯 Overall Assessment

APPROVED ✅ This is a high-quality release with:

  • ✅ No breaking changes
  • ✅ Significant bug fixes for delegate models and complex queries
  • ✅ Performance improvements
  • ✅ Excellent test coverage
  • ✅ Clean, well-structured code
  • ✅ Proper error handling and validation

The release is ready for production deployment.


@ymc9 ymc9 merged commit 266106c into main Mar 8, 2026
10 checks passed
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.

2 participants