Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit003d80f

Browse files
committed
Mark finished Plan nodes with parallel_safe flags.
We'd managed to avoid doing this so far, but it seems pretty obviousthat it would be forced on us some day, and this is much the cleanestway of approaching the open problem that parallel-unsafe subplans arebeing transmitted to parallel workers. Anyway there's no space costdue to alignment considerations, and the time cost is pretty minimalsince we're just copying the flag from the corresponding Path node.(At least in most cases ... some of the klugier spots in createplan.chave to work a bit harder.)In principle we could perhaps get rid of SubPlan.parallel_safe,but I thought it better to keep that in case there are reasons toconsider a SubPlan unsafe even when its child plan is parallel-safe.This patch doesn't actually do anything with the new flags, butI thought I'd commit it separately anyway.Note: although this touches outfuncs/readfuncs, there's no need fora catversion bump because Plan trees aren't stored on disk.Discussion:https://postgr.es/m/87tw5x4vcu.fsf@credativ.de
1 parent35b5f7b commit003d80f

File tree

7 files changed

+39
-18
lines changed

7 files changed

+39
-18
lines changed

‎src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ CopyPlanFields(const Plan *from, Plan *newnode)
118118
COPY_SCALAR_FIELD(plan_rows);
119119
COPY_SCALAR_FIELD(plan_width);
120120
COPY_SCALAR_FIELD(parallel_aware);
121+
COPY_SCALAR_FIELD(parallel_safe);
121122
COPY_SCALAR_FIELD(plan_node_id);
122123
COPY_NODE_FIELD(targetlist);
123124
COPY_NODE_FIELD(qual);

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ _outPlanInfo(StringInfo str, const Plan *node)
275275
WRITE_FLOAT_FIELD(plan_rows,"%.0f");
276276
WRITE_INT_FIELD(plan_width);
277277
WRITE_BOOL_FIELD(parallel_aware);
278+
WRITE_BOOL_FIELD(parallel_safe);
278279
WRITE_INT_FIELD(plan_node_id);
279280
WRITE_NODE_FIELD(targetlist);
280281
WRITE_NODE_FIELD(qual);

‎src/backend/nodes/readfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,7 @@ ReadCommonPlan(Plan *local_node)
14801480
READ_FLOAT_FIELD(plan_rows);
14811481
READ_INT_FIELD(plan_width);
14821482
READ_BOOL_FIELD(parallel_aware);
1483+
READ_BOOL_FIELD(parallel_safe);
14831484
READ_INT_FIELD(plan_node_id);
14841485
READ_NODE_FIELD(targetlist);
14851486
READ_NODE_FIELD(qual);

