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

Commit96c698e

Browse files
committed
Fix parallel-safety marking when moving initplans to another node.
Our policy since commitab77a5a has been that a plan node havingany initplans is automatically not parallel-safe. (This could berelaxed, but not today.) clean_up_removed_plan_level neglectedthis, and could attach initplans to a parallel-safe child plannode without clearing the plan's parallel-safe flag. That couldlead to "subplan was not initialized" errors at runtime, in casean initplan referenced another one and only the referencing onegot transmitted to parallel workers.The fix in clean_up_removed_plan_level is trivial enough.materialize_finished_plan also moves initplans from one nodeto another, but it's okay because it already copies the sourcenode's parallel_safe flag. The other place that does this kindof thing is standard_planner's hack to inject a top-level Gatherwhen debug_parallel_query is active. But that's actually deadcode given that we're correctly enforcing the "initplans aren'tparallel safe" rule, so just replace it with an Assert thatthere are no initplans.Also improve some related comments.Normally we'd add a regression test case for this sort of bug.The mistake itself is already reached by existing tests, but thereis accidentally no visible problem. The only known test case thatcreates an actual failure seems too indirect and fragile to justifykeeping it as a regression test (not least because it fails to failin v11, though the bug is clearly present there too).Per report from Justin Pryzby. Back-patch to all supported branches.Discussion:https://postgr.es/m/ZDVt6MaNWkRDO1LQ@telsasoft.com
1 parent154bcce commit96c698e

File tree

4 files changed

+22
-10
lines changed

4 files changed

+22
-10
lines changed

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,12 +430,10 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions,
430430
Gather*gather=makeNode(Gather);
431431

432432
/*
433-
* If there are any initPlans attached to the formerly-top plan node,
434-
* move them up to the Gather node; same as we do for Material node in
435-
* materialize_finished_plan.
433+
* Top plan must not have any initPlans, else it shouldn't have been
434+
* marked parallel-safe.
436435
*/
437-
gather->plan.initPlan=top_plan->initPlan;
438-
top_plan->initPlan=NIL;
436+
Assert(top_plan->initPlan==NIL);
439437

440438
gather->plan.targetlist=top_plan->targetlist;
441439
gather->plan.qual=NIL;

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1186,7 +1186,19 @@ trivial_subqueryscan(SubqueryScan *plan)
11861186
staticPlan*
11871187
clean_up_removed_plan_level(Plan*parent,Plan*child)
11881188
{
1189-
/* We have to be sure we don't lose any initplans */
1189+
/*
1190+
* We have to be sure we don't lose any initplans, so move any that were
1191+
* attached to the parent plan to the child. If we do move any, the child
1192+
* is no longer parallel-safe.
1193+
*/
1194+
if (parent->initPlan)
1195+
child->parallel_safe= false;
1196+
1197+
/*
1198+
* Attach plans this way so that parent's initplans are processed before
1199+
* any pre-existing initplans of the child. Probably doesn't matter, but
1200+
* let's preserve the ordering just in case.
1201+
*/
11901202
child->initPlan=list_concat(parent->initPlan,
11911203
child->initPlan);
11921204

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2095,7 +2095,7 @@ SS_identify_outer_params(PlannerInfo *root)
20952095
* This is separate from SS_attach_initplans because we might conditionally
20962096
* create more initPlans during create_plan(), depending on which Path we
20972097
* select. However, Paths that would generate such initPlans are expected
2098-
* to have included their cost already.
2098+
* to have included their costand parallel-safety effectsalready.
20992099
*/
21002100
void
21012101
SS_charge_for_initplans(PlannerInfo*root,RelOptInfo*final_rel)
@@ -2151,8 +2151,10 @@ SS_charge_for_initplans(PlannerInfo *root, RelOptInfo *final_rel)
21512151
* (In principle the initPlans could go in any node at or above where they're
21522152
* referenced; but there seems no reason to put them any lower than the
21532153
* topmost node, so we don't bother to track exactly where they came from.)
2154-
* We do not touch the plan node's cost; the initplans should have been
2155-
* accounted for in path costing.
2154+
*
2155+
* We do not touch the plan node's cost or parallel_safe flag. The initplans
2156+
* must have been accounted for in SS_charge_for_initplans, or by any later
2157+
* code that adds initplans via SS_make_initplan_from_plan.
21562158
*/
21572159
void
21582160
SS_attach_initplans(PlannerInfo*root,Plan*plan)

‎src/backend/optimizer/util/pathnode.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3264,7 +3264,7 @@ create_minmaxagg_path(PlannerInfo *root,
32643264
/* For now, assume we are above any joins, so no parameterization */
32653265
pathnode->path.param_info=NULL;
32663266
pathnode->path.parallel_aware= false;
3267-
/* A MinMaxAggPath implies use ofsubplans, so cannot be parallel-safe */
3267+
/* A MinMaxAggPath implies use ofinitplans, so cannot be parallel-safe */
32683268
pathnode->path.parallel_safe= false;
32693269
pathnode->path.parallel_workers=0;
32703270
/* Result is one unordered row */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp