Skip to content

Commit f74fac0

Browse files
committed
Reset relhassubclass upon attaching table as a partition
We don't allow inheritance parents as partitions, and have checks to prevent this; but if a table _was_ in the past an inheritance parents and all their children are removed, the pg_class.relhassubclass flag may remain set, which confuses the partition pruning code (most obviously, it results in an assertion failure; in production builds it may be worse.) Fix by resetting relhassubclass on attach. Backpatch to all supported versions. Reported-by: Alexander Lakhin <exclusion@gmail.com> Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://postgr.es/m/18550-d5e047e9a897a889@postgresql.org
1 parent 547dd2c commit f74fac0

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

src/backend/catalog/heap.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,14 @@ StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound)
35183518
new_val, new_null, new_repl);
35193519
/* Also set the flag */
35203520
((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3521+
3522+
/*
3523+
* We already checked for no inheritance children, but reset
3524+
* relhassubclass in case it was left over.
3525+
*/
3526+
if (rel->rd_rel->relkind == RELKIND_RELATION && rel->rd_rel->relhassubclass)
3527+
((Form_pg_class) GETSTRUCT(newtuple))->relhassubclass = false;
3528+
35213529
CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
35223530
heap_freetuple(newtuple);
35233531
table_close(classRel, RowExclusiveLock);

src/test/regress/expected/alter_table.out

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3909,8 +3909,16 @@ ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1);
39093909
ERROR: cannot attach inheritance child as partition
39103910
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
39113911
ERROR: cannot attach inheritance parent as partition
3912+
DROP TABLE child;
3913+
-- now it should work, with a little tweak
3914+
ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0);
3915+
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
3916+
-- test insert/update, per bug #18550
3917+
INSERT INTO parent VALUES (1);
3918+
UPDATE parent SET a = 2 WHERE a = 1;
3919+
ERROR: new row for relation "parent" violates partition constraint
3920+
DETAIL: Failing row contains (2, null).
39123921
DROP TABLE parent CASCADE;
3913-
NOTICE: drop cascades to table child
39143922
-- check any TEMP-ness
39153923
CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a);
39163924
CREATE TABLE perm_part (a int);

src/test/regress/sql/alter_table.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2410,6 +2410,13 @@ CREATE TABLE parent (LIKE list_parted);
24102410
CREATE TABLE child () INHERITS (parent);
24112411
ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1);
24122412
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
2413+
DROP TABLE child;
2414+
-- now it should work, with a little tweak
2415+
ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0);
2416+
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
2417+
-- test insert/update, per bug #18550
2418+
INSERT INTO parent VALUES (1);
2419+
UPDATE parent SET a = 2 WHERE a = 1;
24132420
DROP TABLE parent CASCADE;
24142421

24152422
-- check any TEMP-ness

0 commit comments

Comments
 (0)