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

Commit41efb83

Browse files
committed
Move resolution of AlternativeSubPlan choices to the planner.
When commitbd3dadd introduced AlternativeSubPlans, I had someambitions towards allowing the choice of subplan to change duringexecution. That has not happened, or even been thought about, in theensuing twelve years; so it seems like a failed experiment. So let'srip that out and resolve the choice of subplan at the end of planning(in setrefs.c) rather than during executor startup. This has a numberof positive benefits:* Removal of a few hundred lines of executor code, sinceAlternativeSubPlans need no longer be supported there.* Removal of executor-startup overhead (particularly, initializationof subplans that won't be used).* Removal of incidental costs of having a larger plan tree, such astree-scanning and copying costs in the plancache; not to mentionsetrefs.c's own costs of processing the discarded subplans.* EXPLAIN no longer has to print a weird (and undocumented)representation of an AlternativeSubPlan choice; it sees only thesubplan actually used. This should mean less confusion for users.* Since setrefs.c knows which subexpression of a plan node it'sworking on at any instant, it's possible to adjust the estimatednumber of executions of the subplan based on that. For example,we should usually estimate more executions of a qual expressionthan a targetlist expression. The implementation used here ispretty simplistic, because we don't want to expend a lot of cycleson the issue; but it's better than ignoring the point entirely,as the executor had to.That last point might possibly result in shifting the choicebetween hashed and non-hashed EXISTS subplans in a few cases,but in general this patch isn't meant to change planner choices.Since we're doing the resolution so late, it's really impossibleto change any plan choices outside the AlternativeSubPlan itself.Patch by me; thanks to David Rowley for review.Discussion:https://postgr.es/m/1992952.1592785225@sss.pgh.pa.us
1 parent3c88199 commit41efb83

File tree

20 files changed

+412
-295
lines changed

20 files changed

+412
-295
lines changed

‎src/backend/executor/execExpr.c

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1104,23 +1104,6 @@ ExecInitExprRec(Expr *node, ExprState *state,
11041104
break;
11051105
}
11061106

1107-
caseT_AlternativeSubPlan:
1108-
{
1109-
AlternativeSubPlan*asplan= (AlternativeSubPlan*)node;
1110-
AlternativeSubPlanState*asstate;
1111-
1112-
if (!state->parent)
1113-
elog(ERROR,"AlternativeSubPlan found with no parent plan");
1114-
1115-
asstate=ExecInitAlternativeSubPlan(asplan,state->parent);
1116-
1117-
scratch.opcode=EEOP_ALTERNATIVE_SUBPLAN;
1118-
scratch.d.alternative_subplan.asstate=asstate;
1119-
1120-
ExprEvalPushStep(state,&scratch);
1121-
break;
1122-
}
1123-
11241107
caseT_FieldSelect:
11251108
{
11261109
FieldSelect*fselect= (FieldSelect*)node;

‎src/backend/executor/execExprInterp.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
431431
&&CASE_EEOP_GROUPING_FUNC,
432432
&&CASE_EEOP_WINDOW_FUNC,
433433
&&CASE_EEOP_SUBPLAN,
434-
&&CASE_EEOP_ALTERNATIVE_SUBPLAN,
435434
&&CASE_EEOP_AGG_STRICT_DESERIALIZE,
436435
&&CASE_EEOP_AGG_DESERIALIZE,
437436
&&CASE_EEOP_AGG_STRICT_INPUT_CHECK_ARGS,
@@ -1536,14 +1535,6 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
15361535
EEO_NEXT();
15371536
}
15381537

1539-
EEO_CASE(EEOP_ALTERNATIVE_SUBPLAN)
1540-
{
1541-
/* too complex for an inline implementation */
1542-
ExecEvalAlternativeSubPlan(state,op,econtext);
1543-
1544-
EEO_NEXT();
1545-
}
1546-
15471538
/* evaluate a strict aggregate deserialization function */
15481539
EEO_CASE(EEOP_AGG_STRICT_DESERIALIZE)
15491540
{
@@ -3868,20 +3859,6 @@ ExecEvalSubPlan(ExprState *state, ExprEvalStep *op, ExprContext *econtext)
38683859
*op->resvalue=ExecSubPlan(sstate,econtext,op->resnull);
38693860
}
38703861

