Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
MAXALIGN the target address where we store flattened value.
authorAmit Kapila <akapila@postgresql.org>
Wed, 3 Oct 2018 04:08:07 +0000 (09:38 +0530)
committerAmit Kapila <akapila@postgresql.org>
Wed, 3 Oct 2018 04:08:07 +0000 (09:38 +0530)
The API (EOH_flatten_into) that flattens the expanded value representation
expects the target address to be maxaligned.  All it's usage adhere to that
principle except when serializing datums for parallel query.  Fix that
usage.

Diagnosed-by: Tom Lane
Author: Tom Lane and Amit Kapila
Backpatch-through: 9.6
Discussion: https://postgr.es/m/11629.1536550032@sss.pgh.pa.us

src/backend/utils/adt/datum.c
src/test/regress/expected/select_parallel.out
src/test/regress/sql/select_parallel.sql

index 81e3b52ec9bec8eda038884cbc9cf86779551df7..692d2545e81b8f187ff9134f418d315832bb8a84 100644 (file)
@@ -338,8 +338,19 @@ datumSerialize(Datum value, bool isnull, bool typByVal, int typLen,
        }
        else if (eoh)
        {
-           EOH_flatten_into(eoh, (void *) *start_address, header);
+           char       *tmp;
+
+           /*
+            * EOH_flatten_into expects the target address to be maxaligned,
+            * so we can't store directly to *start_address.
+            */
+           tmp = (char *) palloc(header);
+           EOH_flatten_into(eoh, (void *) tmp, header);
+           memcpy(*start_address, tmp, header);
            *start_address += header;
+
+           /* be tidy. */
+           pfree(tmp);
        }
        else
        {
index 2f2aac225482d9e1bd95b5792b3dbce4bf7933cd..70c6fe43eb1a9539a4d59098ece88453b59255e9 100644 (file)
@@ -628,6 +628,33 @@ EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1;
    ->  Parallel Seq Scan on tenk1 (actual rows=2000 loops=5)
 (4 rows)
 
+-- test passing expanded-value representations to workers
+CREATE FUNCTION make_some_array(int,int) returns int[] as
+$$declare x int[];
+  begin
+    x[1] := $1;
+    x[2] := $2;
+    return x;
+  end$$ language plpgsql parallel safe;
+CREATE TABLE fooarr(f1 text, f2 int[], f3 text);
+INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one');
+PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2;
+EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2));
+                            QUERY PLAN                            
+------------------------------------------------------------------
+ Gather
+   Workers Planned: 3
+   ->  Parallel Seq Scan on fooarr
+         Filter: ((f1 = '1'::text) AND (f2 = '{1,2}'::integer[]))
+(4 rows)
+
+EXECUTE pstmt('1', make_some_array(1,2));
+ f1 |  f2   | f3  
+----+-------+-----
+ 1  | {1,2} | one
+(1 row)
+
+DEALLOCATE pstmt;
 -- provoke error in worker
 select stringu1::int2 from tenk1 where unique1 = 1;
 ERROR:  invalid input syntax for integer: "BAAAAA"
index b1c1d7762907d304159229eeb2f15e3cb4d39c89..8225719ff35e0bd5fa2477aae091c99300f4bd74 100644 (file)
@@ -218,6 +218,22 @@ explain (costs off)
 -- to increase the parallel query test coverage
 EXPLAIN (analyze, timing off, summary off, costs off) SELECT * FROM tenk1;
 
+-- test passing expanded-value representations to workers
+CREATE FUNCTION make_some_array(int,int) returns int[] as
+$$declare x int[];
+  begin
+    x[1] := $1;
+    x[2] := $2;
+    return x;
+  end$$ language plpgsql parallel safe;
+CREATE TABLE fooarr(f1 text, f2 int[], f3 text);
+INSERT INTO fooarr VALUES('1', ARRAY[1,2], 'one');
+
+PREPARE pstmt(text, int[]) AS SELECT * FROM fooarr WHERE f1 = $1 AND f2 = $2;
+EXPLAIN (COSTS OFF) EXECUTE pstmt('1', make_some_array(1,2));
+EXECUTE pstmt('1', make_some_array(1,2));
+DEALLOCATE pstmt;
+
 -- provoke error in worker
 select stringu1::int2 from tenk1 where unique1 = 1;