44000 — with_check_option_violation
44000 — with_check_option_violation
At a glance
44000 means that a row written through a view would not satisfy that view’s WITH CHECK OPTION predicate. It protects the view’s write invariant; it is not the table-level CHECK condition 23514.
| Field | Value |
|---|---|
| SQLSTATE | 44000 |
| Condition | with_check_option_violation |
| Status | active |
| Known present by | 7.4 |
| Locked snapshots | 9.0.23, 9.1.24, 9.2.24, 9.3.25, 9.4.26, 9.5.25, 9.6.24, 10.23, 11.22, 12.22, 13.23, 14.24, 15.19, 16.15, 17.11, 18.6, 19beta3 |
| Macros | ERRCODE_WITH_CHECK_OPTION_VIOLATION |
| Aliases | — |
Meaning
When an automatically updatable view is defined with WITH CHECK OPTION, PostgreSQL checks that an inserted or updated row remains visible through the view. The executor treats both FALSE and NULL from the view predicate as failure, so a nullable predicate column does not make an unknown row pass. ExecWithCheckOptions reports new row violates check option for view "%s"; the dynamic failing-row DETAIL is included only when the permissions allow the row description. LOCAL checks conditions defined directly in the current view; underlying base-view conditions are not checked unless those base views also specify CHECK OPTION. CASCADED checks the current view and all underlying base-view conditions. CHECK OPTION is supported only on automatically updatable views without an INSTEAD OF trigger or rule; a trigger-updatable base view and an INSTEAD rewrite are separate boundaries where cascading or all checks can be ignored. The selected natural case is a directly updatable view.
Diagnosis
Capture SQLSTATE, view name, DETAIL when present, and the exact row values sent through the view. Read the definition with pg_get_viewdef() and evaluate its predicate using SQL three-valued logic: only TRUE is visible through the check option, while FALSE and NULL fail. Check whether the view is automatically updatable, whether it uses LOCAL or CASCADED, and whether a base view has an INSTEAD OF trigger or an INSTEAD rewrite. Do not search only for table CHECK constraints: LOCAL does not check ordinary underlying-view predicates, while CASCADED does unless a trigger-updatable or rewritten boundary prevents that cascade. Missing DETAIL can be a permission boundary rather than proof that no row was checked.
Response
Correct the row so its predicate is TRUE, or change the view definition only after confirming the schema contract and the intended LOCAL/CASCADED scope. Keep the check option when the view is meant to be an enforced filtered interface. If a trigger-updatable base view or an INSTEAD rewrite is involved, inspect that boundary and its effective checks; do not assume a cascaded check reached it. After an autocommit error the selected connection remained IDLE; inside an explicit transaction rollback the failed block before retrying with a valid row.
Messages
The fixed source templates are new row violates check option for view "%s" and Failing row contains %s.. The view identifier and row rendering are dynamic. Treat DETAIL as diagnostic data and avoid copying it into a stable parser without accounting for values and formatting.
Representative case
The shared registry in verify/cases/44000/snippets.json (SHA-256 7b227bca904c860388c6cf1f5b7f551412b4d67832fb91aaa682f4126072e41c) creates a filtered view, attempts one row outside the predicate, and then inserts a valid row. See the public case export and structured evidence.
The runner qualifies registry relation names inside a private schema. It asserts the natural server SQLSTATE and view diagnostic, then verifies that only the visible row was accepted.
The selected case observed 44000 on PostgreSQL 18.6 and 10.21 when a row with visible = false was inserted through a view with WITH CHECK OPTION. The DETAIL contained the failing row, autocommit stayed IDLE, and a row satisfying the predicate was accepted.
Versions
The locked catalogue records this condition from the early historical boundary through the formal snapshots. The fixed source has the same mechanism in 18.6 and 10.23; the selected runtime case covers a simple insert through a view on 18.6 and 10.21, not every view-rule composition.
Related
Compare 23514 check violation for a table CHECK and 27000 triggered data change violation for trigger-driven same-command changes.
Sources
src.errcodes.18.6(SHA-2566e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba)src.execMain.18.6(SHA-25633b97337fa23a649c5e7a092e1bd405a54e8503529236c62c9d5bb93a1774a8d)CREATE VIEW documentation· local call scansrc.calls.REL_18_6(SHA-2569ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf)