From 335f4e316a6dee9eb3383fc3800954ee9e7f6cef Mon Sep 17 00:00:00 2001 From: Jeevan Chalke Date: Mon, 26 Oct 2026 12:56:01 +0530 Subject: [PATCH v1] Allow parallel query for PL/pgSQL assignment statements. Commit 61c2e1a95f made exec_eval_expr() prepare expressions with CURSOR_OPT_PARALLEL_OK, but exec_assign_expr() prepares the plan itself, with cursorOptions 0, before calling exec_eval_expr(). So queries used in assignments, such as "x := sum(a) from tab", were never considered for parallel execution, while the same query used in IF, RETURN, RAISE and so on could be. The same applies to DECLARE default expressions, which are also evaluated by exec_assign_expr(). The pre-planning in exec_assign_expr() is redundant, since exec_eval_expr() creates the plan if needed; just remove it. Add regression tests for both an assignment statement and a DECLARE default expression. --- src/pl/plpgsql/src/pl_exec.c | 7 +---- src/test/regress/expected/select_parallel.out | 27 +++++++++++++++++++ src/test/regress/sql/select_parallel.sql | 21 +++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index bc1667f7a13..853dee7f4da 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -5116,12 +5116,7 @@ exec_assign_expr(PLpgSQL_execstate *estate, PLpgSQL_datum *target, Oid valtype; int32 valtypmod; - /* - * If first time through, create a plan for this expression. - */ - if (expr->plan == NULL) - exec_prepare_plan(estate, expr, 0); - + /* exec_eval_expr will create a plan if this is the first time through */ value = exec_eval_expr(estate, expr, &isnull, &valtype, &valtypmod); exec_assign_value(estate, target, value, isnull, valtype, valtypmod); exec_eval_cleanup(estate); diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out index e1344215644..2eb5cadb80b 100644 --- a/src/test/regress/expected/select_parallel.out +++ b/src/test/regress/expected/select_parallel.out @@ -1167,6 +1167,33 @@ explain (costs off) Filter: (stringu1 ~~ '%AAAA'::text) (11 rows) +-- PL/pgSQL assignment from a query should be able to use parallel query; +-- check by provoking an error in a worker +SAVEPOINT settings; +SET LOCAL debug_parallel_query = 1; +do $$ +declare x int2; +begin + x := stringu1::int2 from tenk1 where unique1 = 1; +end $$; +ERROR: invalid input syntax for type smallint: "BAAAAA" +CONTEXT: parallel worker +PL/pgSQL assignment "x := stringu1::int2 from tenk1 where unique1 = 1" +PL/pgSQL function inline_code_block line 4 at assignment +ROLLBACK TO SAVEPOINT settings; +-- same for a DECLARE default expression +SAVEPOINT settings; +SET LOCAL debug_parallel_query = 1; +do $$ +declare x int2 := stringu1::int2 from tenk1 where unique1 = 1; +begin + null; +end $$; +ERROR: invalid input syntax for type smallint: "BAAAAA" +CONTEXT: parallel worker +PL/pgSQL expression "stringu1::int2 from tenk1 where unique1 = 1" +PL/pgSQL function inline_code_block line 2 during statement block local variable initialization +ROLLBACK TO SAVEPOINT settings; -- to increase the parallel query test coverage SAVEPOINT settings; SET LOCAL debug_parallel_query = 1; diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql index 71a75bc86ea..9a7c6d5e74e 100644 --- a/src/test/regress/sql/select_parallel.sql +++ b/src/test/regress/sql/select_parallel.sql @@ -447,6 +447,27 @@ explain (costs off) select * from tenk1 a where two in (select two from tenk1 b where stringu1 like '%AAAA' limit 3); +-- PL/pgSQL assignment from a query should be able to use parallel query; +-- check by provoking an error in a worker +SAVEPOINT settings; +SET LOCAL debug_parallel_query = 1; +do $$ +declare x int2; +begin + x := stringu1::int2 from tenk1 where unique1 = 1; +end $$; +ROLLBACK TO SAVEPOINT settings; + +-- same for a DECLARE default expression +SAVEPOINT settings; +SET LOCAL debug_parallel_query = 1; +do $$ +declare x int2 := stringu1::int2 from tenk1 where unique1 = 1; +begin + null; +end $$; +ROLLBACK TO SAVEPOINT settings; + -- to increase the parallel query test coverage SAVEPOINT settings; SET LOCAL debug_parallel_query = 1; -- 2.43.0