Skip to content

Commit ee252f0

Browse files
committed
Fix failure to remove dependencies when a partition is detached.
Otherwise, dropping the partitioned table will automatically drop any previously-detached children, which would be unfortunate. Ashutosh Bapat and Rahila Syed, reviewed by Amit Langote and by me. Discussion: http://postgr.es/m/CAFjFpRdOwHuGj45i25iLQ4QituA0uH6RuLX1h5deD4KBZJ25yg@mail.gmail.com
1 parent 506b565 commit ee252f0

File tree

3 files changed

+44
-14
lines changed

3 files changed

+44
-14
lines changed

src/backend/commands/tablecmds.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ struct DropRelationCallbackState
283283
#define ATT_COMPOSITE_TYPE 0x0010
284284
#define ATT_FOREIGN_TABLE 0x0020
285285

286+
/*
287+
* Partition tables are expected to be dropped when the parent partitioned
288+
* table gets dropped. Hence for partitioning we use AUTO dependency.
289+
* Otherwise, for regular inheritance use NORMAL dependency.
290+
*/
291+
#define child_dependency_type(child_is_partition) \
292+
((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
293+
286294
static void truncate_check_rel(Relation rel);
287295
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
288296
bool is_partition, List **supOids, List **supconstr,
@@ -439,7 +447,8 @@ static void ATExecEnableDisableRule(Relation rel, char *rulename,
439447
static void ATPrepAddInherit(Relation child_rel);
440448
static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
441449
static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
442-
static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid);
450+
static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
451+
DependencyType deptype);
443452
static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
444453
static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
445454
static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode);
@@ -2367,14 +2376,8 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid,
23672376
childobject.objectId = relationId;
23682377
childobject.objectSubId = 0;
23692378

2370-
/*
2371-
* Partition tables are expected to be dropped when the parent partitioned
2372-
* table gets dropped.
2373-
*/
2374-
if (child_is_partition)
2375-
recordDependencyOn(&childobject, &parentobject, DEPENDENCY_AUTO);
2376-
else
2377-
recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
2379+
recordDependencyOn(&childobject, &parentobject,
2380+
child_dependency_type(child_is_partition));
23782381

23792382
/*
23802383
* Post creation hook of this inheritance. Since object_access_hook
@@ -11666,7 +11669,8 @@ RemoveInheritance(Relation child_rel, Relation parent_rel)
1166611669

1166711670
drop_parent_dependency(RelationGetRelid(child_rel),
1166811671
RelationRelationId,
11669-
RelationGetRelid(parent_rel));
11672+
RelationGetRelid(parent_rel),
11673+
child_dependency_type(child_is_partition));
1167011674

1167111675
/*
1167211676
* Post alter hook of this inherits. Since object_access_hook doesn't take
@@ -11686,7 +11690,8 @@ RemoveInheritance(Relation child_rel, Relation parent_rel)
1168611690
* through pg_depend.
1168711691
*/
1168811692
static void
11689-
drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
11693+
drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
11694+
DependencyType deptype)
1169011695
{
1169111696
Relation catalogRelation;
1169211697
SysScanDesc scan;
@@ -11718,7 +11723,7 @@ drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
1171811723
if (dep->refclassid == refclassid &&
1171911724
dep->refobjid == refobjid &&
1172011725
dep->refobjsubid == 0 &&
11721-
dep->deptype == DEPENDENCY_NORMAL)
11726+
dep->deptype == deptype)
1172211727
CatalogTupleDelete(catalogRelation, &depTuple->t_self);
1172311728
}
1172411729

@@ -11839,7 +11844,8 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
1183911844

1184011845
/* If the table was already typed, drop the existing dependency. */
1184111846
if (rel->rd_rel->reloftype)
11842-
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
11847+
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype,
11848+
DEPENDENCY_NORMAL);
1184311849

1184411850
/* Record a dependency on the new type. */
1184511851
tableobj.classId = RelationRelationId;
@@ -11892,7 +11898,8 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode)
1189211898
* table is presumed enough rights. No lock required on the type, either.
1189311899
*/
1189411900

11895-
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
11901+
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype,
11902+
DEPENDENCY_NORMAL);
1189611903

1189711904
/* Clear pg_class.reloftype */
1189811905
relationRelation = heap_open(RelationRelationId, RowExclusiveLock);

src/test/regress/expected/alter_table.out

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3385,6 +3385,19 @@ SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::r
33853385
(1 row)
33863386

33873387
DROP TABLE part_3_4;
3388+
-- check that a detached partition is not dropped on dropping a partitioned table
3389+
CREATE TABLE range_parted2 (
3390+
a int
3391+
) PARTITION BY RANGE(a);
3392+
CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
3393+
ALTER TABLE range_parted2 DETACH PARTITION part_rp;
3394+
DROP TABLE range_parted2;
3395+
SELECT * from part_rp;
3396+
a
3397+
---
3398+
(0 rows)
3399+
3400+
DROP TABLE part_rp;
33883401
-- Check ALTER TABLE commands for partitioned tables and partitions
33893402
-- cannot add/drop column to/from *only* the parent
33903403
ALTER TABLE ONLY list_parted2 ADD COLUMN c int;

src/test/regress/sql/alter_table.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2204,6 +2204,16 @@ SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::re
22042204
SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a';
22052205
DROP TABLE part_3_4;
22062206

2207+
-- check that a detached partition is not dropped on dropping a partitioned table
2208+
CREATE TABLE range_parted2 (
2209+
a int
2210+
) PARTITION BY RANGE(a);
2211+
CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
2212+
ALTER TABLE range_parted2 DETACH PARTITION part_rp;
2213+
DROP TABLE range_parted2;
2214+
SELECT * from part_rp;
2215+
DROP TABLE part_rp;
2216+
22072217
-- Check ALTER TABLE commands for partitioned tables and partitions
22082218

22092219
-- cannot add/drop column to/from *only* the parent

0 commit comments

Comments
 (0)