diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index eba461c0f41..c3e9775539f 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -3155,12 +3155,15 @@ get_matching_range_bounds(PartitionPruneContext *context, * of smallest such bound) or find the smallest one that's * greater than the lookup values and set minoff to that. */ - while (off >= 1 && off < boundinfo->ndatums - 1) + while (true) { int32 cmpval; int nextoff; nextoff = inclusive ? off - 1 : off + 1; + + if (nextoff < 0 || nextoff >= boundinfo->ndatums) + break; cmpval = partition_rbound_datum_cmp(partsupfunc, partcollation, @@ -3214,16 +3217,21 @@ get_matching_range_bounds(PartitionPruneContext *context, if (off >= 0) { /* - * See the comment above. + * As above, check adjacent bounds to see if the bound is + * equal to the lookup value. */ if (is_equal && nvalues < partnatts) { - while (off >= 1 && off < boundinfo->ndatums - 1) + while (true) { int32 cmpval; int nextoff; nextoff = inclusive ? off + 1 : off - 1; + + if (nextoff < 0 || nextoff >= boundinfo->ndatums) + break; + cmpval = partition_rbound_datum_cmp(partsupfunc, partcollation, boundinfo->datums[nextoff], diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index ea3d764de2e..a0411c3e67d 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -1079,6 +1079,39 @@ explain (costs off) select * from mc2p where b is null; Filter: (b IS NULL) (2 rows) +create table mc2ap (a int, b int) partition by range (a, b); +create table mc2ap1 partition of mc2ap for values from (1, 4) to (1, 7); +create table mc2ap2 partition of mc2ap for values from (1, 7) to (3, 8); +create table mc2ap3 partition of mc2ap for values from (4, 8) to (6, 9); +create table mc2ap_def partition of mc2ap default; +-- Ensure we scan all partitions apart from mc2ap3 +explain (costs off) select count(*) from mc2ap where a <= 1; + QUERY PLAN +------------------------------------------- + Aggregate + -> Append + -> Seq Scan on mc2ap1 mc2ap_1 + Filter: (a <= 1) + -> Seq Scan on mc2ap2 mc2ap_2 + Filter: (a <= 1) + -> Seq Scan on mc2ap_def mc2ap_3 + Filter: (a <= 1) +(8 rows) + +drop table mc2ap; +create table mc2bp (c1 int, c2 int) partition by range (c1, c2); +create table mc2bp1 partition of mc2bp for values from (7, 2) to (7, 7); +create table mc2bp_def partition of mc2bp default; +-- Ensure mc2bp1 is pruned and we only scan mc2bp_def +explain (costs off) select count(*) from mc2bp where c1 > 7; + QUERY PLAN +----------------------------------- + Aggregate + -> Seq Scan on mc2bp_def mc2bp + Filter: (c1 > 7) +(3 rows) + +drop table mc2bp; -- boolean partitioning create table boolpart (a bool) partition by list (a); create table boolpart_default partition of boolpart default; diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index a445ee6d2da..09198881eef 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -173,6 +173,26 @@ explain (costs off) select * from mc2p where a is null and b = 1; explain (costs off) select * from mc2p where a is null; explain (costs off) select * from mc2p where b is null; +create table mc2ap (a int, b int) partition by range (a, b); +create table mc2ap1 partition of mc2ap for values from (1, 4) to (1, 7); +create table mc2ap2 partition of mc2ap for values from (1, 7) to (3, 8); +create table mc2ap3 partition of mc2ap for values from (4, 8) to (6, 9); +create table mc2ap_def partition of mc2ap default; + +-- Ensure we scan all partitions apart from mc2ap3 +explain (costs off) select count(*) from mc2ap where a <= 1; + +drop table mc2ap; + +create table mc2bp (c1 int, c2 int) partition by range (c1, c2); +create table mc2bp1 partition of mc2bp for values from (7, 2) to (7, 7); +create table mc2bp_def partition of mc2bp default; + +-- Ensure mc2bp1 is pruned and we only scan mc2bp_def +explain (costs off) select count(*) from mc2bp where c1 > 7; + +drop table mc2bp; + -- boolean partitioning create table boolpart (a bool) partition by list (a); create table boolpart_default partition of boolpart default;