diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 011bb4acddb..d8352f63273 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -20870,13 +20870,14 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, Relation partRel; ObjectAddress address; Oid defaultPartOid; + PartitionDesc partdesc; /* * We must lock the default partition, because detaching this partition * will change its partition constraint. */ - defaultPartOid = - get_default_oid_from_partdesc(RelationGetPartitionDesc(rel, true)); + partdesc = RelationGetPartitionDesc(rel, true); + defaultPartOid = get_default_oid_from_partdesc(partdesc); if (OidIsValid(defaultPartOid)) { /* @@ -20943,10 +20944,13 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, char *partrelname; /* - * Add a new constraint to the partition being detached, which - * supplants the partition constraint (unless there is one already). + * For strategies other than hash, add a constraint to the partition + * being detached which supplants the partition constraint. For hash + * we cannot do that, because the constraint would reference the + * partitioned table OID, possibly causing problems later. */ - DetachAddConstraintIfNeeded(wqueue, partRel); + if (partdesc->boundinfo->strategy != PARTITION_STRATEGY_HASH) + DetachAddConstraintIfNeeded(wqueue, partRel); /* * We're almost done now; the only traces that remain are the diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index b33e06a0d3d..11dbb0426f1 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -4490,6 +4490,14 @@ Check constraints: "part_rp100_a_check" CHECK (a >= 123 AND a < 133 AND a IS NOT NULL) DROP TABLE range_parted2; +-- Test that hash partitions continue to work after they're concurrently +-- detached (bugs #18371, #19070) +CREATE TABLE hash_parted2 (a int) PARTITION BY HASH(a); +CREATE TABLE part_hp PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +ALTER TABLE hash_parted2 DETACH PARTITION part_hp CONCURRENTLY; +DROP TABLE hash_parted2; +INSERT INTO part_hp VALUES (1); +DROP TABLE part_hp; -- Check ALTER TABLE commands for partitioned tables and partitions -- cannot add/drop column to/from *only* the parent ALTER TABLE ONLY list_parted2 ADD COLUMN c int; diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 90bf5c17682..f1a7d776013 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2834,6 +2834,15 @@ ALTER TABLE range_parted2 DETACH PARTITION part_rp100 CONCURRENTLY; \d part_rp100 DROP TABLE range_parted2; +-- Test that hash partitions continue to work after they're concurrently +-- detached (bugs #18371, #19070) +CREATE TABLE hash_parted2 (a int) PARTITION BY HASH(a); +CREATE TABLE part_hp PARTITION OF hash_parted2 FOR VALUES WITH (MODULUS 2, REMAINDER 0); +ALTER TABLE hash_parted2 DETACH PARTITION part_hp CONCURRENTLY; +DROP TABLE hash_parted2; +INSERT INTO part_hp VALUES (1); +DROP TABLE part_hp; + -- Check ALTER TABLE commands for partitioned tables and partitions -- cannot add/drop column to/from *only* the parent