]> granicus.if.org Git - postgresql/commitdiff
MAXALIGN the target address where we store flattened value.
authorAmit Kapila <akapila@postgresql.org>
Wed, 3 Oct 2018 04:24:01 +0000 (09:54 +0530)
committerAmit Kapila <akapila@postgresql.org>
Wed, 3 Oct 2018 04:24:01 +0000 (09:54 +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 d02e3c811064f6ccb5f38ecee3ba6992b8a23d76..76e99ccf4eeae73e0602b4cb6766a6130a867f9b 100644 (file)
@@ -334,8 +334,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 07fd37e720e892bb6ea763558ab53d1af4e5319d..5655997e0560afeb38ab74efc746145c8817231e 100644 (file)
@@ -235,6 +235,33 @@ explain (costs off)
          Index Cond: (unique1 = 1)
 (5 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;
 do $$begin
   -- Provoke error, possibly in worker.  If this error happens to occur in
   -- the worker, there will be a CONTEXT line which must be hidden.
index a7e2a61cffdf5527f042d1d944524ebbb421847d..627a7b2dd2cd6fcd804e508d21b76fe4b97a32b1 100644 (file)
@@ -96,6 +96,22 @@ explain (costs off)
 explain (costs off)
   select stringu1::int2 from tenk1 where unique1 = 1;
 
+-- 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;
+
 do $$begin
   -- Provoke error, possibly in worker.  If this error happens to occur in
   -- the worker, there will be a CONTEXT line which must be hidden.