‎src/backend/optimizer/plan/createplan.c

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static Plan *create_unique_plan(PlannerInfo *root, UniquePath *best_path,
8888
intflags);
8989
staticGather*create_gather_plan(PlannerInfo*root,GatherPath*best_path);
9090
staticPlan*create_projection_plan(PlannerInfo*root,ProjectionPath*best_path);
91-
staticPlan*inject_projection_plan(Plan*subplan,List*tlist);
91+
staticPlan*inject_projection_plan(Plan*subplan,List*tlist,boolparallel_safe);
9292
staticSort*create_sort_plan(PlannerInfo*root,SortPath*best_path,intflags);
9393
staticGroup*create_group_plan(PlannerInfo*root,GroupPath*best_path);
9494
staticUnique*create_upper_unique_plan(PlannerInfo*root,UpperUniquePath*best_path,
@@ -920,6 +920,9 @@ create_gating_plan(PlannerInfo *root, Path *path, Plan *plan,
920920
*/
921921
copy_plan_costsize(gplan,plan);
922922

923+
/* Gating quals could be unsafe, so better use the Path's safety flag */
924+
gplan->parallel_safe=path->parallel_safe;
925+
923926
returngplan;
924927
}
925928

@@ -1313,7 +1316,8 @@ create_unique_plan(PlannerInfo *root, UniquePath *best_path, int flags)
13131316
*/
13141317
if (!is_projection_capable_plan(subplan)&&
13151318
!tlist_same_exprs(newtlist,subplan->targetlist))
1316-
subplan=inject_projection_plan(subplan,newtlist);
1319+
subplan=inject_projection_plan(subplan,newtlist,
1320+
best_path->path.parallel_safe);
13171321
else
13181322
subplan->targetlist=newtlist;
13191323
}
@@ -1572,7 +1576,8 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path)
15721576
plan->total_cost=best_path->path.total_cost;
15731577
plan->plan_rows=best_path->path.rows;
15741578
plan->plan_width=best_path->path.pathtarget->width;
1575-
/* ... but be careful not to munge subplan's parallel-aware flag */
1579+
plan->parallel_safe=best_path->path.parallel_safe;
1580+
/* ... but don't change subplan's parallel_aware flag */
15761581
}
15771582
else
15781583
{
@@ -1592,9 +1597,12 @@ create_projection_plan(PlannerInfo *root, ProjectionPath *best_path)
15921597
* This is used in a few places where we decide on-the-fly that we need a
15931598
* projection step as part of the tree generated for some Path node.
15941599
* We should try to get rid of this in favor of doing it more honestly.
1600+
*
1601+
* One reason it's ugly is we have to be told the right parallel_safe marking
1602+
* to apply (since the tlist might be unsafe even if the child plan is safe).
15951603
*/
15961604
staticPlan*
1597-
inject_projection_plan(Plan*subplan,List*tlist)
1605+
inject_projection_plan(Plan*subplan,List*tlist,boolparallel_safe)
15981606
{
15991607
Plan*plan;
16001608

@@ -1608,6 +1616,7 @@ inject_projection_plan(Plan *subplan, List *tlist)
16081616
* consistent not more so. Hence, just copy the subplan's cost.
16091617
*/
16101618
copy_plan_costsize(plan,subplan);
1619+
plan->parallel_safe=parallel_safe;
16111620

16121621
returnplan;
16131622
}
@@ -1984,6 +1993,7 @@ create_minmaxagg_plan(PlannerInfo *root, MinMaxAggPath *best_path)
19841993
plan->plan_rows=1;
19851994
plan->plan_width=mminfo->path->pathtarget->width;
19861995
plan->parallel_aware= false;
1996+
plan->parallel_safe=mminfo->path->parallel_safe;
19871997

19881998
/* Convert the plan into an InitPlan in the outer query. */
19891999
SS_make_initplan_from_plan(root,subroot,plan,mminfo->param);
@@ -2829,6 +2839,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
28292839
clamp_row_est(apath->bitmapselectivity*apath->path.parent->tuples);
28302840
plan->plan_width=0;/* meaningless */
28312841
plan->parallel_aware= false;
2842+
plan->parallel_safe=apath->path.parallel_safe;
28322843
*qual=subquals;
28332844
*indexqual=subindexquals;
28342845
*indexECs=subindexECs;
@@ -2892,6 +2903,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
28922903
clamp_row_est(opath->bitmapselectivity*opath->path.parent->tuples);
28932904
plan->plan_width=0;/* meaningless */
28942905
plan->parallel_aware= false;
2906+
plan->parallel_safe=opath->path.parallel_safe;
28952907
}
28962908

28972909
/*
@@ -2936,6 +2948,7 @@ create_bitmap_subplan(PlannerInfo *root, Path *bitmapqual,
29362948
clamp_row_est(ipath->indexselectivity*ipath->path.parent->tuples);
29372949
plan->plan_width=0;/* meaningless */
29382950
plan->parallel_aware= false;
2951+
plan->parallel_safe=ipath->path.parallel_safe;
29392952
*qual=get_actual_clauses(ipath->indexclauses);
29402953
*indexqual=get_actual_clauses(ipath->indexquals);
29412954
foreach(l,ipath->indexinfo->indpred)
@@ -4834,7 +4847,7 @@ order_qual_clauses(PlannerInfo *root, List *clauses)
48344847
/*
48354848
* Copy cost and size info from a Path node to the Plan node created from it.
48364849
* The executor usually won't use this info, but it's needed by EXPLAIN.
4837-
* Also copy the parallel-aware flag, which the executor *will* use.
4850+
* Also copy the parallel-related flags, which the executor *will* use.
48384851
*/
48394852
staticvoid
48404853
copy_generic_path_info(Plan*dest,Path*src)
@@ -4844,6 +4857,7 @@ copy_generic_path_info(Plan *dest, Path *src)
48444857
dest->plan_rows=src->rows;
48454858
dest->plan_width=src->pathtarget->width;
48464859
dest->parallel_aware=src->parallel_aware;
4860+
dest->parallel_safe=src->parallel_safe;
48474861
}
48484862

48494863
/*
@@ -4859,6 +4873,8 @@ copy_plan_costsize(Plan *dest, Plan *src)
48594873
dest->plan_width=src->plan_width;
48604874
/* Assume the inserted node is not parallel-aware. */
48614875
dest->parallel_aware= false;
4876+
/* Assume the inserted node is parallel-safe, if child plan is. */
4877+
dest->parallel_safe=src->parallel_safe;
48624878
}
48634879

48644880
/*
@@ -4888,6 +4904,7 @@ label_sort_with_costsize(PlannerInfo *root, Sort *plan, double limit_tuples)
48884904
plan->plan.plan_rows=lefttree->plan_rows;
48894905
plan->plan.plan_width=lefttree->plan_width;
48904906
plan->plan.parallel_aware= false;
4907+
plan->plan.parallel_safe=lefttree->parallel_safe;
48914908
}
48924909

48934910
/*
@@ -5696,7 +5713,8 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
56965713
{
56975714
/* copy needed so we don't modify input's tlist below */
56985715
tlist=copyObject(tlist);
5699-
lefttree=inject_projection_plan(lefttree,tlist);
5716+
lefttree=inject_projection_plan(lefttree,tlist,
5717+
lefttree->parallel_safe);
57005718
}
57015719

