diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index f02a5e7..eca46e8 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 *res; + + /* + * EOH_flatten_into expects the target address to be maxaligned so + * can't directly pass start_address. + */ + res = (char *) palloc(header); + EOH_flatten_into(eoh, (void *) res, header); + memcpy(*start_address, res, header); *start_address += header; + + /* be tidy. */ + pfree(res); } else { diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index 26409d3..e05379d 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -1088,6 +1088,38 @@ ORDER BY 1, 2, 3; ------------------------------+---------------------------+-------------+-------------- (0 rows) +--test expanded value representation +SAVEPOINT settings; +CREATE DOMAIN arrdomain AS int[]; +CREATE FUNCTION make_psafe_ad(int,int) returns arrdomain as + 'declare x arrdomain; + begin + x := array[$1,$2]; + return x; + end' language plpgsql parallel safe; +CREATE TABLE tarrdomain(c1 int, c2 arrdomain); +INSERT INTO tarrdomain values(1, array[1,2]); +ANALYZE tarrdomain; +SET force_parallel_mode=1; +PREPARE stmt_sel_domain(arrdomain) AS SELECT * FROM tarrdomain where c2 = $1; +EXPLAIN (COSTS OFF) EXECUTE stmt_sel_domain(make_psafe_ad(1,2)); + QUERY PLAN +-------------------------------------------------------- + Gather + Workers Planned: 1 + Single Copy: true + -> Seq Scan on tarrdomain + Filter: ((c2)::integer[] = '{1,2}'::integer[]) +(5 rows) + +EXECUTE stmt_sel_domain(make_psafe_ad(1,2)); + c1 | c2 +----+------- + 1 | {1,2} +(1 row) + +DEALLOCATE stmt_sel_domain; +ROLLBACK TO SAVEPOINT settings; -- test interation 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; diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index 938c708..d72e131 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -410,6 +410,27 @@ ORDER BY 1; SELECT * FROM information_schema.foreign_data_wrapper_options ORDER BY 1, 2, 3; +--test expanded value representation +SAVEPOINT settings; +CREATE DOMAIN arrdomain AS int[]; + +CREATE FUNCTION make_psafe_ad(int,int) returns arrdomain as + 'declare x arrdomain; + begin + x := array[$1,$2]; + return x; + end' language plpgsql parallel safe; + +CREATE TABLE tarrdomain(c1 int, c2 arrdomain); +INSERT INTO tarrdomain values(1, array[1,2]); +ANALYZE tarrdomain; +SET force_parallel_mode=1; +PREPARE stmt_sel_domain(arrdomain) AS SELECT * FROM tarrdomain where c2 = $1; +EXPLAIN (COSTS OFF) EXECUTE stmt_sel_domain(make_psafe_ad(1,2)); +EXECUTE stmt_sel_domain(make_psafe_ad(1,2)); +DEALLOCATE stmt_sel_domain; +ROLLBACK TO SAVEPOINT settings; + -- test interation 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;