On CREATE TABLE, consider skipping validation of subpartitions.
authorRobert Haas <rhaas@postgresql.org>
Thu, 5 Oct 2017 17:21:50 +0000 (13:21 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 5 Oct 2017 17:23:28 +0000 (13:23 -0400)
This is just like commit 14f67a8ee282ebc0de78e773fbd597f460ab4a54, but
for CREATE PARTITION rather than ATTACH PARTITION.

Jeevan Ladhe, with test case changes by me.

Discussion: http://postgr.es/m/CAOgcT0MWwG8WBw8frFMtRYHAgDD=tpt6U7WcsO_L2k0KYpm4Jg@mail.gmail.com

src/backend/catalog/partition.c
src/test/regress/expected/alter_table.out
src/test/regress/sql/alter_table.sql

index 9777d40e663bb86e44f89804661fdb53a53e7422..3a8306a0552fe9295f98dc093a5929dd6c3e8231 100644 (file)
@@ -953,7 +953,25 @@ check_default_allows_bound(Relation parent, Relation default_rel,
 
                /* Lock already taken above. */
                if (part_relid != RelationGetRelid(default_rel))
+               {
                        part_rel = heap_open(part_relid, NoLock);
+
+                       /*
+                        * If the partition constraints on default partition child imply
+                        * that it will not contain any row that would belong to the new
+                        * partition, we can avoid scanning the child table.
+                        */
+                       if (PartConstraintImpliedByRelConstraint(part_rel,
+                                                                                                        def_part_constraints))
+                       {
+                               ereport(INFO,
+                                               (errmsg("partition constraint for table \"%s\" is implied by existing constraints",
+                                                               RelationGetRelationName(part_rel))));
+
+                               heap_close(part_rel, NoLock);
+                               continue;
+                       }
+               }
                else
                        part_rel = default_rel;
 
index cda8ce556cb3d232a49b0fc24495037945bade3d..dbe438dcd4b25bbe3b4480bbf4beb3351c1366c9 100644 (file)
@@ -3474,9 +3474,10 @@ DETAIL:  "part_5" is already a child of "list_parted2".
 ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0);
 ERROR:  circular inheritance not allowed
 DETAIL:  "list_parted2" is already a child of "list_parted2".
--- If the partitioned table being attached does not have a constraint that
--- would allow validation scan to be skipped, but an individual partition
--- does, then the partition's validation scan is skipped.
+-- If a partitioned table being created or an existing table being attached
+-- as a paritition does not have a constraint that would allow validation scan
+-- to be skipped, but an individual partition does, then the partition's
+-- validation scan is skipped.
 CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a);
 CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b);
 CREATE TABLE quuux_default1 PARTITION OF quuux_default (
@@ -3487,6 +3488,11 @@ ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1); -- validate!
 CREATE TABLE quuux2 (a int, b text);
 ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2); -- skip validation
 INFO:  updated partition constraint for default partition "quuux_default1" is implied by existing constraints
+DROP TABLE quuux1, quuux2;
+-- should validate for quuux1, but not for quuux2
+CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1);
+CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2);
+INFO:  partition constraint for table "quuux_default1" is implied by existing constraints
 DROP TABLE quuux;
 --
 -- DETACH PARTITION
index d0daacf3e9a38c0e45faca71c30ed75b0a9e464e..0c8ae2ab970719a51523142f553db2e6edc433df 100644 (file)
@@ -2285,9 +2285,10 @@ ALTER TABLE list_parted2 ATTACH PARTITION part_2 FOR VALUES IN (2);
 ALTER TABLE part_5 ATTACH PARTITION list_parted2 FOR VALUES IN ('b');
 ALTER TABLE list_parted2 ATTACH PARTITION list_parted2 FOR VALUES IN (0);
 
--- If the partitioned table being attached does not have a constraint that
--- would allow validation scan to be skipped, but an individual partition
--- does, then the partition's validation scan is skipped.
+-- If a partitioned table being created or an existing table being attached
+-- as a paritition does not have a constraint that would allow validation scan
+-- to be skipped, but an individual partition does, then the partition's
+-- validation scan is skipped.
 CREATE TABLE quuux (a int, b text) PARTITION BY LIST (a);
 CREATE TABLE quuux_default PARTITION OF quuux DEFAULT PARTITION BY LIST (b);
 CREATE TABLE quuux_default1 PARTITION OF quuux_default (
@@ -2297,6 +2298,10 @@ CREATE TABLE quuux1 (a int, b text);
 ALTER TABLE quuux ATTACH PARTITION quuux1 FOR VALUES IN (1); -- validate!
 CREATE TABLE quuux2 (a int, b text);
 ALTER TABLE quuux ATTACH PARTITION quuux2 FOR VALUES IN (2); -- skip validation
+DROP TABLE quuux1, quuux2;
+-- should validate for quuux1, but not for quuux2
+CREATE TABLE quuux1 PARTITION OF quuux FOR VALUES IN (1);
+CREATE TABLE quuux2 PARTITION OF quuux FOR VALUES IN (2);
 DROP TABLE quuux;
 
 --