BUG #19808: NOT NULL NO INHERIT copied by CREATE TABLE (LIKE) not enforced on partitioned table

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.

Browse pgsql-bugs by date

  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