mirror of
https://github.com/postgres/postgres.git
synced 2025-06-30 21:42:05 +03:00
Add new function planstate_tree_walker.
ExplainPreScanNode knows how to iterate over a generic tree of plan states; factor that logic out into a separate walker function so that other code, such as upcoming patches for parallel query, can also use it. Patch by me, reviewed by Tom Lane.
This commit is contained in:
@ -55,10 +55,7 @@ static void ExplainOneQuery(Query *query, IntoClause *into, ExplainState *es,
|
||||
static void report_triggers(ResultRelInfo *rInfo, bool show_relname,
|
||||
ExplainState *es);
|
||||
static double elapsed_time(instr_time *starttime);
|
||||
static void ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used);
|
||||
static void ExplainPreScanMemberNodes(List *plans, PlanState **planstates,
|
||||
Bitmapset **rels_used);
|
||||
static void ExplainPreScanSubPlans(List *plans, Bitmapset **rels_used);
|
||||
static bool ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used);
|
||||
static void ExplainNode(PlanState *planstate, List *ancestors,
|
||||
const char *relationship, const char *plan_name,
|
||||
ExplainState *es);
|
||||
@ -724,7 +721,7 @@ elapsed_time(instr_time *starttime)
|
||||
* This ensures that we don't confusingly assign un-suffixed aliases to RTEs
|
||||
* that never appear in the EXPLAIN output (such as inheritance parents).
|
||||
*/
|
||||
static void
|
||||
static bool
|
||||
ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
|
||||
{
|
||||
Plan *plan = planstate->plan;
|
||||
@ -764,91 +761,7 @@ ExplainPreScanNode(PlanState *planstate, Bitmapset **rels_used)
|
||||
break;
|
||||
}
|
||||
|
||||
/* initPlan-s */
|
||||
if (planstate->initPlan)
|
||||
ExplainPreScanSubPlans(planstate->initPlan, rels_used);
|
||||
|
||||
/* lefttree */
|
||||
if (outerPlanState(planstate))
|
||||
ExplainPreScanNode(outerPlanState(planstate), rels_used);
|
||||
|
||||
/* righttree */
|
||||
if (innerPlanState(planstate))
|
||||
ExplainPreScanNode(innerPlanState(planstate), rels_used);
|
||||
|
||||
/* special child plans */
|
||||
switch (nodeTag(plan))
|
||||
{
|
||||
case T_ModifyTable:
|
||||
ExplainPreScanMemberNodes(((ModifyTable *) plan)->plans,
|
||||
((ModifyTableState *) planstate)->mt_plans,
|
||||
rels_used);
|
||||
break;
|
||||
case T_Append:
|
||||
ExplainPreScanMemberNodes(((Append *) plan)->appendplans,
|
||||
((AppendState *) planstate)->appendplans,
|
||||
rels_used);
|
||||
break;
|
||||
case T_MergeAppend:
|
||||
ExplainPreScanMemberNodes(((MergeAppend *) plan)->mergeplans,
|
||||
((MergeAppendState *) planstate)->mergeplans,
|
||||
rels_used);
|
||||
break;
|
||||
case T_BitmapAnd:
|
||||
ExplainPreScanMemberNodes(((BitmapAnd *) plan)->bitmapplans,
|
||||
((BitmapAndState *) planstate)->bitmapplans,
|
||||
rels_used);
|
||||
break;
|
||||
case T_BitmapOr:
|
||||
ExplainPreScanMemberNodes(((BitmapOr *) plan)->bitmapplans,
|
||||
((BitmapOrState *) planstate)->bitmapplans,
|
||||
rels_used);
|
||||
break;
|
||||
case T_SubqueryScan:
|
||||
ExplainPreScanNode(((SubqueryScanState *) planstate)->subplan,
|
||||
rels_used);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* subPlan-s */
|
||||
if (planstate->subPlan)
|
||||
ExplainPreScanSubPlans(planstate->subPlan, rels_used);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prescan the constituent plans of a ModifyTable, Append, MergeAppend,
|
||||
* BitmapAnd, or BitmapOr node.
|
||||
*
|
||||
* Note: we don't actually need to examine the Plan list members, but
|
||||
* we need the list in order to determine the length of the PlanState array.
|
||||
*/
|
||||
static void
|
||||
ExplainPreScanMemberNodes(List *plans, PlanState **planstates,
|
||||
Bitmapset **rels_used)
|
||||
{
|
||||
int nplans = list_length(plans);
|
||||
int j;
|
||||
|
||||
for (j = 0; j < nplans; j++)
|
||||
ExplainPreScanNode(planstates[j], rels_used);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prescan a list of SubPlans (or initPlans, which also use SubPlan nodes).
|
||||
*/
|
||||
static void
|
||||
ExplainPreScanSubPlans(List *plans, Bitmapset **rels_used)
|
||||
{
|
||||
ListCell *lst;
|
||||
|
||||
foreach(lst, plans)
|
||||
{
|
||||
SubPlanState *sps = (SubPlanState *) lfirst(lst);
|
||||
|
||||
ExplainPreScanNode(sps->planstate, rels_used);
|
||||
}
|
||||
return planstate_tree_walker(planstate, ExplainPreScanNode, rels_used);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user