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 03:44:09 +0000 (09:14 +0530)
committerAmit Kapila <akapila@postgresql.org>
Wed, 3 Oct 2018 03:44:09 +0000 (09:14 +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 f02a5e77aee427b07c391dc4b3cb18042aad58d3..495768275db57bc7bf13aed0b563d20c8f4e3324 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 1a35d82a16386101cd9aadd2fc738c30c6905ec7..7891a94d01132a1c42b31bbea438570dc0afd957 100644 (file)
@@ -1088,7 +1088,34 @@ ORDER BY 1, 2, 3;
 ------------------------------+---------------------------+-------------+--------------
 (0 rows)
 
--- test interation between subquery and partial_paths
+-- 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;
+-- test interaction between subquery and partial_paths
 SET LOCAL min_parallel_table_scan_size TO 0;
 CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1;
 EXPLAIN (COSTS OFF)
index 938c708d18fd84fba86f525af769b6d9f7c4113a..e0f99accb4d5d859f62b2676653dc5c1a3a1bd75 100644 (file)
@@ -410,7 +410,23 @@ ORDER BY 1;
 SELECT * FROM information_schema.foreign_data_wrapper_options
 ORDER BY 1, 2, 3;
 
--- test interation between subquery and partial_paths
+-- 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;
+
+-- test interaction between subquery and partial_paths
 SET LOCAL min_parallel_table_scan_size TO 0;
 CREATE VIEW tenk1_vw_sec WITH (security_barrier) AS SELECT * FROM tenk1;
 EXPLAIN (COSTS OFF)