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

Commit4ea9948

Browse files
committed
Fix up parallel-safety marking for appendrels.
The previous coding assumed that the value derived byset_rel_consider_parallel() for an appendrel parent would be accurate forall the appendrel's children; but this is not so, for example because onechild might scan a temp table. Instead, apply set_rel_consider_parallel()to each child rel as well as the parent, and then take the AND of theresults as controlling parallel safety for the appendrel as a whole.(We might someday be able to deal more intelligently than this with casesin which some of the childrels are parallel-safe and others not, but that'sfor later.)Robert Haas and Tom Lane
1 parent2c6e647 commit4ea9948

File tree

1 file changed

+58
-15
lines changed

1 file changed

+58
-15
lines changed

‎src/backend/optimizer/path/allpaths.c

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ make_one_rel(PlannerInfo *root, List *joinlist)
165165
set_base_rel_consider_startup(root);
166166

167167
/*
168-
*Generate access paths for the base rels. set_base_rel_sizes also sets
169-
*the consider_parallel flag for each baserel, if appropriate.
168+
*Compute size estimates and consider_parallel flags for each base rel,
169+
*then generate access paths.
170170
*/
171171
set_base_rel_sizes(root);
172172
set_base_rel_pathlists(root);
@@ -234,7 +234,7 @@ set_base_rel_consider_startup(PlannerInfo *root)
234234
*
235235
* We do this in a separate pass over the base rels so that rowcount
236236
* estimates are available for parameterized path generation, and also so
237-
* thatthe consider_parallel flag is set correctly before we begin to
237+
* thateach rel's consider_parallel flag is set correctly before we begin to
238238
* generate paths.
239239
*/
240240
staticvoid
@@ -262,9 +262,10 @@ set_base_rel_sizes(PlannerInfo *root)
262262
/*
263263
* If parallelism is allowable for this query in general, see whether
264264
* it's allowable for this rel in particular. We have to do this
265-
* before set_rel_size, because that if this is an inheritance parent,
266-
* set_append_rel_size will pass the consider_parallel flag down to
267-
* inheritance children.
265+
* before set_rel_size(), because (a) if this rel is an inheritance
266+
* parent, set_append_rel_size() will use and perhaps change the rel's
267+
* consider_parallel flag, and (b) for some RTE types, set_rel_size()
268+
* goes ahead and makes paths immediately.
268269
*/
269270
if (root->glob->parallelModeOK)
270271
set_rel_consider_parallel(root,rel,rte);
@@ -494,18 +495,24 @@ set_plain_rel_size(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
494495

495496
/*
496497
* If this relation could possibly be scanned from within a worker, then set
497-
* the consider_parallel flag. The flag has previously been initialized to
498-
* false, so we just bail out if it becomes clear that we can't safely set it.
498+
* its consider_parallel flag.
499499
*/
500500
staticvoid
501501
set_rel_consider_parallel(PlannerInfo*root,RelOptInfo*rel,
502502
RangeTblEntry*rte)
503503
{
504+
/*
505+
* The flag has previously been initialized to false, so we can just
506+
* return if it becomes clear that we can't safely set it.
507+
*/
508+
Assert(!rel->consider_parallel);
509+
504510
/* Don't call this if parallelism is disallowed for the entire query. */
505511
Assert(root->glob->parallelModeOK);
506512

507-
/* Don't call this for non-baserels. */
508-
Assert(rel->reloptkind==RELOPT_BASEREL);
513+
/* This should only be called for baserels and appendrel children. */
514+
Assert(rel->reloptkind==RELOPT_BASEREL||
515+
rel->reloptkind==RELOPT_OTHER_MEMBER_REL);
509516

510517
/* Assorted checks based on rtekind. */
511518
switch (rte->rtekind)
@@ -556,6 +563,13 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
556563
if (!rel->fdwroutine->IsForeignScanParallelSafe(root,rel,rte))
557564
return;
558565
}
566+
567+
/*
568+
* There are additional considerations for appendrels, which we'll
569+
* deal with in set_append_rel_size and set_append_rel_pathlist.
570+
* For now, just set consider_parallel based on the rel's own
571+
* quals and targetlist.
572+
*/
559573
break;
560574

561575
caseRTE_SUBQUERY:
@@ -607,8 +621,9 @@ set_rel_consider_parallel(PlannerInfo *root, RelOptInfo *rel,
607621
* give up on parallelizing access to this relation. We could consider
608622
* instead postponing application of the restricted quals until we're
609623
* above all the parallelism in the plan tree, but it's not clear that
610-
* this would be a win in very many cases, and it might be tricky to make
611-
* outer join clauses work correctly.
624+
* that would be a win in very many cases, and it might be tricky to make
625+
* outer join clauses work correctly. It would likely break equivalence
626+
* classes, too.
612627
*/
613628
if (has_parallel_hazard((Node*)rel->baserestrictinfo, false))
614629
return;
@@ -965,9 +980,6 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
965980
continue;
966981
}
967982

968-
/* Copy consider_parallel flag from parent. */
969-
childrel->consider_parallel=rel->consider_parallel;
970-
971983
/*
972984
* CE failed, so finish copying/modifying targetlist and join quals.
973985
*
@@ -1007,6 +1019,16 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
10071019
* otherrels. So we just leave the child's attr_needed empty.
10081020
*/
10091021

1022+
/*
1023+
* If parallelism is allowable for this query in general, see whether
1024+
* it's allowable for this childrel in particular. But if we've
1025+
* already decided the appendrel is not parallel-safe as a whole,
1026+
* there's no point in considering parallelism for this child. For
1027+
* consistency, do this before calling set_rel_size() for the child.
1028+
*/
1029+
if (root->glob->parallelModeOK&&rel->consider_parallel)
1030+
set_rel_consider_parallel(root,childrel,childRTE);
1031+
10101032
/*
10111033
* Compute the child's size.
10121034
*/
@@ -1023,6 +1045,18 @@ set_append_rel_size(PlannerInfo *root, RelOptInfo *rel,
10231045
/* We have at least one live child. */
10241046
has_live_children= true;
10251047

1048+
/*
1049+
* If any live child is not parallel-safe, treat the whole appendrel
1050+
* as not parallel-safe. In future we might be able to generate plans
1051+
* in which some children are farmed out to workers while others are
1052+
* not; but we don't have that today, so it's a waste to consider
1053+
* partial paths anywhere in the appendrel unless it's all safe.
1054+
* (Child rels visited before this one will be unmarked in
1055+
* set_append_rel_pathlist().)
1056+
*/
1057+
if (!childrel->consider_parallel)
1058+
rel->consider_parallel= false;
1059+
10261060
/*
10271061
* Accumulate size information from each live child.
10281062
*/
@@ -1139,6 +1173,15 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
11391173
childRTE=root->simple_rte_array[childRTindex];
11401174
childrel=root->simple_rel_array[childRTindex];
11411175

1176+
/*
1177+
* If set_append_rel_size() decided the parent appendrel was
1178+
* parallel-unsafe at some point after visiting this child rel, we
1179+
* need to propagate the unsafety marking down to the child, so that
1180+
* we don't generate useless partial paths for it.
1181+
*/
1182+
if (!rel->consider_parallel)
1183+
childrel->consider_parallel= false;
1184+
11421185
/*
11431186
* Compute the child's access paths.
11441187
*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp