Allow partitioned tables to be dropped without CASCADE
authorSimon Riggs <simon@2ndQuadrant.com>
Mon, 6 Mar 2017 10:20:53 +0000 (15:50 +0530)
committerSimon Riggs <simon@2ndQuadrant.com>
Mon, 6 Mar 2017 10:20:53 +0000 (15:50 +0530)
Record partitioned table dependencies as DEPENDENCY_AUTO
rather than DEPENDENCY_NORMAL, so that DROP TABLE just works.

Remove all the tests for partitioned tables where earlier
work had deliberately avoided using CASCADE.

Amit Langote, reviewed by Ashutosh Bapat and myself

src/backend/commands/tablecmds.c
src/test/regress/expected/alter_table.out
src/test/regress/expected/create_table.out
src/test/regress/expected/inherit.out
src/test/regress/expected/insert.out
src/test/regress/expected/update.out
src/test/regress/sql/alter_table.sql
src/test/regress/sql/create_table.sql
src/test/regress/sql/inherit.sql
src/test/regress/sql/insert.sql
src/test/regress/sql/update.sql

index 35b863169178c2920e5d9bfe5bbe38ee5c950af0..6904d5c07a18bc48b0d781349d56fdc82fd9f2e4 100644 (file)
@@ -289,9 +289,11 @@ static List *MergeAttributes(List *schema, List *supers, char relpersistence,
 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
-static void StoreCatalogInheritance(Oid relationId, List *supers);
+static void StoreCatalogInheritance(Oid relationId, List *supers,
+                       bool child_is_partition);
 static void StoreCatalogInheritance1(Oid relationId, Oid parentOid,
-                        int16 seqNumber, Relation inhRelation);
+                        int16 seqNumber, Relation inhRelation,
+                        bool child_is_partition);
 static int findAttrByName(const char *attributeName, List *schema);
 static void AlterIndexNamespaces(Relation classRel, Relation rel,
                   Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved);
@@ -725,7 +727,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
                                          typaddress);
 
    /* Store inheritance information for new rel. */
-   StoreCatalogInheritance(relationId, inheritOids);
+   StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL);
 
    /*
     * We must bump the command counter to make the newly-created relation
@@ -2248,7 +2250,8 @@ MergeCheckConstraint(List *constraints, char *name, Node *expr)
  * supers is a list of the OIDs of the new relation's direct ancestors.
  */
 static void
-StoreCatalogInheritance(Oid relationId, List *supers)
+StoreCatalogInheritance(Oid relationId, List *supers,
+                       bool child_is_partition)
 {
    Relation    relation;
    int16       seqNumber;
@@ -2278,7 +2281,8 @@ StoreCatalogInheritance(Oid relationId, List *supers)
    {
        Oid         parentOid = lfirst_oid(entry);
 
-       StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation);
+       StoreCatalogInheritance1(relationId, parentOid, seqNumber, relation,
+                                child_is_partition);
        seqNumber++;
    }
 
@@ -2291,7 +2295,8 @@ StoreCatalogInheritance(Oid relationId, List *supers)
  */
 static void
 StoreCatalogInheritance1(Oid relationId, Oid parentOid,
-                        int16 seqNumber, Relation inhRelation)
+                        int16 seqNumber, Relation inhRelation,
+                        bool child_is_partition)
 {
    TupleDesc   desc = RelationGetDescr(inhRelation);
    Datum       values[Natts_pg_inherits];
@@ -2325,7 +2330,14 @@ StoreCatalogInheritance1(Oid relationId, Oid parentOid,
    childobject.objectId = relationId;
    childobject.objectSubId = 0;
 
-   recordDependencyOn(&childobject, &parentobject, DEPENDENCY_NORMAL);
+   /*
+    * 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);
 
    /*
     * Post creation hook of this inheritance. Since object_access_hook
@@ -10753,7 +10765,9 @@ CreateInheritance(Relation child_rel, Relation parent_rel)
    StoreCatalogInheritance1(RelationGetRelid(child_rel),
                             RelationGetRelid(parent_rel),
                             inhseqno + 1,
-                            catalogRelation);
+                            catalogRelation,
+                            parent_rel->rd_rel->relkind ==
+                                           RELKIND_PARTITIONED_TABLE);
 
    /* Now we're done with pg_inherits */
    heap_close(catalogRelation, RowExclusiveLock);
index 9885fcba89cbbc7ecb96cd0145927ce1b9408359..c15bbdcbd1477d2dcc8c0d358c711c626ac0c90b 100644 (file)
@@ -3339,10 +3339,8 @@ ALTER TABLE list_parted2 DROP COLUMN b;
 ERROR:  cannot drop column named in partition key
 ALTER TABLE list_parted2 ALTER COLUMN b TYPE text;
 ERROR:  cannot alter type of column named in partition key
--- cleanup: avoid using CASCADE
-DROP TABLE list_parted, part_1;
-DROP TABLE list_parted2, part_2, part_5, part_5_a;
-DROP TABLE range_parted, part1, part2;
+-- cleanup
+DROP TABLE list_parted, list_parted2, range_parted;
 -- more tests for certain multi-level partitioning scenarios
 create table p (a int, b int) partition by range (a, b);
 create table p1 (b int, a int not null) partition by range (b);
@@ -3371,5 +3369,5 @@ insert into p1 (a, b) values (2, 3);
 -- check that partition validation scan correctly detects violating rows
 alter table p attach partition p1 for values from (1, 2) to (1, 10);
 ERROR:  partition constraint is violated by some row
--- cleanup: avoid using CASCADE
-drop table p, p1, p11;
+-- cleanup
+drop table p;
index 20eb3d35f9de0addc7ff576b9b778829229197cc..c07a474b3d8d0fbb4a096753f0b7b5f3baad188e 100644 (file)
@@ -667,10 +667,5 @@ Check constraints:
     "check_a" CHECK (length(a) > 0)
 Number of partitions: 3 (Use \d+ to list them.)
 
--- cleanup: avoid using CASCADE
-DROP TABLE parted, part_a, part_b, part_c, part_c_1_10;
-DROP TABLE list_parted, part_1, part_2, part_null;
-DROP TABLE range_parted;
-DROP TABLE list_parted2, part_ab, part_null_z;
-DROP TABLE range_parted2, part0, part1, part2, part3;
-DROP TABLE range_parted3, part00, part10, part11, part12;
+-- cleanup
+DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3;
index a8c8b28a75e7bc50cf45e884c74c5d7911c5e6d2..795d9f575c66c5ee5d9301efb79a9c515a1f3016 100644 (file)
@@ -1843,23 +1843,5 @@ explain (costs off) select * from range_list_parted where a >= 30;
          Filter: (a >= 30)
 (11 rows)
 
-drop table list_parted cascade;
-NOTICE:  drop cascades to 3 other objects
-DETAIL:  drop cascades to table part_ab_cd
-drop cascades to table part_ef_gh
-drop cascades to table part_null_xy
-drop table range_list_parted cascade;
-NOTICE:  drop cascades to 13 other objects
-DETAIL:  drop cascades to table part_1_10
-drop cascades to table part_1_10_ab
-drop cascades to table part_1_10_cd
-drop cascades to table part_10_20
-drop cascades to table part_10_20_ab
-drop cascades to table part_10_20_cd
-drop cascades to table part_21_30
-drop cascades to table part_21_30_ab
-drop cascades to table part_21_30_cd
-drop cascades to table part_40_inf
-drop cascades to table part_40_inf_ab
-drop cascades to table part_40_inf_cd
-drop cascades to table part_40_inf_null
+drop table list_parted;
+drop table range_list_parted;
index 397238332b8d614aee182e5beb215fa5be6a2b16..d16880fa2d521cee8a78e3de5b2357f504530ade 100644 (file)
@@ -314,10 +314,7 @@ select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_p
 (9 rows)
 
 -- cleanup
-drop table part1, part2, part3, part4, range_parted;
-drop table part_ee_ff3_1, part_ee_ff3_2, part_ee_ff1, part_ee_ff2, part_ee_ff3;
-drop table part_ee_ff, part_gg2_2, part_gg2_1, part_gg2, part_gg1, part_gg;
-drop table part_aa_bb, part_cc_dd, part_null, list_parted;
+drop table range_parted, list_parted;
 -- more tests for certain multi-level partitioning scenarios
 create table p (a int, b int) partition by range (a, b);
 create table p1 (b int not null, a int not null) partition by range ((b+0));
@@ -417,4 +414,4 @@ revoke all on key_desc_1 from someone_else;
 drop role someone_else;
 drop table key_desc, key_desc_1;
 -- cleanup
-drop table p, p1, p11, p12, p2, p3, p4;
+drop table p;
index a1e92554505574c3c7cf206f61fba1011f836b10..9366f04255cb530de588b5a86f8338161924ca3e 100644 (file)
@@ -219,9 +219,4 @@ DETAIL:  Failing row contains (b, 9).
 -- ok
 update range_parted set b = b + 1 where b = 10;
 -- cleanup
-drop table range_parted cascade;
-NOTICE:  drop cascades to 4 other objects
-DETAIL:  drop cascades to table part_a_1_a_10
-drop cascades to table part_a_10_a_20
-drop cascades to table part_b_1_b_10
-drop cascades to table part_b_10_b_20
+drop table range_parted;
index f7b754f0beeae160f1801a0204c0d626a84640ea..37f327bf6d58bdd1eeb2b1c518ac719d1598806f 100644 (file)
@@ -2199,10 +2199,8 @@ ALTER TABLE part_2 INHERIT inh_test;
 ALTER TABLE list_parted2 DROP COLUMN b;
 ALTER TABLE list_parted2 ALTER COLUMN b TYPE text;
 
--- cleanup: avoid using CASCADE
-DROP TABLE list_parted, part_1;
-DROP TABLE list_parted2, part_2, part_5, part_5_a;
-DROP TABLE range_parted, part1, part2;
+-- cleanup
+DROP TABLE list_parted, list_parted2, range_parted;
 
 -- more tests for certain multi-level partitioning scenarios
 create table p (a int, b int) partition by range (a, b);
@@ -2227,5 +2225,5 @@ insert into p1 (a, b) values (2, 3);
 -- check that partition validation scan correctly detects violating rows
 alter table p attach partition p1 for values from (1, 2) to (1, 10);
 
--- cleanup: avoid using CASCADE
-drop table p, p1, p11;
+-- cleanup
+drop table p;
index f41dd714751ff05099b134d8f8cec9342dcf6e90..1f0fa8e16d8ee1be31c3d78565492c1e8f3b671c 100644 (file)
@@ -595,10 +595,5 @@ CREATE TABLE part_c_1_10 PARTITION OF part_c FOR VALUES FROM (1) TO (10);
 -- returned.
 \d parted
 
--- cleanup: avoid using CASCADE
-DROP TABLE parted, part_a, part_b, part_c, part_c_1_10;
-DROP TABLE list_parted, part_1, part_2, part_null;
-DROP TABLE range_parted;
-DROP TABLE list_parted2, part_ab, part_null_z;
-DROP TABLE range_parted2, part0, part1, part2, part3;
-DROP TABLE range_parted3, part00, part10, part11, part12;
+-- cleanup
+DROP TABLE parted, list_parted, range_parted, list_parted2, range_parted2, range_parted3;
index a8b7eb1c8da4c6d6b87dc1324d9daf6683b54187..836ec22c204b4ea129d79fbe0d79b1de8c67697b 100644 (file)
@@ -612,5 +612,5 @@ explain (costs off) select * from range_list_parted where b is null;
 explain (costs off) select * from range_list_parted where a is not null and a < 67;
 explain (costs off) select * from range_list_parted where a >= 30;
 
-drop table list_parted cascade;
-drop table range_list_parted cascade;
+drop table list_parted;
+drop table range_list_parted;
index 4f19df5c25cc8c58fcd15ca6a2b5103290f06a5d..b0b552bd993350c984cab5f0e776eeb1e6044d1c 100644 (file)
@@ -186,10 +186,7 @@ insert into list_parted (b) values (1);
 select tableoid::regclass::text, a, min(b) as min_b, max(b) as max_b from list_parted group by 1, 2 order by 1;
 
 -- cleanup
-drop table part1, part2, part3, part4, range_parted;
-drop table part_ee_ff3_1, part_ee_ff3_2, part_ee_ff1, part_ee_ff2, part_ee_ff3;
-drop table part_ee_ff, part_gg2_2, part_gg2_1, part_gg2, part_gg1, part_gg;
-drop table part_aa_bb, part_cc_dd, part_null, list_parted;
+drop table range_parted, list_parted;
 
 -- more tests for certain multi-level partitioning scenarios
 create table p (a int, b int) partition by range (a, b);
@@ -271,4 +268,4 @@ drop role someone_else;
 drop table key_desc, key_desc_1;
 
 -- cleanup
-drop table p, p1, p11, p12, p2, p3, p4;
+drop table p;
index d7721ed37602d3ea1fdeb829d237df197266d683..663711997b00952e1e9f0f3e7e54ac1d77f100a1 100644 (file)
@@ -126,4 +126,4 @@ update range_parted set b = b - 1 where b = 10;
 update range_parted set b = b + 1 where b = 10;
 
 -- cleanup
-drop table range_parted cascade;
+drop table range_parted;