[PATCH] Fix default partition validation for reordered child columns

Started by CharSyam19 days ago1 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t254050
psql -h localhost -U postgres

Built from patchset v1 (message #1), October 23, 2026 at 12:58 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t254050_1 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t254050_1 && git checkout t254050_1

Patchset v1 (message #1) is on t254050_1

Jump to latest
#1CharSyam
charsyam@gmail.com

Hi, Hackers.

I found a case where adding a partition succeeds even though a child of
its default partition contains a row that belongs to the new partition.
The row then becomes invisible to queries that prune the default
partition.

Here is a reproducer on current master:

CREATE TABLE defmap (a int, b int) PARTITION BY LIST (a);
CREATE TABLE defmap_def PARTITION OF defmap DEFAULT
PARTITION BY RANGE (b);
CREATE TABLE defmap_child (b int CHECK (b > 0), a int);
ALTER TABLE defmap_def ATTACH PARTITION defmap_child
FOR VALUES FROM (1) TO (100);
INSERT INTO defmap VALUES (0, 2);

CREATE TABLE defmap_0 PARTITION OF defmap FOR VALUES IN (0);
SELECT tableoid::regclass, a, b FROM defmap WHERE a = 0;
SELECT a, b FROM defmap_child WHERE a = 0;

Without the patch, CREATE TABLE succeeds. The query through defmap
returns no rows, while the direct query against defmap_child returns
(0, 2). The CREATE TABLE statement should instead fail because the
row already belongs to the proposed new partition.

check_default_partition_contents() maps the updated default constraint
to the child table's attribute numbers before scanning it. However,
its PartConstraintImpliedByRelConstraint() call receives the unmapped
constraint. With the reordered columns above, it compares the child's
CHECK (b > 0) against a condition intended for a, concludes that the
scan is unnecessary, and misses the conflicting row.

The attached patch uses the mapped constraint for both the implication
check and the scan, and adds this case to create_table's regression
tests. The child-side mapping was introduced in 23cccb17fe0 for the
scan, but was not used for the implication check.

I ran make -C src/test/regress check; all 239 tests passed.

Attachments:

t254050_1
0001-Fix-default-partition-validation-for-reordered-child-columns.patchapplication/octet-stream; name=0001-Fix-default-partition-validation-for-reordered-child-columns.patchDownload+34-6