3871-
/*
3872-
* Hand off evaluation of an alternative subplan to nodeSubplan.c
3873-
*/
3874-
void
3875-
ExecEvalAlternativeSubPlan(ExprState*state,ExprEvalStep*op,ExprContext*econtext)
3876-
{
3877-
AlternativeSubPlanState*asstate=op->d.alternative_subplan.asstate;
3878-
3879-
/* could potentially be nested, so make sure there's enough stack */
3880-
check_stack_depth();
3881-
3882-
*op->resvalue=ExecAlternativeSubPlan(asstate,econtext,op->resnull);
3883-
}
3884-
38853862
/*
38863863
* Evaluate a wholerow Var expression.
38873864
*

‎src/backend/executor/nodeSubplan.c

Lines changed: 0 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,83 +1303,3 @@ ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
13031303
parent->chgParam=bms_add_member(parent->chgParam,paramid);
13041304
}
13051305
}
1306-
1307-
1308-
/*
1309-
* ExecInitAlternativeSubPlan
1310-
*
1311-
* Initialize for execution of one of a set of alternative subplans.
1312-
*/
1313-
AlternativeSubPlanState*
1314-
ExecInitAlternativeSubPlan(AlternativeSubPlan*asplan,PlanState*parent)
1315-
{
1316-
AlternativeSubPlanState*asstate=makeNode(AlternativeSubPlanState);
1317-
doublenum_calls;
1318-
SubPlan*subplan1;
1319-
SubPlan*subplan2;
1320-
Costcost1;
1321-
Costcost2;
1322-
ListCell*lc;
1323-
1324-
asstate->subplan=asplan;
1325-
1326-
/*
1327-
* Initialize subplans. (Can we get away with only initializing the one
1328-
* we're going to use?)
1329-
*/
1330-
foreach(lc,asplan->subplans)
1331-
{
1332-
SubPlan*sp=lfirst_node(SubPlan,lc);
1333-
SubPlanState*sps=ExecInitSubPlan(sp,parent);
1334-
1335-
asstate->subplans=lappend(asstate->subplans,sps);
1336-
parent->subPlan=lappend(parent->subPlan,sps);
1337-
}
1338-
1339-
/*
1340-
* Select the one to be used. For this, we need an estimate of the number
1341-
* of executions of the subplan. We use the number of output rows
1342-
* expected from the parent plan node. This is a good estimate if we are
1343-
* in the parent's targetlist, and an underestimate (but probably not by
1344-
* more than a factor of 2) if we are in the qual.
1345-
*/
1346-
num_calls=parent->plan->plan_rows;
1347-
1348-
/*
1349-
* The planner saved enough info so that we don't have to work very hard
1350-
* to estimate the total cost, given the number-of-calls estimate.
1351-
*/
1352-
Assert(list_length(asplan->subplans)==2);
1353-
subplan1= (SubPlan*)linitial(asplan->subplans);
1354-
subplan2= (SubPlan*)lsecond(asplan->subplans);
1355-
1356-
cost1=subplan1->startup_cost+num_calls*subplan1->per_call_cost;
1357-
cost2=subplan2->startup_cost+num_calls*subplan2->per_call_cost;
1358-
1359-
if (cost1<cost2)
1360-
asstate->active=0;
1361-
else
1362-
asstate->active=1;
1363-
1364-
returnasstate;
1365-
}
1366-
1367-
/*
1368-
* ExecAlternativeSubPlan
1369-
*
1370-
* Execute one of a set of alternative subplans.
1371-
*
1372-
* Note: in future we might consider changing to different subplans on the
1373-
* fly, in case the original rowcount estimate turns out to be way off.
1374-
*/
1375-
Datum
1376-
ExecAlternativeSubPlan(AlternativeSubPlanState*node,
1377-
ExprContext*econtext,
1378-
bool*isNull)
1379-
{
1380-
/* Just pass control to the active subplan */
1381-
SubPlanState*activesp=list_nth_node(SubPlanState,
1382-
node->subplans,node->active);
1383-
1384-
returnExecSubPlan(activesp,econtext,isNull);
1385-
}

‎src/backend/jit/llvm/llvmjit_expr.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,12 +1918,6 @@ llvm_compile_expr(ExprState *state)
19181918
LLVMBuildBr(b,opblocks[opno+1]);
19191919
break;
19201920

1921-
caseEEOP_ALTERNATIVE_SUBPLAN:
1922-
build_EvalXFunc(b,mod,"ExecEvalAlternativeSubPlan",
1923-
v_state,op,v_econtext);
1924-
LLVMBuildBr(b,opblocks[opno+1]);
1925-
break;
1926-
19271921
caseEEOP_AGG_STRICT_DESERIALIZE:
19281922
caseEEOP_AGG_DESERIALIZE:
19291923
{

‎src/backend/jit/llvm/llvmjit_types.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ void *referenced_functions[] =
102102
ExecAggTransReparent,
103103
ExecEvalAggOrderedTransDatum,
104104
ExecEvalAggOrderedTransTuple,
105-
ExecEvalAlternativeSubPlan,
106105
ExecEvalArrayCoerce,
107106
ExecEvalArrayExpr,
108107
ExecEvalConstraintCheck,

‎src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2254,6 +2254,7 @@ _outPlannerInfo(StringInfo str, const PlannerInfo *node)
22542254
WRITE_BOOL_FIELD(hasLateralRTEs);
22552255
WRITE_BOOL_FIELD(hasHavingQual);
22562256
WRITE_BOOL_FIELD(hasPseudoConstantQuals);
2257+
WRITE_BOOL_FIELD(hasAlternativeSubPlans);
22572258
WRITE_BOOL_FIELD(hasRecursion);
22582259
WRITE_INT_FIELD(wt_param_id);
22592260
WRITE_BITMAPSET_FIELD(curOuterRels);

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,8 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
629629
root->minmax_aggs=NIL;
630630
root->qual_security_level=0;
631631
root->inhTargetKind=INHKIND_NONE;
632+
root->hasPseudoConstantQuals= false;
633+
root->hasAlternativeSubPlans= false;
632634
root->hasRecursion=hasRecursion;
633635
if (hasRecursion)
634636
root->wt_param_id=assign_special_exec_param(root);
@@ -759,9 +761,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse,
759761
*/
760762
root->hasHavingQual= (parse->havingQual!=NULL);
761763

762-
/* Clear this flag; might get set in distribute_qual_to_rels */
763-
root->hasPseudoConstantQuals= false;
764-
765764
/*
766765
* Do expression preprocessing on targetlist and quals, as well as other
767766
* random expressions in the querytree. Note that we do not need to

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp