Skip to content

fix(schema-engine): use allowlist in pg constraints query to handle PostgreSQL 18 NOT NULL contype#5819

Open
tsushanth wants to merge 1 commit into
prisma:mainfrom
tsushanth:fix/pg18-not-null-constraint-introspection
Open

fix(schema-engine): use allowlist in pg constraints query to handle PostgreSQL 18 NOT NULL contype#5819
tsushanth wants to merge 1 commit into
prisma:mainfrom
tsushanth:fix/pg18-not-null-constraint-introspection

Conversation

@tsushanth

Copy link
Copy Markdown

What

Change the PostgreSQL constraint introspection query from a denylist to an allowlist.

Before:

AND contype NOT IN ('p', 'u', 'f')

After:

AND contype IN ('c', 'x')

Why

PostgreSQL 18 introduces NOT NULL constraints as first-class pg_constraint rows with contype = 'n' (PG 18 docs). The previous denylist allowed these rows through to get_constraints, where row.get_expect_char("constraint_type") panics when the value arrives as Text("n") rather than a char — which is the case for all driver-adapter paths, since values cross the JS boundary as strings.

The practical impact: any PostgreSQL 18 database with at least one NOT NULL column (i.e. effectively all of them) breaks db push diffing, db pull, and migrate dev/deploy when going through the WASM engine with a driver adapter (@prisma/adapter-pg, PGlite, etc.). The promise returned by schemaPush never settles because the panic has no registered handler.

The fix uses an allowlist restricted to 'c' (check) and 'x' (exclusion) — the only two contype values get_constraints actually handles. Column nullability is already read from pg_attribute.attnotnull, so NOT-NULL-as-constraint rows carry no information Prisma needs. This also future-proofs the query against any new contype values PostgreSQL might introduce (PG 18 also added 't' for trigger constraints upstream).

Fixes prisma/prisma#29635

…ostgreSQL 18 NOT NULL contype

PostgreSQL 18 adds NOT NULL constraints as first-class pg_constraint rows
with contype = 'n'. The previous denylist `NOT IN ('p', 'u', 'f')` let
these rows through to get_constraints, where get_expect_char("constraint_type")
panics when the value arrives as Text (the driver-adapter value path).

Switching to an allowlist `IN ('c', 'x')` — the only two contypes the
describer actually handles (check and exclusion constraints) — prevents any
unknown or future contype from reaching the panic site. Column nullability
is already read from pg_attribute.attnotnull, so NOT-NULL-as-constraint rows
carry no information Prisma needs.

Fixes prisma/prisma#29635
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d2d58299-d873-4b65-b0e1-3ede699080ce

📥 Commits

Reviewing files that changed from the base of the PR and between 1171e96 and 0cf4038.

📒 Files selected for processing (1)
  • schema-engine/sql-schema-describer/src/postgres/constraints_query.sql

Summary by CodeRabbit

  • Bug Fixes
    • Updated constraint filtering logic in database schema analysis to ensure the correct constraint types are captured and processed.

Walkthrough

The PostgreSQL constraints introspection query in constraints_query.sql has its contype filter changed on line 15 from a denylist (contype NOT IN ('p', 'u', 'f')) to an allowlist (contype IN ('c', 'x')). This restricts the query result set to only check constraints (c) and exclusion constraints (x), implicitly excluding all other constraint types including the PostgreSQL 18 NOT NULL constraint (n), primary key (p), unique (u), and foreign key (f).

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: converting from a denylist to an allowlist in PostgreSQL constraints query to handle PostgreSQL 18's new NOT NULL constraint type.
Description check ✅ Passed The description clearly explains what changed, why it was necessary (PostgreSQL 18 NOT NULL constraints), and the practical impact on database introspection operations.
Linked Issues check ✅ Passed The PR directly addresses the linked issue #29635 by implementing the allowlist approach for constraint types, preventing NOT NULL constraint rows from causing panics during introspection.
Out of Scope Changes check ✅ Passed The change is narrowly scoped to the PostgreSQL constraints query file, modifying only the constraint type filter as required by the linked issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

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.

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.

Schema engine panics introspecting PostgreSQL 18: NOT NULL constraints (contype 'n') fail constraint_type parsing

1 participant