57025720
/* Don't bother testing is_projection_capable_plan again */
@@ -5975,6 +5993,7 @@ materialize_finished_plan(Plan *subplan)
59755993
matplan->plan_rows=subplan->plan_rows;
59765994
matplan->plan_width=subplan->plan_width;
59775995
matplan->parallel_aware= false;
5996+
matplan->parallel_safe=subplan->parallel_safe;
59785997

59795998
returnmatplan;
59805999
}

‎src/backend/optimizer/plan/planner.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -351,11 +351,9 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
351351

352352
/*
353353
* Optionally add a Gather node for testing purposes, provided this is
354-
* actually a safe thing to do. (Note: we assume adding a Material node
355-
* above did not change the parallel safety of the plan, so we can still
356-
* rely on best_path->parallel_safe.)
354+
* actually a safe thing to do.
357355
*/
358-
if (force_parallel_mode!=FORCE_PARALLEL_OFF&&best_path->parallel_safe)
356+
if (force_parallel_mode!=FORCE_PARALLEL_OFF&&top_plan->parallel_safe)
359357
{
360358
Gather*gather=makeNode(Gather);
361359

@@ -378,6 +376,7 @@ standard_planner(Query *parse, int cursorOptions, ParamListInfo boundParams)
378376
gather->plan.plan_rows=top_plan->plan_rows;
379377
gather->plan.plan_width=top_plan->plan_width;
380378
gather->plan.parallel_aware= false;
379+
gather->plan.parallel_safe= false;
381380

382381
/* use parallel mode for parallel plans. */
383382
root->glob->parallelModeNeeded= true;

‎src/backend/optimizer/plan/subselect.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ static Node *build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot,
5858
List*plan_params,
5959
SubLinkTypesubLinkType,intsubLinkId,
6060
Node*testexpr,booladjust_testexpr,
61-
boolunknownEqFalse,boolparallel_safe);
61+
boolunknownEqFalse);
6262
staticList*generate_subquery_params(PlannerInfo*root,List*tlist,
6363
List**paramIds);
6464
staticList*generate_subquery_vars(PlannerInfo*root,List*tlist,
@@ -550,8 +550,7 @@ make_subplan(PlannerInfo *root, Query *orig_subquery,
550550
/* And convert to SubPlan or InitPlan format. */
551551
result=build_subplan(root,plan,subroot,plan_params,
552552
subLinkType,subLinkId,
553-
testexpr, true,isTopQual,
554-
best_path->parallel_safe);
553+
testexpr, true,isTopQual);
555554

556555
/*
557556
* If it's a correlated EXISTS with an unimportant targetlist, we might be
@@ -605,8 +604,7 @@ make_subplan(PlannerInfo *root, Query *orig_subquery,
605604
plan_params,
606605
ANY_SUBLINK,0,
607606
newtestexpr,
608-
false, true,
609-
best_path->parallel_safe));
607+
false, true));
610608
/* Check we got what we expected */
611609
Assert(hashplan->parParam==NIL);
612610
Assert(hashplan->useHashTable);
@@ -635,7 +633,7 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot,
635633
List*plan_params,
636634
SubLinkTypesubLinkType,intsubLinkId,
637635
Node*testexpr,booladjust_testexpr,
638-
boolunknownEqFalse,boolparallel_safe)
636+
boolunknownEqFalse)
639637
{
640638
Node*result;
641639
SubPlan*splan;
@@ -654,7 +652,7 @@ build_subplan(PlannerInfo *root, Plan *plan, PlannerInfo *subroot,
654652
&splan->firstColCollation);
655653
splan->useHashTable= false;
656654
splan->unknownEqFalse=unknownEqFalse;
657-
splan->parallel_safe=parallel_safe;
655+
splan->parallel_safe=plan->parallel_safe;
658656
splan->setParam=NIL;
659657
splan->parParam=NIL;
660658
splan->args=NIL;
@@ -1218,7 +1216,8 @@ SS_process_ctes(PlannerInfo *root)
12181216

12191217
/*
12201218
* CTE scans are not considered for parallelism (cf
1221-
* set_rel_consider_parallel).
1219+
* set_rel_consider_parallel), and even if they were, initPlans aren't
1220+
* parallel-safe.
12221221
*/
12231222
splan->parallel_safe= false;
12241223
splan->setParam=NIL;

‎src/include/nodes/plannodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ typedef struct Plan
124124
* information needed for parallel query
125125
*/
126126
boolparallel_aware;/* engage parallel-aware logic? */
127+
boolparallel_safe;/* OK to use as part of parallel plan? */
127128

128129
/*
129130
* Common structural data for all Plan types.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp