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
This commit is contained in:
parent
506b565831
commit
ee252f074b
@ -283,6 +283,14 @@ struct DropRelationCallbackState
|
||||
#define ATT_COMPOSITE_TYPE 0x0010
|
||||
#define ATT_FOREIGN_TABLE 0x0020
|
||||
|
||||
/*
|
||||
* Partition tables are expected to be dropped when the parent partitioned
|
||||
* table gets dropped. Hence for partitioning we use AUTO dependency.
|
||||
* Otherwise, for regular inheritance use NORMAL dependency.
|
||||
*/
|
||||
#define child_dependency_type(child_is_partition) \
|
||||
((child_is_partition) ? DEPENDENCY_AUTO : DEPENDENCY_NORMAL)
|
||||
|
||||
static void truncate_check_rel(Relation rel);
|
||||
static List *MergeAttributes(List *schema, List *supers, char relpersistence,
|
||||
bool is_partition, List **supOids, List **supconstr,
|
||||
@ -439,7 +447,8 @@ static void ATExecEnableDisableRule(Relation rel, char *rulename,
|
||||
static void ATPrepAddInherit(Relation child_rel);
|
||||
static ObjectAddress ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode);
|
||||
static ObjectAddress ATExecDropInherit(Relation rel, RangeVar *parent, LOCKMODE lockmode);
|
||||
static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid);
|
||||
static void drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
|
||||
DependencyType deptype);
|
||||
static ObjectAddress ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode);
|
||||
static void ATExecDropOf(Relation rel, LOCKMODE lockmode);
|
||||
static void ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode);
|
||||
@ -2367,14 +2376,8 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid,
|
||||
childobject.objectId = relationId;
|
||||
childobject.objectSubId = 0;
|
||||
|
||||
/*
|
||||
* Partition tables are expected to be dropped when the parent partitioned
|
||||
* table gets dropped.
|
||||
*/
|
||||
if (child_is_partition)
|
||||
recordDependencyOn(&childobject, &parentobject, DEPENDENCY_AUTO);
|
||||
else
|
||||
recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
|
||||
recordDependencyOn(&childobject, &parentobject,
|
||||
child_dependency_type(child_is_partition));
|
||||
|
||||
/*
|
||||
* Post creation hook of this inheritance. Since object_access_hook
|
||||
@ -11666,7 +11669,8 @@ RemoveInheritance(Relation child_rel, Relation parent_rel)
|
||||
|
||||
drop_parent_dependency(RelationGetRelid(child_rel),
|
||||
RelationRelationId,
|
||||
RelationGetRelid(parent_rel));
|
||||
RelationGetRelid(parent_rel),
|
||||
child_dependency_type(child_is_partition));
|
||||
|
||||
/*
|
||||
* Post alter hook of this inherits. Since object_access_hook doesn't take
|
||||
@ -11686,7 +11690,8 @@ RemoveInheritance(Relation child_rel, Relation parent_rel)
|
||||
* through pg_depend.
|
||||
*/
|
||||
static void
|
||||
drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
|
||||
drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid,
|
||||
DependencyType deptype)
|
||||
{
|
||||
Relation catalogRelation;
|
||||
SysScanDesc scan;
|
||||
@ -11718,7 +11723,7 @@ drop_parent_dependency(Oid relid, Oid refclassid, Oid refobjid)
|
||||
if (dep->refclassid == refclassid &&
|
||||
dep->refobjid == refobjid &&
|
||||
dep->refobjsubid == 0 &&
|
||||
dep->deptype == DEPENDENCY_NORMAL)
|
||||
dep->deptype == deptype)
|
||||
CatalogTupleDelete(catalogRelation, &depTuple->t_self);
|
||||
}
|
||||
|
||||
@ -11839,7 +11844,8 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
|
||||
|
||||
/* If the table was already typed, drop the existing dependency. */
|
||||
if (rel->rd_rel->reloftype)
|
||||
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
|
||||
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype,
|
||||
DEPENDENCY_NORMAL);
|
||||
|
||||
/* Record a dependency on the new type. */
|
||||
tableobj.classId = RelationRelationId;
|
||||
@ -11892,7 +11898,8 @@ ATExecDropOf(Relation rel, LOCKMODE lockmode)
|
||||
* table is presumed enough rights. No lock required on the type, either.
|
||||
*/
|
||||
|
||||
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype);
|
||||
drop_parent_dependency(relid, TypeRelationId, rel->rd_rel->reloftype,
|
||||
DEPENDENCY_NORMAL);
|
||||
|
||||
/* Clear pg_class.reloftype */
|
||||
relationRelation = heap_open(RelationRelationId, RowExclusiveLock);
|
||||
|
@ -3385,6 +3385,19 @@ SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::r
|
||||
(1 row)
|
||||
|
||||
DROP TABLE part_3_4;
|
||||
-- check that a detached partition is not dropped on dropping a partitioned table
|
||||
CREATE TABLE range_parted2 (
|
||||
a int
|
||||
) PARTITION BY RANGE(a);
|
||||
CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
|
||||
ALTER TABLE range_parted2 DETACH PARTITION part_rp;
|
||||
DROP TABLE range_parted2;
|
||||
SELECT * from part_rp;
|
||||
a
|
||||
---
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE part_rp;
|
||||
-- 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;
|
||||
|
@ -2204,6 +2204,16 @@ SELECT attinhcount, attislocal FROM pg_attribute WHERE attrelid = 'part_3_4'::re
|
||||
SELECT coninhcount, conislocal FROM pg_constraint WHERE conrelid = 'part_3_4'::regclass AND conname = 'check_a';
|
||||
DROP TABLE part_3_4;
|
||||
|
||||
-- check that a detached partition is not dropped on dropping a partitioned table
|
||||
CREATE TABLE range_parted2 (
|
||||
a int
|
||||
) PARTITION BY RANGE(a);
|
||||
CREATE TABLE part_rp PARTITION OF range_parted2 FOR VALUES FROM (0) to (100);
|
||||
ALTER TABLE range_parted2 DETACH PARTITION part_rp;
|
||||
DROP TABLE range_parted2;
|
||||
SELECT * from part_rp;
|
||||
DROP TABLE part_rp;
|
||||
|
||||
-- Check ALTER TABLE commands for partitioned tables and partitions
|
||||
|
||||
-- cannot add/drop column to/from *only* the parent
|
||||
|
Loading…
x
Reference in New Issue
Block a user