Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Fix SIGSEGV in pruning for ScalarArrayOp with constant-null array.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 9 Aug 2019 17:20:28 +0000 (13:20 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 9 Aug 2019 17:20:28 +0000 (13:20 -0400)
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

src/backend/partitioning/partprune.c
src/test/regress/expected/partition_prune.out
src/test/regress/sql/partition_prune.sql

index bfc16409dd9bffb081dba53adb251b6306894170..e15e11e3ab3fc46eca4787ec948cf5a9aca11d15 100644 (file)
@@ -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,
index 638722851617662275e60cd307aa50cb6619615c..c564c056b9c1332b20ca63ce217fb5885ce8a864 100644 (file)
@@ -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
index 4d60556d38c16b9f4b4636c1b50e0b26d9478fda..48956c4ee3a19a6b4ab28389dfdacca2e7fbd3ae 100644 (file)
@@ -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;