| From: | PG Bug reporting form <noreply(at)postgresql(dot)org> |
|---|---|
| To: | pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Cc: | 303677365(at)qq(dot)com |
| Subject: | BUG #19808: NOT NULL NO INHERIT copied by CREATE TABLE (LIKE) not enforced on partitioned table |
| Date: | 2026-10-29 06:20:55 |
| Message-ID: | 19808-6fce48c9105a1ca0@postgresql.org |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
The following bug has been logged on the website:
Bug reference: 19808
Logged by: chunling qin
Email address: 303677365(at)qq(dot)com
PostgreSQL version: 18.6
Operating system: Linux x86_64
Description:
When CREATE TABLE (LIKE) copies a column declared NOT NULL NO INHERIT into a
*partitioned* table, the NOT NULL flag is recorded on the parent
(pg_attribute.attnotnull = true) but is not propagated to the partitions, so
an INSERT of NULL succeeds. Because the parent column is marked attnotnull,
the planner also prunes "WHERE a IS NULL" to an empty result, making the
stored NULL rows invisible to that predicate while "a + 0 IS NULL" still
finds them - two logically equivalent predicates disagree.
Test case (self-contained):
CREATE TABLE nn_src (a int NOT NULL NO INHERIT, b text);
CREATE TABLE nn_p (LIKE nn_src) PARTITION BY LIST (a);
CREATE TABLE nn_pd PARTITION OF nn_p DEFAULT;
INSERT INTO nn_p VALUES (NULL, 'null-row'); -- accepted
Catalog state: the parent has attnotnull = true for column a, the partition
has attnotnull = false.
Result on 18.6 (official docker image postgres:latest):
SELECT a, b FROM nn_p; -> (NULL, 'null-row')
SELECT count(*) FROM nn_p WHERE a IS NULL; -> 0
SELECT count(*) FROM nn_p WHERE a + 0 IS NULL; -> 1
EXPLAIN (COSTS OFF) SELECT * FROM nn_p WHERE a IS NULL;
Result
One-Time Filter: false
Baselines - the same INSERT is rejected whenever NO INHERIT is not involved:
(1) LIKE into a non-partitioned table:
CREATE TABLE nn_plain (LIKE nn_src); INSERT INTO nn_plain VALUES
(NULL,'x');
-> ERROR: null value in column "a" of relation "nn_plain" violates
not-null constraint
(2) plain NOT NULL (no NO INHERIT) declared in the partitioned parent:
CREATE TABLE nn_p2 (a int NOT NULL, b text) PARTITION BY LIST (a); ...
INSERT NULL
-> ERROR: null value in column "a" of relation "nn_p2d" violates
not-null constraint
(3) LIKE copying a plain NOT NULL source column into a partitioned table:
CREATE TABLE src2 (a int NOT NULL, b text);
CREATE TABLE nn_p3 (LIKE src2) PARTITION BY LIST (a); ... INSERT NULL
-> ERROR: null value in column "a" of relation "nn_p3d" violates
not-null constraint
So NO INHERIT is the specific trigger: the parent gets attnotnull = true
without enforcement or propagation to partitions, which is contradictory for
a partitioned table - inserts are routed to the partition and only checked
there, while the planner uses the parent's flag to prove that no NULLs can
exist.
Expected: either the NO INHERIT qualifier is rejected/ignored for a
partitioned table created via LIKE, or the constraint is enforced like every
other path. In any case "a IS NULL" and "a + 0 IS NULL" must not disagree.
| From | Date | Subject | |
|---|---|---|---|
| Next Message | PG Bug reporting form | 2026-10-29 06:26:24 | BUG #19809: oidvector index dedup still returns wrong results on 18.6; CTAS persists the corrupted rows |
| Previous Message | PG Bug reporting form | 2026-10-29 06:17:19 | BUG #19807: CHECK constraint not enforced on partitioned table when partition overrides a virtual generated colu |