aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-08-09 13:20:28 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2019-08-09 13:20:28 -0400
commit2f729d83226705d1149419a2aef7c1678fe641ec (patch)
tree220a863b34ae69cff8878ba5f6c912e37d01449b /src
parentbf6455d4c557ff9ef42985bb4806b251497bdc60 (diff)
downloadpostgresql-2f729d83226705d1149419a2aef7c1678fe641ec.tar.gz
postgresql-2f729d83226705d1149419a2aef7c1678fe641ec.zip
Fix SIGSEGV in pruning for ScalarArrayOp with constant-null array.
Not much to be said here: commit 9fdb675fc should have checked constisnull, didn't. Per report from Piotr Włodarczyk. Back-patch to v11 where bug was introduced. Discussion: https://postgr.es/m/CAP-dhMr+vRpwizEYjUjsiZ1vwqpohTm+3Pbdt6Pr7FEgPq9R0Q@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/partitioning/partprune.c7
-rw-r--r--src/test/regress/expected/partition_prune.out68
-rw-r--r--src/test/regress/sql/partition_prune.sql10
3 files changed, 84 insertions, 1 deletions
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index bfc16409dd9..e15e11e3ab3 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -2034,7 +2034,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
* nodes, one for each array element (excepting nulls).
*/
Const *arr = (Const *) rightop;
- ArrayType *arrval = DatumGetArrayTypeP(arr->constvalue);
+ ArrayType *arrval;
int16 elemlen;
bool elembyval;
char elemalign;
@@ -2043,6 +2043,11 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
int num_elems,
i;
+ /* If the array itself is null, the saop returns null */
+ if (arr->constisnull)
+ return PARTCLAUSE_MATCH_CONTRADICT;
+
+ arrval = DatumGetArrayTypeP(arr->constvalue);
get_typlenbyvalalign(ARR_ELEMTYPE(arrval),
&elemlen, &elembyval, &elemalign);
deconstruct_array(arrval,
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index 63872285161..c564c056b9c 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -1197,6 +1197,60 @@ explain (costs off) select * from coercepart where a !~ all ('{ab,bc}');
Filter: ((a)::text !~ ALL ('{ab,bc}'::text[]))
(7 rows)
+explain (costs off) select * from coercepart where a = any ('{ab,bc}');
+ QUERY PLAN
+-------------------------------------------------------
+ Append
+ -> Seq Scan on coercepart_ab
+ Filter: ((a)::text = ANY ('{ab,bc}'::text[]))
+ -> Seq Scan on coercepart_bc
+ Filter: ((a)::text = ANY ('{ab,bc}'::text[]))
+(5 rows)
+
+explain (costs off) select * from coercepart where a = any ('{ab,null}');
+ QUERY PLAN
+---------------------------------------------------------
+ Append
+ -> Seq Scan on coercepart_ab
+ Filter: ((a)::text = ANY ('{ab,NULL}'::text[]))
+(3 rows)
+
+explain (costs off) select * from coercepart where a = any (null::text[]);
+ QUERY PLAN
+--------------------------
+ Result
+ One-Time Filter: false
+(2 rows)
+
+explain (costs off) select * from coercepart where a = all ('{ab}');
+ QUERY PLAN
+----------------------------------------------------
+ Append
+ -> Seq Scan on coercepart_ab
+ Filter: ((a)::text = ALL ('{ab}'::text[]))
+(3 rows)
+
+explain (costs off) select * from coercepart where a = all ('{ab,bc}');
+ QUERY PLAN
+--------------------------
+ Result
+ One-Time Filter: false
+(2 rows)
+
+explain (costs off) select * from coercepart where a = all ('{ab,null}');
+ QUERY PLAN
+--------------------------
+ Result
+ One-Time Filter: false
+(2 rows)
+
+explain (costs off) select * from coercepart where a = all (null::text[]);
+ QUERY PLAN
+--------------------------
+ Result
+ One-Time Filter: false
+(2 rows)
+
drop table coercepart;
CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a);
CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2);
@@ -3076,6 +3130,20 @@ select * from stable_qual_pruning
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000 PST","Fri Jan 01 00:00:00 2010 PST"}'::timestamp with time zone[]))
(4 rows)
+explain (analyze, costs off, summary off, timing off)
+select * from stable_qual_pruning
+ where a = any(null::timestamptz[]);
+ QUERY PLAN
+----------------------------------------------------------------
+ Append (actual rows=0 loops=1)
+ -> Seq Scan on stable_qual_pruning1 (actual rows=0 loops=1)
+ Filter: (a = ANY (NULL::timestamp with time zone[]))
+ -> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1)
+ Filter: (a = ANY (NULL::timestamp with time zone[]))
+ -> Seq Scan on stable_qual_pruning3 (actual rows=0 loops=1)
+ Filter: (a = ANY (NULL::timestamp with time zone[]))
+(7 rows)
+
drop table stable_qual_pruning;
--
-- Check that pruning with composite range partitioning works correctly when
diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql
index 4d60556d38c..48956c4ee3a 100644
--- a/src/test/regress/sql/partition_prune.sql
+++ b/src/test/regress/sql/partition_prune.sql
@@ -180,6 +180,13 @@ explain (costs off) select * from coercepart where a ~ any ('{ab}');
explain (costs off) select * from coercepart where a !~ all ('{ab}');
explain (costs off) select * from coercepart where a ~ any ('{ab,bc}');
explain (costs off) select * from coercepart where a !~ all ('{ab,bc}');
+explain (costs off) select * from coercepart where a = any ('{ab,bc}');
+explain (costs off) select * from coercepart where a = any ('{ab,null}');
+explain (costs off) select * from coercepart where a = any (null::text[]);
+explain (costs off) select * from coercepart where a = all ('{ab}');
+explain (costs off) select * from coercepart where a = all ('{ab,bc}');
+explain (costs off) select * from coercepart where a = all ('{ab,null}');
+explain (costs off) select * from coercepart where a = all (null::text[]);
drop table coercepart;
@@ -764,6 +771,9 @@ select * from stable_qual_pruning
explain (analyze, costs off, summary off, timing off)
select * from stable_qual_pruning
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
+explain (analyze, costs off, summary off, timing off)
+select * from stable_qual_pruning
+ where a = any(null::timestamptz[]);
drop table stable_qual_pruning;