Skip to content

Commit 682ce91

Browse files
committed
Allow parallel query for prepared statements with generic plans.
This was always intended to work, but due to an oversight in max_parallel_hazard_walker, it didn't. In testing, we missed the fact that it was only working for custom plans, where the parameter value has been substituted for the parameter itself early enough that everything worked. In a generic plan, the Param node survives and must be treated as parallel-safe. SerializeParamList provides for the transmission of parameter values to workers. Amit Kapila with help from Kuntal Ghosh. Some changes by me. Discussion: http://postgr.es/m/CAA4eK1+_BuZrmVCeua5Eqnm4Co9DAXdM5HPAOE2J19ePbR912Q@mail.gmail.com
1 parent 6784d7a commit 682ce91

File tree

4 files changed

+37
-7
lines changed

4 files changed

+37
-7
lines changed

src/backend/optimizer/util/clauses.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,13 +1223,17 @@ max_parallel_hazard_walker(Node *node, max_parallel_hazard_context *context)
12231223

12241224
/*
12251225
* We can't pass Params to workers at the moment either, so they are also
1226-
* parallel-restricted, unless they are PARAM_EXEC Params listed in
1227-
* safe_param_ids, meaning they could be generated within the worker.
1226+
* parallel-restricted, unless they are PARAM_EXTERN Params or are
1227+
* PARAM_EXEC Params listed in safe_param_ids, meaning they could be
1228+
* generated within the worker.
12281229
*/
12291230
else if (IsA(node, Param))
12301231
{
12311232
Param *param = (Param *) node;
12321233

1234+
if (param->paramkind == PARAM_EXTERN)
1235+
return false;
1236+
12331237
if (param->paramkind != PARAM_EXEC ||
12341238
!list_member_int(context->safe_param_ids, param->paramid))
12351239
{

src/pl/plpgsql/src/pl_exec.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6588,8 +6588,8 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
65886588
* force_parallel_mode is on, the planner might've stuck a Gather node
65896589
* atop that. The simplest way to deal with this is to look through the
65906590
* Gather node. The Gather node's tlist would normally contain a Var
6591-
* referencing the child node's output ... but setrefs.c might also have
6592-
* copied a Const as-is.
6591+
* referencing the child node's output, but it could also be a Param, or
6592+
* it could be a Const that setrefs.c copied as-is.
65936593
*/
65946594
plan = stmt->planTree;
65956595
for (;;)
@@ -6616,9 +6616,9 @@ exec_save_simple_expr(PLpgSQL_expr *expr, CachedPlan *cplan)
66166616
/* If setrefs.c copied up a Const, no need to look further */
66176617
if (IsA(tle_expr, Const))
66186618
break;
6619-
/* Otherwise, it better be an outer Var */
6620-
Assert(IsA(tle_expr, Var));
6621-
Assert(((Var *) tle_expr)->varno == OUTER_VAR);
6619+
/* Otherwise, it had better be a Param or an outer Var */
6620+
Assert(IsA(tle_expr, Param) || (IsA(tle_expr, Var) &&
6621+
((Var *) tle_expr)->varno == OUTER_VAR));
66226622
/* Descend to the child node */
66236623
plan = plan->lefttree;
66246624
}

src/test/regress/expected/select_parallel.out

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,26 @@ explain (costs off)
101101
-> Parallel Index Only Scan using tenk1_unique1 on tenk1
102102
(5 rows)
103103

104+
-- test prepared statement
105+
prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1;
106+
explain (costs off) execute tenk1_count(1);
107+
QUERY PLAN
108+
----------------------------------------------
109+
Finalize Aggregate
110+
-> Gather
111+
Workers Planned: 4
112+
-> Partial Aggregate
113+
-> Parallel Seq Scan on tenk1
114+
Filter: (hundred > 1)
115+
(6 rows)
116+
117+
execute tenk1_count(1);
118+
count
119+
-------
120+
9800
121+
(1 row)
122+
123+
deallocate tenk1_count;
104124
-- test parallel plans for queries containing un-correlated subplans.
105125
alter table tenk2 set (parallel_workers = 0);
106126
explain (costs off)

src/test/regress/sql/select_parallel.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ explain (costs off)
3939
select sum(parallel_restricted(unique1)) from tenk1
4040
group by(parallel_restricted(unique1));
4141

42+
-- test prepared statement
43+
prepare tenk1_count(integer) As select count((unique1)) from tenk1 where hundred > $1;
44+
explain (costs off) execute tenk1_count(1);
45+
execute tenk1_count(1);
46+
deallocate tenk1_count;
47+
4248
-- test parallel plans for queries containing un-correlated subplans.
4349
alter table tenk2 set (parallel_workers = 0);
4450
explain (costs off)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy