From 9866884c26e2bb4b08b50069472149fba8c7b4c9 Mon Sep 17 00:00:00 2001 From: Jeevan Ladhe Date: Thu, 14 Sep 2017 13:31:08 +0530 Subject: [PATCH 1/1] Check default partitition child validation scan is skippable Optimize check_default_allows_bound() such that the default partition children constraints are checked against new partition constraints for implication and avoid scan of the child of which existing constraints are implied by new default partition constraints. Also, added testcase for the same. Jeevan Ladhe. --- src/backend/catalog/partition.c | 14 ++++++++++++++ src/test/regress/expected/alter_table.out | 14 ++++++++++++-- src/test/regress/sql/alter_table.sql | 9 +++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 73eff17..919b6b2 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -951,7 +951,21 @@ 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); + + /* Can we skip scanning this part_rel? */ + 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; diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 0478a8a..32c4fda 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -3346,6 +3346,18 @@ INFO: partition constraint for table "part_3_4" is implied by existing constrai ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6)); CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66); INFO: partition constraint for table "list_parted2_def" is implied by existing constraints +-- check if default partition child relation scan skipped +DROP TABLE list_parted2_def; +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT PARTITION BY RANGE (a); +CREATE TABLE list_parted2_def_p1 PARTITION OF list_parted2_def FOR VALUES FROM (21) TO (30); +CREATE TABLE list_parted2_def_p2 PARTITION OF list_parted2_def FOR VALUES FROM (31) TO (40); +ALTER TABLE list_parted2_def_p1 ADD CONSTRAINT check_a CHECK (a IN (21, 22)); +ALTER TABLE list_parted2_def_p2 ADD CONSTRAINT check_a CHECK (a IN (31, 32)); +CREATE TABLE part_9 PARTITION OF list_parted2 FOR VALUES IN (9); +INFO: partition constraint for table "list_parted2_def_p1" is implied by existing constraints +INFO: partition constraint for table "list_parted2_def_p2" is implied by existing constraints +CREATE TABLE part_31 PARTITION OF list_parted2 FOR VALUES IN (31); +INFO: partition constraint for table "list_parted2_def_p1" is implied by existing constraints -- check validation when attaching range partitions CREATE TABLE range_parted ( a int, @@ -3436,7 +3448,6 @@ ALTER TABLE part_7 ATTACH PARTITION part_7_a_null FOR VALUES IN ('a', null); INFO: partition constraint for table "part_7_a_null" is implied by existing constraints ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7); INFO: partition constraint for table "part_7" is implied by existing constraints -INFO: partition constraint for table "list_parted2_def" is implied by existing constraints -- Same example, but check this time that the constraint correctly detects -- violating rows ALTER TABLE list_parted2 DETACH PARTITION part_7; @@ -3450,7 +3461,6 @@ SELECT tableoid::regclass, a, b FROM part_7 order by a; (2 rows) ALTER TABLE list_parted2 ATTACH PARTITION part_7 FOR VALUES IN (7); -INFO: partition constraint for table "list_parted2_def" is implied by existing constraints ERROR: partition constraint is violated by some row -- check that leaf partitions of default partition are scanned when -- attaching a partitioned table. diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 37cca72..3ad6302 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -2163,6 +2163,15 @@ ALTER TABLE list_parted2 ATTACH PARTITION part_3_4 FOR VALUES IN (3, 4); -- check if default partition scan skipped ALTER TABLE list_parted2_def ADD CONSTRAINT check_a CHECK (a IN (5, 6)); CREATE TABLE part_55_66 PARTITION OF list_parted2 FOR VALUES IN (55, 66); +-- check if default partition child relation scan skipped +DROP TABLE list_parted2_def; +CREATE TABLE list_parted2_def PARTITION OF list_parted2 DEFAULT PARTITION BY RANGE (a); +CREATE TABLE list_parted2_def_p1 PARTITION OF list_parted2_def FOR VALUES FROM (21) TO (30); +CREATE TABLE list_parted2_def_p2 PARTITION OF list_parted2_def FOR VALUES FROM (31) TO (40); +ALTER TABLE list_parted2_def_p1 ADD CONSTRAINT check_a CHECK (a IN (21, 22)); +ALTER TABLE list_parted2_def_p2 ADD CONSTRAINT check_a CHECK (a IN (31, 32)); +CREATE TABLE part_9 PARTITION OF list_parted2 FOR VALUES IN (9); +CREATE TABLE part_31 PARTITION OF list_parted2 FOR VALUES IN (31); -- check validation when attaching range partitions CREATE TABLE range_parted ( -- 2.7.4