Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Dec 17, 2025

fixes #510

Summary by CodeRabbit

  • Bug Fixes

    • Improved validation of unary boolean expressions with clearer errors for invalid operands.
    • Centralized database query error handling for consistent, more informative error reporting.
  • Tests

    • Added a regression test covering invalid boolean-expression validation.
    • Minor wording fixes in two existing regression test descriptions.
  • Chores

    • Added "*.vsix" to .gitignore.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings December 17, 2025 05:22
@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Added UnaryExpr validation to require Boolean operands, centralized DB query error handling via an internal wrapper in the query executor, and added/updated regression tests exercising the unary validation and minor test description fixes.

Changes

Cohort / File(s) Summary
Unary Expression Validation
packages/language/src/validators/expression-validator.ts
Added handling for UnaryExpr in the expression validator and a private validateUnaryExpr that enforces the operand is Boolean, emitting an error when not.
Query Execution Error Handling
packages/orm/src/client/executor/zenstack-query-executor.ts
Replaced direct connection.executeQuery(...) calls with a private internalExecuteQuery(...) wrapper that delegates to the connection and converts thrown errors into DB query errors including SQL and parameters.
Regression Tests
tests/regression/test/issue-510.test.ts, tests/regression/test/issue-503/regression.test.ts, tests/regression/test/issue-505.test.ts
Added a new regression test asserting unary ! on non-boolean operands errors during policy client init; corrected two test suite description strings (typo/text-only changes).
Repository Metadata
.gitignore
Added *.vsix to ignore patterns.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Check expression-validator integration: ensure UnaryExpr branch, type resolution for operand, and error message/positioning are correct.
  • Verify internalExecuteQuery preserves original error context (SQL, params) and is used consistently across execution paths.
  • Run the new regression test and confirm the regex matches the emitted validation message exactly.

Possibly related PRs

Poem

🐰 I hopped through AST trees with care,

I checked each "!" with a watchful stare.
No non-boolean may now pretend,
Queries wrapped before they wend.
A tiny test to prove the end. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ❓ Inconclusive Minor scope concerns: .gitignore addition is unrelated to the core objective, and test description corrections in other files are tangential. Consider whether .gitignore and test description corrections should be in a separate maintenance PR, or confirm they are acceptable as incidental fixes.
✅ 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 accurately describes the main objective of the PR: enforcing that the unary '!' operator should only work with boolean fields.
Linked Issues check ✅ Passed The PR successfully implements the requirement from #510 by adding UnaryExpr validation to enforce boolean-only operands and introducing error handling for invalid expressions.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/issue-510

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5350da4 and 418dd65.

