Skip to content

Commit 0662eb6

Browse files
committed
Fix SIGSEGV in pruning for ScalarArrayOp with constant-null array.
Not much to be said here: commit 9fdb675 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
1 parent 1661a40 commit 0662eb6

File tree

3 files changed

+82
-1
lines changed

3 files changed

+82
-1
lines changed

src/backend/partitioning/partprune.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2059,7 +2059,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
20592059
* nodes, one for each array element (excepting nulls).
20602060
*/
20612061
Const *arr = (Const *) rightop;
2062-
ArrayType *arrval = DatumGetArrayTypeP(arr->constvalue);
2062+
ArrayType *arrval;
20632063
int16 elemlen;
20642064
bool elembyval;
20652065
char elemalign;
@@ -2068,6 +2068,11 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
20682068
int num_elems,
20692069
i;
20702070

2071+
/* If the array itself is null, the saop returns null */
2072+
if (arr->constisnull)
2073+
return PARTCLAUSE_MATCH_CONTRADICT;
2074+
2075+
arrval = DatumGetArrayTypeP(arr->constvalue);
20712076
get_typlenbyvalalign(ARR_ELEMTYPE(arrval),
20722077
&elemlen, &elembyval, &elemalign);
20732078
deconstruct_array(arrval,

src/test/regress/expected/partition_prune.out

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,58 @@ explain (costs off) select * from coercepart where a !~ all ('{ab,bc}');
11861186
Filter: ((a)::text !~ ALL ('{ab,bc}'::text[]))
11871187
(7 rows)
11881188

1189+
explain (costs off) select * from coercepart where a = any ('{ab,bc}');
1190+
QUERY PLAN
1191+
-------------------------------------------------------
1192+
Append
1193+
-> Seq Scan on coercepart_ab
1194+
Filter: ((a)::text = ANY ('{ab,bc}'::text[]))
1195+
-> Seq Scan on coercepart_bc
1196+
Filter: ((a)::text = ANY ('{ab,bc}'::text[]))
1197+
(5 rows)
1198+
1199+
explain (costs off) select * from coercepart where a = any ('{ab,null}');
1200+
QUERY PLAN
1201+
---------------------------------------------------
1202+
Seq Scan on coercepart_ab
1203+
Filter: ((a)::text = ANY ('{ab,NULL}'::text[]))
1204+
(2 rows)
1205+
1206+
explain (costs off) select * from coercepart where a = any (null::text[]);
1207+
QUERY PLAN
1208+
--------------------------
1209+
Result
1210+
One-Time Filter: false
1211+
(2 rows)
1212+
1213+
explain (costs off) select * from coercepart where a = all ('{ab}');
1214+
QUERY PLAN
1215+
----------------------------------------------
1216+
Seq Scan on coercepart_ab
1217+
Filter: ((a)::text = ALL ('{ab}'::text[]))
1218+
(2 rows)
1219+
1220+
explain (costs off) select * from coercepart where a = all ('{ab,bc}');
1221+
QUERY PLAN
1222+
--------------------------
1223+
Result
1224+
One-Time Filter: false
1225+
(2 rows)
1226+
1227+
explain (costs off) select * from coercepart where a = all ('{ab,null}');
1228+
QUERY PLAN
1229+
--------------------------
1230+
Result
1231+
One-Time Filter: false
1232+
(2 rows)
1233+
1234+
explain (costs off) select * from coercepart where a = all (null::text[]);
1235+
QUERY PLAN
1236+
--------------------------
1237+
Result
1238+
One-Time Filter: false
1239+
(2 rows)
1240+
11891241
drop table coercepart;
11901242
CREATE TABLE part (a INT, b INT) PARTITION BY LIST (a);
11911243
CREATE TABLE part_p1 PARTITION OF part FOR VALUES IN (-2,-1,0,1,2);
@@ -3157,6 +3209,20 @@ select * from stable_qual_pruning
31573209
Filter: (a = ANY ('{"Tue Feb 01 00:00:00 2000 PST","Fri Jan 01 00:00:00 2010 PST"}'::timestamp with time zone[]))
31583210
(4 rows)
31593211

3212+
explain (analyze, costs off, summary off, timing off)
3213+
select * from stable_qual_pruning
3214+
where a = any(null::timestamptz[]);
3215+
QUERY PLAN
3216+
----------------------------------------------------------------
3217+
Append (actual rows=0 loops=1)
3218+
-> Seq Scan on stable_qual_pruning1 (actual rows=0 loops=1)
3219+
Filter: (a = ANY (NULL::timestamp with time zone[]))
3220+
-> Seq Scan on stable_qual_pruning2 (actual rows=0 loops=1)
3221+
Filter: (a = ANY (NULL::timestamp with time zone[]))
3222+
-> Seq Scan on stable_qual_pruning3 (actual rows=0 loops=1)
3223+
Filter: (a = ANY (NULL::timestamp with time zone[]))
3224+
(7 rows)
3225+
31603226
drop table stable_qual_pruning;
31613227
--
31623228
-- Check that pruning with composite range partitioning works correctly when

src/test/regress/sql/partition_prune.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,13 @@ explain (costs off) select * from coercepart where a ~ any ('{ab}');
184184
explain (costs off) select * from coercepart where a !~ all ('{ab}');
185185
explain (costs off) select * from coercepart where a ~ any ('{ab,bc}');
186186
explain (costs off) select * from coercepart where a !~ all ('{ab,bc}');
187+
explain (costs off) select * from coercepart where a = any ('{ab,bc}');
188+
explain (costs off) select * from coercepart where a = any ('{ab,null}');
189+
explain (costs off) select * from coercepart where a = any (null::text[]);
190+
explain (costs off) select * from coercepart where a = all ('{ab}');
191+
explain (costs off) select * from coercepart where a = all ('{ab,bc}');
192+
explain (costs off) select * from coercepart where a = all ('{ab,null}');
193+
explain (costs off) select * from coercepart where a = all (null::text[]);
187194

188195
drop table coercepart;
189196

@@ -803,6 +810,9 @@ select * from stable_qual_pruning
803810
explain (analyze, costs off, summary off, timing off)
804811
select * from stable_qual_pruning
805812
where a = any(array['2000-02-01', '2010-01-01']::timestamptz[]);
813+
explain (analyze, costs off, summary off, timing off)
814+
select * from stable_qual_pruning
815+
where a = any(null::timestamptz[]);
806816

807817
drop table stable_qual_pruning;
808818

0 commit comments

Comments
 (0)