fix-partition-pruning-with-isnull.patch
text/x-patch
Filename: fix-partition-pruning-with-isnull.patch
Type: text/x-patch
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/partitioning/partprune.c | 12 | 1 |
| src/test/regress/expected/partition_prune.out | 12 | 0 |
| src/test/regress/sql/partition_prune.sql | 5 | 0 |
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 7179b22a05..0fbc2dba33 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -3383,10 +3383,21 @@ perform_pruning_base_step(PartitionPruneContext *context,
bool isnull;
Oid cmpfn;
+ /*
+ * IS NULL clause is not added into array of ExprStates
+ * and thus 'stateidx' based on 'keyno' cannot be used to get
+ * ExprStates array element. Use the index based on 'nvalues'
+ * in order to obtain proper datum from the array.
+ */
+ int exprstateidx =
+ PruneCxtStateIdx(context->partnatts, opstep->step.step_id,
+ nvalues);
+
expr = lfirst(lc1);
stateidx = PruneCxtStateIdx(context->partnatts,
opstep->step.step_id, keyno);
- partkey_datum_from_expr(context, expr, stateidx,
+
+ partkey_datum_from_expr(context, expr, exprstateidx,
&datum, &isnull);
/*
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index bb1223e2b1..a16e08a405 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -1921,6 +1921,18 @@ explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and
Filter: (((a = 1) AND (b = 'abcde'::text)) OR ((a = 2) AND (b = 'xxx'::text)) OR ((a IS NULL) AND (b IS NULL)))
(7 rows)
+-- test partition pruning with prepared statement and IS NULL clause.
+prepare stmt AS select * from hp where a is null and b = $1;
+explain (costs off) execute stmt('xxx');
+ QUERY PLAN
+--------------------------------------------
+ Append
+ Subplans Removed: 3
+ -> Seq Scan on hp2 hp_1
+ Filter: ((a IS NULL) AND (b = $1))
+(4 rows)
+
+deallocate stmt;
-- test pruning when not all the partitions exist
drop table hp1;
drop table hp3;
diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql
index 83fed54b8c..9cafbdd538 100644
--- a/src/test/regress/sql/partition_prune.sql
+++ b/src/test/regress/sql/partition_prune.sql
@@ -374,6 +374,11 @@ explain (costs off) select * from hp where a = 2 and b = 'xxx';
explain (costs off) select * from hp where a = 1 and b = 'abcde';
explain (costs off) select * from hp where (a = 1 and b = 'abcde') or (a = 2 and b = 'xxx') or (a is null and b is null);
+-- test partition pruning with prepared statement and IS NULL clause.
+prepare stmt AS select * from hp where a is null and b = $1;
+explain (costs off) execute stmt('xxx');
+deallocate stmt;
+
-- test pruning when not all the partitions exist
drop table hp1;
drop table hp3;