diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index 81e3b52ec9b..692d2545e81 100644 --- a/src/backend/utils/adt/datum.c +++ b/src/backend/utils/adt/datum.c @@ -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 { diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index 2f2aac22548..70c6fe43eb1 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -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" diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index b1c1d776290..8225719ff35 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -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;