Skip to content

Commit fe1d16f

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 670fb9f commit fe1d16f

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
@@ -3849,6 +3849,14 @@ StorePartitionBound(Relation rel, Relation parent, PartitionBoundSpec *bound)
38493849
new_val, new_null, new_repl);
38503850
/* Also set the flag */
38513851
((Form_pg_class) GETSTRUCT(newtuple))->relispartition = true;
3852+
3853+
/*
3854+
* We already checked for no inheritance children, but reset
3855+
* relhassubclass in case it was left over.
3856+
*/
3857+
if (rel->rd_rel->relkind == RELKIND_RELATION && rel->rd_rel->relhassubclass)
3858+
((Form_pg_class) GETSTRUCT(newtuple))->relhassubclass = false;
3859+
38523860
CatalogTupleUpdate(classRel, &newtuple->t_self, newtuple);
38533861
heap_freetuple(newtuple);
38543862
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
@@ -3911,8 +3911,16 @@ ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1);
39113911
ERROR: cannot attach inheritance child as partition
39123912
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
39133913
ERROR: cannot attach inheritance parent as partition
3914+
DROP TABLE child;
3915+
-- now it should work, with a little tweak
3916+
ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0);
3917+
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
3918+
-- test insert/update, per bug #18550
3919+
INSERT INTO parent VALUES (1);
3920+
UPDATE parent SET a = 2 WHERE a = 1;
3921+
ERROR: new row for relation "parent" violates partition constraint
3922+
DETAIL: Failing row contains (2, null).
39143923
DROP TABLE parent CASCADE;
3915-
NOTICE: drop cascades to table child
39163924
-- check any TEMP-ness
39173925
CREATE TEMP TABLE temp_parted (a int) PARTITION BY LIST (a);
39183926
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
@@ -2413,6 +2413,13 @@ CREATE TABLE parent (LIKE list_parted);
24132413
CREATE TABLE child () INHERITS (parent);
24142414
ALTER TABLE list_parted ATTACH PARTITION child FOR VALUES IN (1);
24152415
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
2416+
DROP TABLE child;
2417+
-- now it should work, with a little tweak
2418+
ALTER TABLE parent ADD CONSTRAINT check_a CHECK (a > 0);
2419+
ALTER TABLE list_parted ATTACH PARTITION parent FOR VALUES IN (1);
2420+
-- test insert/update, per bug #18550
2421+
INSERT INTO parent VALUES (1);
2422+
UPDATE parent SET a = 2 WHERE a = 1;
24162423
DROP TABLE parent CASCADE;
24172424

24182425
-- check any TEMP-ness

0 commit comments

Comments
 (0)