📒 Files selected for processing (5)
  • .gitignore (1 hunks)
  • packages/language/src/validators/expression-validator.ts (3 hunks)
  • tests/regression/test/issue-503/regression.test.ts (1 hunks)
  • tests/regression/test/issue-505.test.ts (1 hunks)
  • tests/regression/test/issue-510.test.ts (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • .gitignore
  • tests/regression/test/issue-505.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/language/src/validators/expression-validator.ts
  • tests/regression/test/issue-510.test.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/e2e/**/*.{ts,tsx} : E2E tests should validate real-world schema compatibility with established projects

Applied to files:

  • tests/regression/test/issue-503/regression.test.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests

Applied to files:

  • tests/regression/test/issue-503/regression.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: build-test (20.x, sqlite)
🔇 Additional comments (1)
tests/regression/test/issue-503/regression.test.ts (1)

5-5: Minor consistency improvement—LGTM.

The correction from "issues" (plural) to "issue" (singular) accurately reflects that this test suite covers a single issue (#503).


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.

@claude
Copy link

claude bot commented Dec 17, 2025

Claude finished @ymc9's task —— View job


Code Review: fix(orm): operator "!" should only be applicable to boolean fields

Reviewing PR #511 that fixes issue #510 regarding the "!" operator restriction to boolean fields.

Review Tasks:

  • Analyze the changed files and understand the fix
  • Review validation logic changes
  • Review query executor changes
  • Evaluate test coverage
  • Check for code quality, bugs, performance, and security issues
  • Provide constructive feedback

Analysis

Problem: The issue was that the "!" operator could be used on non-boolean fields, which should not be allowed. The error occurred in the ZModel schema on line 96: (!Image || auth().id == Image.userId) where !Image attempts to negate an Image model reference.

Solution Overview: The fix adds proper validation for unary expressions in the expression validator to ensure the "!" operator is only applied to boolean fields.

Code Changes Review

1. Expression Validator (packages/language/src/validators/expression-validator.ts)

  • Good: Added proper import for UnaryExpr type
  • Good: Added validation case for UnaryExpr in the main validation switch
  • Good: Implemented validateUnaryExpr method that checks operand type is Boolean
  • Good: Clear error message: operand of "${expr.operator}" must be of Boolean type

2. Query Executor (packages/orm/src/client/executor/zenstack-query-executor.ts)

  • Good: Added centralized error handling with internalExecuteQuery method
  • Good: Consistent error wrapping using createDBQueryError
  • Good: Applied to all three query execution paths for consistency

3. Test Coverage (tests/regression/test/issue-510.test.ts)

  • Good: Comprehensive test case with realistic schema
  • Good: Tests the exact problematic pattern: !Image in access control
  • Good: Verifies proper error message matching

Feedback & Recommendations

Strengths:

  1. Targeted Fix: The validation correctly identifies the root cause and prevents invalid unary operations on non-boolean types
  2. Error Handling: Good centralization of query error handling in the executor
  3. Test Quality: The regression test captures the real-world scenario and ensures the fix works
  4. Code Consistency: Changes follow existing patterns in the codebase

Minor Considerations:

  1. Future-Proofing: The validateUnaryExpr method is generic enough to handle other unary operators if added later
  2. Error Context: The error message includes the operator name, which is helpful for debugging
  3. Type Safety: Proper TypeScript types are used throughout

Security & Performance Assessment

  • Security: No security concerns - this is a compile-time validation that prevents invalid expressions
  • Performance: Minimal impact - validation only runs during schema compilation, no runtime cost
  • Error Handling: Improved error handling in query executor reduces potential for silent failures

Code Quality Assessment

  • Maintainability: ⭐⭐⭐⭐⭐ Clean, focused changes with clear intent
  • Testability: ⭐⭐⭐⭐⭐ Excellent test coverage for the specific issue
  • Documentation: ⭐⭐⭐⭐ Code is self-documenting, clear method names and error messages

Overall Assessment: This is a well-implemented fix that properly addresses the reported issue. The changes are minimal, focused, and follow good engineering practices. The validation logic is sound, the error handling improvements are beneficial, and the test coverage ensures the fix works correctly.

Recommendation: ✅ Approve - This PR is ready to merge.


Copy link

@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: 0

🧹 Nitpick comments (1)
packages/orm/src/client/executor/zenstack-query-executor.ts (1)

201-201: Good refactoring, but appears unrelated to the PR's main objective.

The changes centralize error handling through the new internalExecuteQuery wrapper, providing consistent error formatting with SQL context. The implementation correctly avoids double-wrapping by checking for ORMError instances in the outer catch block (lines 114-116).

However, this refactoring seems tangential to the PR's stated objective of fixing the "!" operator validation. While it's a reasonable improvement, consider whether it should be in a separate PR for clarity.

Also applies to: 249-249, 473-473

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbe7257 and 5350da4.

📒 Files selected for processing (3)
  • packages/language/src/validators/expression-validator.ts (3 hunks)
  • packages/orm/src/client/executor/zenstack-query-executor.ts (4 hunks)
  • tests/regression/test/issue-510.test.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/e2e/**/*.{ts,tsx} : E2E tests should validate real-world schema compatibility with established projects

Applied to files:

  • tests/regression/test/issue-510.test.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests

Applied to files:

  • tests/regression/test/issue-510.test.ts
  • packages/orm/src/client/executor/zenstack-query-executor.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/**/type*.{ts,tsx} : Ensure TypeScript inference and type coverage are validated through type coverage tests

Applied to files:

  • tests/regression/test/issue-510.test.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`

Applied to files:

  • tests/regression/test/issue-510.test.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Use Kysely as the query builder interface for low-level database queries, avoiding raw SQL when possible

Applied to files:

  • packages/orm/src/client/executor/zenstack-query-executor.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Implement plugin hooks at ORM, Kysely, and entity mutation levels for query interception and customization

Applied to files:

  • packages/orm/src/client/executor/zenstack-query-executor.ts
🧬 Code graph analysis (3)
tests/regression/test/issue-510.test.ts (1)
packages/testtools/src/client.ts (1)
  • createPolicyTestClient (258-269)
packages/orm/src/client/executor/zenstack-query-executor.ts (2)
packages/orm/src/client/executor/zenstack-driver.ts (2)
  • connection (129-170)
  • compiledQuery (181-188)
packages/orm/src/client/errors.ts (1)
  • createDBQueryError (122-129)
packages/language/src/validators/expression-validator.ts (1)
packages/language/src/generated/ast.ts (2)
  • UnaryExpr (741-746)
  • UnaryExpr (748-748)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Agent
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: claude-review
  • GitHub Check: build-test (20.x, sqlite)
🔇 Additional comments (6)
packages/language/src/validators/expression-validator.ts (3)

15-15: LGTM! Import added correctly.

The UnaryExpr import is necessary for the new validation logic and is properly placed with other AST type imports.


71-73: LGTM! Switch case properly integrated.

The new case for UnaryExpr follows the established pattern and correctly delegates to the validation method.


252-256: LGTM! Validation correctly restricts "!" to boolean operands.

The implementation correctly enforces that the operand of the "!" operator must be of Boolean type, directly addressing the PR objective. The error message is clear and matches the test expectation.

tests/regression/test/issue-510.test.ts (2)

1-99: LGTM! Comprehensive regression test with realistic schema.

The test correctly sets up a scenario that triggers the validation error. Line 96 contains the key test case where !Image incorrectly applies the "!" operator to a relation field (File?) rather than a boolean, which should be caught by the new validation.


101-101: LGTM! Test assertion validates the fix correctly.

The assertion properly verifies that the schema with an invalid unary expression is rejected with the expected error message, matching the validation added in expression-validator.ts.

packages/orm/src/client/executor/zenstack-query-executor.ts (1)

487-493: LGTM! Centralized error handling with helpful context.

The wrapper method correctly catches query execution errors and enriches them with SQL and parameter information, making debugging easier. The implementation properly delegates to connection.executeQuery and wraps any errors using createDBQueryError.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes issue #510 by adding validation to ensure the unary "!" operator can only be applied to boolean fields. Previously, the "!" operator could be incorrectly used on non-boolean types (such as relation fields) without a validation error. The fix adds a validateUnaryExpr method to the expression validator that checks if the operand is of Boolean type.

Key changes:

  • Added validation for UnaryExpr to ensure "!" operator only accepts Boolean operands
  • Added a regression test that verifies the fix with a schema containing !Image where Image is a File? relation
  • Refactored query execution error handling by introducing internalExecuteQuery wrapper method

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/regression/test/issue-510.test.ts Adds regression test verifying that using "!" on a non-boolean field (Image relation) throws appropriate error
packages/language/src/validators/expression-validator.ts Implements validateUnaryExpr method to check that "!" operator operands are Boolean type
packages/orm/src/client/executor/zenstack-query-executor.ts Refactors query execution to use internalExecuteQuery wrapper for consistent error handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@claude
Copy link

claude bot commented Dec 17, 2025

Claude finished @ymc9's task —— View job


Code Review: fix(orm): operator "!" should only be applicable to boolean fields

Reviewing PR #511 that fixes issue #510 regarding the "!" operator restriction to boolean fields.

Review Tasks:

  • Analyze the changed files and understand the fix
  • Review validation logic changes
  • Review query executor changes
  • Evaluate test coverage
  • Check for code quality, bugs, performance, and security issues
  • Provide constructive feedback

Analysis

Problem: The issue was that the "!" operator could be used on non-boolean fields, which should not be allowed. The error occurred in the ZModel schema on line 96: (!Image || auth().id == Image.userId) where !Image attempts to negate an Image model reference.

Solution Overview: The fix adds proper validation for unary expressions in the expression validator to ensure the "!" operator is only applied to boolean fields.

Code Changes Review

1. Expression Validator (packages/language/src/validators/expression-validator.ts)

  • Good: Added proper import for UnaryExpr type
  • Good: Added validation case for UnaryExpr in the main validation switch
  • Good: Implemented validateUnaryExpr method that checks operand type is Boolean
  • Good: Clear error message: operand of "${expr.operator}" must be of Boolean type

2. Query Executor (packages/orm/src/client/executor/zenstack-query-executor.ts)

  • Good: Added centralized error handling with internalExecuteQuery method
  • Good: Consistent error wrapping using createDBQueryError
  • Good: Applied to all three query execution paths for consistency

3. Test Coverage (tests/regression/test/issue-510.test.ts)

  • Good: Comprehensive test case with realistic schema
  • Good: Tests the exact problematic pattern: !Image in access control
  • Good: Verifies proper error message matching

Feedback & Recommendations

Strengths:

  1. Targeted Fix: The validation correctly identifies the root cause and prevents invalid unary operations on non-boolean types
  2. Error Handling: Good centralization of query error handling in the executor
  3. Test Quality: The regression test captures the real-world scenario and ensures the fix works
  4. Code Consistency: Changes follow existing patterns in the codebase

Minor Considerations:

  1. Future-Proofing: The validateUnaryExpr method is generic enough to handle other unary operators if added later
  2. Error Context: The error message includes the operator name, which is helpful for debugging
  3. Type Safety: Proper TypeScript types are used throughout

Security & Performance Assessment

  • Security: No security concerns - this is a compile-time validation that prevents invalid expressions
  • Performance: Minimal impact - validation only runs during schema compilation, no runtime cost
  • Error Handling: Improved error handling in query executor reduces potential for silent failures

Code Quality Assessment

  • Maintainability: ⭐⭐⭐⭐⭐ Clean, focused changes with clear intent
  • Testability: ⭐⭐⭐⭐⭐ Excellent test coverage for the specific issue
  • Documentation: ⭐⭐⭐⭐ Code is self-documenting, clear method names and error messages

Overall Assessment: This is a well-implemented fix that properly addresses the reported issue. The changes are minimal, focused, and follow good engineering practices. The validation logic is sound, the error handling improvements are beneficial, and the test coverage ensures the fix works correctly.

Recommendation: ✅ Approve - This PR is ready to merge.


@ymc9 ymc9 merged commit 3172523 into dev Dec 17, 2025
5 checks passed
@ymc9 ymc9 deleted the fix/issue-510 branch December 17, 2025 05:56
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