22004 — null_value_not_allowed
22004 is nullvaluenot_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.
English manual coverage begins with PostgreSQL 8.1. Source history and runtime observations have their own recorded version boundaries.
Reading PG 18·Select a recorded version
- aliases
- Unknown
- class name
- Data Exception
- condition name
- null_value_not_allowed
- lang
- en
- sqlstate
- 22004
Definition PG 18
22004
At a glance {#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.
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.
SELECT * FROM XMLTABLE(XMLNAMESPACES (NULL AS p), '/p:row' PASSING '<p:row xmlns:p="u"/>' COLUMNS x text PATH 'p:x');
SELECT count(*) FROM XMLTABLE(XMLNAMESPACES ('u' AS p), '/p:row' PASSING '<p:row xmlns:p="u"><p:x>ok</p:x></p:row>' COLUMNS x text PATH 'p:x');
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 {#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 {#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 {#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 {#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 {#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 {#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 {#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.
Compare versions
SQLSTATE evidence and recorded runtime versions
cases · xmltable_null_namespace
{
"assertions": [
"SQLSTATE is 22004",
"The diagnostic identifies the XMLTABLE namespace URI",
"The failed autocommit session remains IDLE",
"A non-NULL namespace URI returns one row afterward"
],
"case_id": "xmltable_null_namespace",
"cleanup": "Drop the case schema with an owner connection.",
"has_snippet": true,
"position": 0,
"preconditions": [],
"repair": "Supply the namespace URI required by the XML document and keep this XMLTABLE path distinct from a table-column NOT NULL violation.",
"trigger": "Evaluate XMLTABLE with a NULL namespace URI.",
"versions": [
"10",
"18"
]
}claims · identity
{
"claim_id": "identity",
"limits": "",
"method": "Read fixed definition.",
"position": 0,
"runtime": [],
"sources": [
"src.errcodes.18.6"
],
"statement": "22004 is null_value_not_allowed in SQLSTATE Class 22."
}claims · mechanism.xmltable-namespace
{
"claim_id": "mechanism.xmltable-namespace",
"limits": "Other functions may use 22004 for different NULL contracts.",
"method": "Read the complete namespace evaluation and NULL guard.",
"position": 1,
"runtime": [],
"sources": [
"src.path.xmltable"
],
"statement": "The XMLTABLE table-function executor rejects a NULL namespace URI and reports 22004 before producing rows."
}claims · mechanism.xmltable-null-guards
{
"claim_id": "mechanism.xmltable-null-guards",
"limits": "The selected runtime covers only the namespace URI guard.",
"method": "Read the complete tfuncInitialize guard sequence.",
"position": 2,
"runtime": [],
"sources": [
"src.path.xmltable-filters",
"src.path.xmltable-output"
],
"statement": "The table-function executor module has separate 22004 guards for null row-filter expressions, null column-filter expressions, and output columns marked NOT NULL whose value remains NULL after any DEFAULT expression is applied, each with a distinct primary message."
}claims · history
{
"claim_id": "history",
"limits": "",
"method": "Use catalogue boundary.",
"position": 3,
"runtime": [],
"sources": [
"src.errcodes.18.6"
],
"statement": "The locked catalogue records 22004 from 7.4 without proving an exact implementation introduction date."
}claims · runtime.observation
{
"claim_id": "runtime.observation",
"limits": "The observation covers XMLTABLE namespace evaluation only.",
"method": "Execute the shared registry and inspect selected summaries.",
"position": 4,
"runtime": [
"runtime.22004-data1-latest.latest",
"runtime.22004-data1-pg10.pg10"
],
"sources": [
"manifest.22004",
"snippet-registry.22004"
],
"statement": "The xmltable_null_namespace case passed on isolated PostgreSQL 18.6 and 10.21: a NULL URI raised 22004 and the valid URI repair returned one row with the session IDLE."
}messages · message.xmltable
{
"limits": "",
"message_id": "message.xmltable",
"path": "",
"position": 0,
"raw": {
"id": "message.xmltable",
"primary_template": "namespace URI must not be null",
"severity_source": "ERROR",
"sources": [
"src.path.xmltable"
],
"sqlstate": "22004"
},
"severity": "ERROR",
"sources": [
"src.path.xmltable"
],
"templates": [
{
"kind": "primary",
"literal": "namespace URI must not be null",
"position": 0,
"role": "",
"template": "namespace URI must not be null"
}
]
}messages · message.xmltable-row-filter
{
"limits": "",
"message_id": "message.xmltable-row-filter",
"path": "",
"position": 1,
"raw": {
"id": "message.xmltable-row-filter",
"primary_template": "row filter expression must not be null",
"severity_source": "ERROR",
"sources": [
"src.path.xmltable-filters"
],
"sqlstate": "22004"
},
"severity": "ERROR",
"sources": [
"src.path.xmltable-filters"
],
"templates": [
{
"kind": "primary",
"literal": "row filter expression must not be null",
"position": 0,
"role": "",
"template": "row filter expression must not be null"
}
]
}messages · message.xmltable-column-filter
{
"limits": "",
"message_id": "message.xmltable-column-filter",
"path": "",
"position": 2,
"raw": {
"detail_template": "Filter for column \"%s\" is null.",
"id": "message.xmltable-column-filter",
"primary_template": "column filter expression must not be null",
"severity_source": "ERROR",
"sources": [
"src.path.xmltable-filters"
],
"sqlstate": "22004"
},
"severity": "ERROR",
"sources": [
"src.path.xmltable-filters"
],
"templates": [
{
"kind": "primary",
"literal": "column filter expression must not be null",
"position": 0,
"role": "",
"template": "column filter expression must not be null"
},
{
"kind": "detail",
"literal": "Filter for column \" \" is null.",
"position": 1,
"role": "",
"template": "Filter for column \"%s\" is null."
}
]
}messages · message.xmltable-column-output
{
"limits": "",
"message_id": "message.xmltable-column-output",
"path": "",
"position": 3,
"raw": {
"guard_context": "XMLTABLE output column is marked NOT NULL and remains NULL after the output value and any DEFAULT expression have been evaluated",
"id": "message.xmltable-column-output",
"primary_template": "null is not allowed in column \"%s\"",
"severity_source": "ERROR",
"sources": [
"src.path.xmltable-output"
],
"sqlstate": "22004"
},
"severity": "ERROR",
"sources": [
"src.path.xmltable-output"
],
"templates": [
{
"kind": "primary",
"literal": "null is not allowed in column \" \"",
"position": 0,
"role": "",
"template": "null is not allowed in column \"%s\""
}
]
}runtimes · runtime.22004-data1-latest.latest · 18.6 (Homebrew) · passed
{
"cases": [
"xmltable_null_namespace"
],
"limits": "",
"position": 0,
"raw": {
"cases": [
"xmltable_null_namespace"
],
"id": "runtime.22004-data1-latest.latest",
"observed": {
"sqlstate": "22004",
"status_after_repair": "IDLE"
},
"raw": "verify/results/22004-data1-latest/latest/raw.jsonl",
"raw_sha256": "245e7dc22a58a7411347c9d7ef3732ee19b16b83bd6935946330e15f883bf863",
"run_id": "22004-data1-latest",
"server_version": "18.6 (Homebrew)",
"server_version_num": 180006,
"snippet_registry": {
"path": "verify/cases/22004/snippets.json",
"sha256": "a71cda2337e992c422232fa9f7fabc158411970e959daba3c571f521e65ece0c"
},
"status": "passed",
"summary": "verify/results/22004-data1-latest/latest/summary.json",
"summary_sha256": "6d2a04c9fec0b2253747c2961000f74500aa992f83b58123a15bc0eaa3a02575",
"target": "latest"
},
"run_id": "22004-data1-latest",
"runtime_id": "runtime.22004-data1-latest.latest",
"server_version": "18.6 (Homebrew)",
"status": "passed",
"target": "latest"
}runtimes · runtime.22004-data1-pg10.pg10 · 10.21 (Debian 10.21-1.pgdg90+1) · passed
{
"cases": [
"xmltable_null_namespace"
],
"limits": "",
"position": 1,
"raw": {
"cases": [
"xmltable_null_namespace"
],
"id": "runtime.22004-data1-pg10.pg10",
"observed": {
"sqlstate": "22004",
"status_after_repair": "IDLE"
},
"raw": "verify/results/22004-data1-pg10/pg10/raw.jsonl",
"raw_sha256": "05609b74ec6458e635c31330ee36d4ce3a5e8695b078bb1dfd29caf290eac3da",
"run_id": "22004-data1-pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"server_version_num": 100021,
"snippet_registry": {
"path": "verify/cases/22004/snippets.json",
"sha256": "a71cda2337e992c422232fa9f7fabc158411970e959daba3c571f521e65ece0c"
},
"status": "passed",
"summary": "verify/results/22004-data1-pg10/pg10/summary.json",
"summary_sha256": "ec256223667ce3481fe0284a6455601713b9a863e4320a55e02e0728a5b6373c",
"target": "pg10"
},
"run_id": "22004-data1-pg10",
"runtime_id": "runtime.22004-data1-pg10.pg10",
"server_version": "10.21 (Debian 10.21-1.pgdg90+1)",
"status": "passed",
"target": "pg10"
}sources · src.errcodes.18.6
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/utils/errcodes.txt",
"position": 0,
"sha256": "6e8de346643ba84aa3c9c6a73360acfc7b2dfb89162c06c08ce9bf5bcd5bbcba",
"source_id": "src.errcodes.18.6",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/utils/errcodes.txt#L195"
}sources · src.calls.REL_18_6
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "",
"path": "raw/calls/REL_18_6.jsonl",
"position": 1,
"sha256": "9ee8a0e81d8f0825c5c1ae45583439859a26e602bdd4ce2f2a62aa278867ccbf",
"source_id": "src.calls.REL_18_6",
"tag": "",
"url": ""
}sources · src.path.xmltable
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/executor/nodeTableFuncscan.c",
"position": 2,
"sha256": "0a9faaa9e45bb460dd98e4688f088711d459333eb8bd94255779f2c0218df82b",
"source_id": "src.path.xmltable",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeTableFuncscan.c#L346-L371"
}sources · src.path.xmltable-filters
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/executor/nodeTableFuncscan.c",
"position": 3,
"sha256": "0a9faaa9e45bb460dd98e4688f088711d459333eb8bd94255779f2c0218df82b",
"source_id": "src.path.xmltable-filters",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeTableFuncscan.c#L380-L419"
}sources · src.path.xmltable-output
{
"commit": "724edf9bde9d356724ad384a2e196edc3c9f80f7",
"docs_url": "",
"kind": "upstream_source",
"location": "",
"path": "src/backend/executor/nodeTableFuncscan.c",
"position": 4,
"sha256": "0a9faaa9e45bb460dd98e4688f088711d459333eb8bd94255779f2c0218df82b",
"source_id": "src.path.xmltable-output",
"tag": "REL_18_6",
"url": "https://github.com/postgres/postgres/blob/724edf9bde9d356724ad384a2e196edc3c9f80f7/src/backend/executor/nodeTableFuncscan.c#L494-L508"
}sources · snippet-registry.22004
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "",
"path": "verify/cases/22004/snippets.json",
"position": 5,
"sha256": "a71cda2337e992c422232fa9f7fabc158411970e959daba3c571f521e65ece0c",
"source_id": "snippet-registry.22004",
"tag": "",
"url": ""
}sources · manifest.22004
{
"commit": "",
"docs_url": "",
"kind": "local_artifact",
"location": "",
"path": "verify/cases/22004/cases.json",
"position": 6,
"sha256": "b0dc8a3d3580f20a4d8abb23ce148c4919b6e085aa06f772d6feb1c0e282107d",
"source_id": "manifest.22004",
"tag": "workspace",
"url": "verify/cases/22004/cases.json"
}Source references
Full definition and evidence JSON
Definition sources
center · PostgreSQL 18 · english-manuals:7217004fde97f287aa753af91e961d30d12352d258f3ac102dcfe7ae4fc443bf
Text language: en · english-manuals:7217004fde97f287aa753af91e961d30d12352d258f3ac102dcfe7ae4fc443bf