Skip to content

Conversation

@tonxxd
Copy link

@tonxxd tonxxd commented Jan 4, 2026

Fix issue #2328 where String[] fields cause PostgreSQL syntax errors when combined with policy guards in WHERE clauses.

The issue was that when select is undefined, Prisma selects all fields but generates invalid PostgreSQL SQL for array fields. By explicitly setting select to include all fields (including arrays) instead of using undefined, Prisma generates correct SQL.

Changes:

  • Replace select = undefined with explicit makeAllFieldSelect() call
  • Add makeAllFieldSelect() method that includes all scalar fields including arrays
  • Preserves all existing behavior while fixing the SQL generation bug

Fix issue zenstackhq#2328 where String[] fields cause PostgreSQL syntax errors when
combined with policy guards in WHERE clauses.

The issue was that when select is undefined, Prisma selects all fields
but generates invalid PostgreSQL SQL for array fields. By explicitly
setting select to include all fields (including arrays) instead of
using undefined, Prisma generates correct SQL.

Changes:
- Replace select = undefined with explicit makeAllFieldSelect() call
- Add makeAllFieldSelect() method that includes all scalar fields including arrays
- Preserves all existing behavior while fixing the SQL generation bug
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

When a schema is present, selection logic now deterministically selects all scalar fields via a new helper; otherwise it falls back to the existing ID-only selection. The previous fallback that forced scalar selection when entityChecker.selector was absent was removed.

Changes

Cohort / File(s) Summary
Policy Field Selection Logic
packages/runtime/src/enhancements/node/policy/policy-utils.ts
Replaced conditional guardrail with deterministic selection: added private makeAllScalarFieldSelect(model) to build an explicit select of scalar fields when schema exists; removed prior fallback that forced scalar-only selection for entityChecker.selector; merged entityChecker.selector into existing selects rather than forcing a fallback.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing PostgreSQL policy queries to correctly handle String[] array fields.
Description check ✅ Passed The description is clearly related to the changeset, explaining the issue, root cause, and the specific changes made to fix array field handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10ca5da and f10449a.

📒 Files selected for processing (1)
  • packages/runtime/src/enhancements/node/policy/policy-utils.ts
🔇 Additional comments (2)
packages/runtime/src/enhancements/node/policy/policy-utils.ts (2)

891-906: LGTM! Solid fix for the PostgreSQL array field issue.

The explicit field selection approach correctly addresses the root cause. The conditional logic is well-reasoned:

  • Schema validation requires all scalar fields, so makeAllScalarFieldSelect is appropriate
  • When no schema validation is needed, selecting only ID fields is an optimization

The comments clearly explain the rationale, which is helpful for future maintainers.


1254-1267: Implementation is correct and safely handles edge cases.

The makeAllScalarFieldSelect method properly uses a defensive if (fields) check before iterating. Even if this.getModelFields(model) returns undefined (when the model is not found in modelMeta), the method safely returns an empty object {} without errors.

In practice, the edge case of an invalid model would fail earlier: this method is only called when a Zod schema exists (line 897), and the same calling context also invokes getZodSchema, getEntityChecker, and getModelPolicyDef on the same model. Any of these would fail first if the model is invalid, making the defensive check in makeAllScalarFieldSelect sufficient for safety.


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

🧹 Nitpick comments (1)
packages/runtime/src/enhancements/node/policy/policy-utils.ts (1)

1262-1280: Consider consolidating with makeAllScalarFieldSelect.

The new makeAllFieldSelect method has an identical implementation to the existing makeAllScalarFieldSelect method (lines 1249-1260). Both iterate over model fields and include only non-data-model (scalar) fields.

Consider reusing the existing method or consolidating them to reduce duplication:

🔎 Proposed refactor
-    /**
-     * Creates a select object that includes all fields (scalar and array) for the model.
-     * This is used instead of undefined to ensure Prisma handles array fields correctly
-     * when generating PostgreSQL SQL queries with WHERE clauses.
-     */
-    private makeAllFieldSelect(model: string): any {
-        const fields = this.getModelFields(model);
-        const result: any = {};
-        if (fields) {
-            Object.entries(fields).forEach(([k, v]) => {
-                // Include all scalar fields (including arrays) - explicitly setting select
-                // instead of undefined ensures Prisma generates correct SQL
-                if (!v.isDataModel) {
-                    result[k] = true;
-                }
-            });
-        }
-        return result;
-    }

Then update line 897 to use the existing method:

-            select = this.makeAllFieldSelect(model);
+            select = this.makeAllScalarFieldSelect(model);
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7634e2c and 10ca5da.

📒 Files selected for processing (1)
  • packages/runtime/src/enhancements/node/policy/policy-utils.ts
🔇 Additional comments (1)
packages/runtime/src/enhancements/node/policy/policy-utils.ts (1)

891-906: LGTM!

The conditional logic correctly differentiates between schema validation (requiring all fields) and policy-only checks (requiring only ID fields). The spread-based merge for entityChecker.selector properly combines the selections.

@tonxxd tonxxd closed this Jan 4, 2026
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.

1 participant