Skip to content

Commit ebb7902

Browse files
author
Etsuro Fujita
committed
Disable asynchronous execution if using gating Result nodes.
mark_async_capable_plan(), which is called from create_append_plan() to determine whether subplans are async-capable, failed to take into account that the given subplan created from a given subpath might include a gating Result node if the subpath is a SubqueryScanPath or ForeignPath, causing a segmentation fault there when the subplan created from a SubqueryScanPath includes the Result node, or causing ExecAsyncRequest() to throw an error about an unrecognized node type when the subplan created from a ForeignPath includes the Result node, because in the latter case the Result node was unintentionally considered as async-capable, but we don't currently support executing Result nodes asynchronously. Fix by modifying mark_async_capable_plan() to disable asynchronous execution in such cases. Also, adjust code in the ProjectionPath case in mark_async_capable_plan(), for consistency with other cases, and adjust/improve comments there. is_async_capable_path() added in commit 27e1f14, which was rewritten to mark_async_capable_plan() in a later commit, has the same issue, causing the error at execution mentioned above, so back-patch to v14 where the aforesaid commit went in. Per report from Justin Pryzby. Etsuro Fujita, reviewed by Zhihong Yu and Justin Pryzby. Discussion: https://postgr.es/m/20220408124338.GK24419%40telsasoft.com
1 parent 71f3946 commit ebb7902

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

contrib/postgres_fdw/expected/postgres_fdw.out

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10424,6 +10424,32 @@ DROP TABLE local_tbl;
1042410424
DROP INDEX base_tbl1_idx;
1042510425
DROP INDEX base_tbl2_idx;
1042610426
DROP INDEX async_p3_idx;
10427+
-- Disable async execution if we use gating Result nodes for pseudoconstant
10428+
-- quals
10429+
EXPLAIN (VERBOSE, COSTS OFF)
10430+
SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER;
10431+
QUERY PLAN
10432+
----------------------------------------------------------------
10433+
Append
10434+
-> Result
10435+
Output: async_pt_1.a, async_pt_1.b, async_pt_1.c
10436+
One-Time Filter: (CURRENT_USER = SESSION_USER)
10437+
-> Foreign Scan on public.async_p1 async_pt_1
10438+
Output: async_pt_1.a, async_pt_1.b, async_pt_1.c
10439+
Remote SQL: SELECT a, b, c FROM public.base_tbl1
10440+
-> Result
10441+
Output: async_pt_2.a, async_pt_2.b, async_pt_2.c
10442+
One-Time Filter: (CURRENT_USER = SESSION_USER)
10443+
-> Foreign Scan on public.async_p2 async_pt_2
10444+
Output: async_pt_2.a, async_pt_2.b, async_pt_2.c
10445+
Remote SQL: SELECT a, b, c FROM public.base_tbl2
10446+
-> Result
10447+
Output: async_pt_3.a, async_pt_3.b, async_pt_3.c
10448+
One-Time Filter: (CURRENT_USER = SESSION_USER)
10449+
-> Seq Scan on public.async_p3 async_pt_3
10450+
Output: async_pt_3.a, async_pt_3.b, async_pt_3.c
10451+
(18 rows)
10452+
1042710453
-- Test that pending requests are processed properly
1042810454
SET enable_mergejoin TO false;
1042910455
SET enable_hashjoin TO false;

contrib/postgres_fdw/sql/postgres_fdw.sql

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3317,6 +3317,11 @@ DROP INDEX base_tbl1_idx;
33173317
DROP INDEX base_tbl2_idx;
33183318
DROP INDEX async_p3_idx;
33193319

3320+
-- Disable async execution if we use gating Result nodes for pseudoconstant
3321+
-- quals
3322+
EXPLAIN (VERBOSE, COSTS OFF)
3323+
SELECT * FROM async_pt WHERE CURRENT_USER = SESSION_USER;
3324+
33203325
-- Test that pending requests are processed properly
33213326
SET enable_mergejoin TO false;
33223327
SET enable_hashjoin TO false;

src/backend/optimizer/plan/createplan.c

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ static List *get_gating_quals(PlannerInfo *root, List *quals);
8282
static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
8383
List *gating_quals);
8484
static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path);
85-
static bool is_async_capable_path(Path *path);
85+
static bool is_async_capable_plan(Plan *plan, Path *path);
8686
static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path,
8787
int flags);
8888
static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path,
@@ -1109,18 +1109,25 @@ create_join_plan(PlannerInfo *root, JoinPath *best_path)
11091109
}
11101110

11111111
/*
1112-
* is_async_capable_path
1113-
* Check whether a given Path node is async-capable.
1112+
* is_async_capable_plan
1113+
* Check whether the Plan node created from a Path node is async-capable.
11141114
*/
11151115
static bool
1116-
is_async_capable_path(Path *path)
1116+
is_async_capable_plan(Plan *plan, Path *path)
11171117
{
11181118
switch (nodeTag(path))
11191119
{
11201120
case T_ForeignPath:
11211121
{
11221122
FdwRoutine *fdwroutine = path->parent->fdwroutine;
11231123

1124+
/*
1125+
* If the generated plan node includes a gating Result node,
1126+
* we can't execute it asynchronously.
1127+
*/
1128+
if (IsA(plan, Result))
1129+
return false;
1130+
11241131
Assert(fdwroutine != NULL);
11251132
if (fdwroutine->IsForeignPathAsyncCapable != NULL &&
11261133
fdwroutine->IsForeignPathAsyncCapable((ForeignPath *) path))
@@ -1295,8 +1302,8 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags)
12951302

12961303
subplans = lappend(subplans, subplan);
12971304

1298-
/* Check to see if subplan can be executed asynchronously */
1299-
if (consider_async && is_async_capable_path(subpath))
1305+
/* If needed, check to see if subplan can be executed asynchronously */
1306+
if (consider_async && is_async_capable_plan(subplan, subpath))
13001307
{
13011308
subplan->async_capable = true;
13021309
++nasyncplans;

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