diff options
-rw-r--r-- | src/backend/executor/execPartition.c | 29 | ||||
-rw-r--r-- | src/test/regress/expected/partition_prune.out | 24 | ||||
-rw-r--r-- | src/test/regress/sql/partition_prune.sql | 24 |
3 files changed, 62 insertions, 15 deletions
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 4698f74f910..873e65f3f6d 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -1888,7 +1888,7 @@ ExecInitPruningContext(PartitionPruneContext *context, foreach(lc, pruning_steps) { PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc); - ListCell *lc2; + ListCell *lc2 = list_head(step->exprs); int keyno; /* not needed for other step kinds */ @@ -1897,22 +1897,27 @@ ExecInitPruningContext(PartitionPruneContext *context, Assert(list_length(step->exprs) <= partnatts); - keyno = 0; - foreach(lc2, step->exprs) + for (keyno = 0; keyno < partnatts; keyno++) { - Expr *expr = (Expr *) lfirst(lc2); + if (bms_is_member(keyno, step->nullkeys)) + continue; - /* not needed for Consts */ - if (!IsA(expr, Const)) + if (lc2 != NULL) { - int stateidx = PruneCxtStateIdx(partnatts, - step->step.step_id, - keyno); + Expr *expr = lfirst(lc2); - context->exprstates[stateidx] = - ExecInitExpr(expr, context->planstate); + /* not needed for Consts */ + if (!IsA(expr, Const)) + { + int stateidx = PruneCxtStateIdx(partnatts, + step->step.step_id, + keyno); + + context->exprstates[stateidx] = + ExecInitExpr(expr, context->planstate); + } + lc2 = lnext(lc2); } - keyno++; } } } diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out index feb52f9a9c6..083dd1259ef 100644 --- a/src/test/regress/expected/partition_prune.out +++ b/src/test/regress/expected/partition_prune.out @@ -1907,7 +1907,6 @@ explain (costs off) select * from hp where a = 1 and b = 'abcde' and One-Time Filter: false (2 rows) -drop table hp; -- -- Test runtime partition pruning -- @@ -2133,6 +2132,29 @@ explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2); Filter: ((b >= $1) AND (b <= $2) AND (a < $0)) (10 rows) +-- +-- Test runtime pruning with hash partitioned tables +-- +-- recreate partitions dropped above +create table hp1 partition of hp for values with (modulus 4, remainder 1); +create table hp2 partition of hp for values with (modulus 4, remainder 2); +create table hp3 partition of hp for values with (modulus 4, remainder 3); +-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual +prepare hp_q1 (text) as +select * from hp where a is null and b = $1; +set plan_cache_mode = force_generic_plan; +explain (costs off) execute hp_q1('xxx'); + QUERY PLAN +-------------------------------------------- + Append + Subplans Removed: 3 + -> Seq Scan on hp2 + Filter: ((a IS NULL) AND (b = $1)) +(4 rows) + +reset plan_cache_mode; +deallocate hp_q1; +drop table hp; -- Test a backwards Append scan create table list_part (a int) partition by list (a); create table list_part1 partition of list_part for values in (1); diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql index 01572424e93..765f3c68a43 100644 --- a/src/test/regress/sql/partition_prune.sql +++ b/src/test/regress/sql/partition_prune.sql @@ -371,8 +371,6 @@ drop table hp2; explain (costs off) select * from hp where a = 1 and b = 'abcde' and (c = 2 or c = 3); -drop table hp; - -- -- Test runtime partition pruning -- @@ -451,6 +449,28 @@ execute ab_q3 (1, 8); explain (analyze, costs off, summary off, timing off) execute ab_q3 (2, 2); +-- +-- Test runtime pruning with hash partitioned tables +-- + +-- recreate partitions dropped above +create table hp1 partition of hp for values with (modulus 4, remainder 1); +create table hp2 partition of hp for values with (modulus 4, remainder 2); +create table hp3 partition of hp for values with (modulus 4, remainder 3); + +-- Ensure we correctly prune unneeded partitions when there is an IS NULL qual +prepare hp_q1 (text) as +select * from hp where a is null and b = $1; + +set plan_cache_mode = force_generic_plan; + +explain (costs off) execute hp_q1('xxx'); + +reset plan_cache_mode; +deallocate hp_q1; + +drop table hp; + -- Test a backwards Append scan create table list_part (a int) partition by list (a); create table list_part1 partition of list_part for values in (1); |