22004 — null_value_not_allowed
22004
At a glance
22004 is null_value_not_allowed. The fixed table-function path rejects a null namespace URI; many other extensions and core functions use the same condition for different null contracts.
| Field | Value |
|---|---|
| SQLSTATE | 22004 |
| Condition | null_value_not_allowed |
| 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_NULL_VALUE_NOT_ALLOWED |
| Aliases | — |
The shared case supplies a NULL XMLTABLE namespace URI, then repeats the table-function call with URI u and a matching XML row. Send the two SELECT statements separately; the first is expected to fail before the repaired call runs. The runner controls the session and cleanup.
Calibration observed the table-function namespace URI path: a NULL namespace reported namespace URI must not be null; a valid URI returned one XMLTABLE row, and both runner autocommit sessions returned to IDLE.
Messages
The namespace guard raises ERROR with primary namespace URI must not be null, with no separate DETAIL or HINT. The table-function executor module also has distinct ERROR guards for a null row-filter expression and a null column-filter expression (with a column-name DETAIL). Its output-column guard is narrower: after the XMLTABLE output column is marked NOT NULL, the value is obtained and any DEFAULT expression is applied; only when it is still NULL does it raise null is not allowed in column "%s". That output-column condition is distinct from an ordinary NULL result or a separate 23502 constraint error. The selected runtime observed only the namespace message.
Meaning
22004 is a NULL contract failure. In the fixed nodeTableFuncscan.c path, the rejected value is a namespace URI used by a table function: namespace URI must not be null. The same condition name can be selected by other functions, so a NULL function argument, a NULL result from a STRICT function, and a table column declared NOT NULL are different investigations. A normal SQL NULL result is not evidence of 22004; use the actual SQLSTATE and diagnostic fields.
Diagnosis
Use the full message, routine, context, and object fields to identify which parameter or descriptor was NULL. For the confirmed table-function path, inspect the namespace URI expression and the table-function XML/row description that supplied it. A plain NULL input or a STRICT function returning NULL does not by itself indicate this condition. If the response instead names a column constraint, use its actual SQLSTATE and constraint fields; do not relabel a column NOT NULL violation as 22004.
Response
Fix the function parameter or descriptor that the message identifies, or change the table-function definition so the namespace URI contract is satisfied. Preserve intentional SQL NULLs where the API permits them; replacing every NULL with an empty string can change XML or query semantics. The frozen case used autocommit, so the failed statement left the session IDLE; inside an explicit transaction, roll back the transaction or roll back to a pre-existing savepoint before continuing. Validate the corrected call before repeating a write.
Versions
The locked catalogue records this condition from 7.4 in the listed formal snapshots and 19beta3; fixed source coverage is PostgreSQL 18.6.
Related
22000 for other Data Exception paths, 22002 for the ECPG indicator-variable condition, and 23502 when the actual response is a not-null-constraint violation.
Sources
The confirmed table-function check is nodeTableFuncscan.c#L368-L370; the neighboring filter/output guards are in nodeTableFuncscan.c#L380-L419 and nodeTableFuncscan.c#L494-L508. The structured evidence record pins these paths and keeps other NULL contracts conditional.