@ -1045,7 +1045,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
double sub_limit_tuples ;
AttrNumber * groupColIdx = NULL ;
bool need_tlist_eval = true ;
QualCost tlist_cost ;
Path * cheapest_path ;
Path * sorted_path ;
Path * best_path ;
@ -1355,27 +1354,9 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
/*
* Also , account for the cost of evaluation of the sub_tlist .
*
* Up to now , we have only been dealing with " flat " tlists ,
* containing just Vars . So their evaluation cost is zero
* according to the model used by cost_qual_eval ( ) ( or if you
* prefer , the cost is factored into cpu_tuple_cost ) . Thus we
* can avoid accounting for tlist cost throughout
* query_planner ( ) and subroutines . But now we ' ve inserted a
* tlist that might contain actual operators , sub - selects , etc
* - - - so we ' d better account for its cost .
*
* Below this point , any tlist eval cost for added - on nodes
* should be accounted for as we create those nodes .
* Presently , of the node types we can add on , only Agg ,
* WindowAgg , and Group project new tlists ( the rest just copy
* their input tuples ) - - - so make_agg ( ) , make_windowagg ( ) and
* make_group ( ) are responsible for computing the added cost .
* See comments for add_tlist_costs_to_plan ( ) for more info .
*/
cost_qual_eval ( & tlist_cost , sub_tlist , root ) ;
result_plan - > startup_cost + = tlist_cost . startup ;
result_plan - > total_cost + = tlist_cost . startup +
tlist_cost . per_tuple * result_plan - > plan_rows ;
add_tlist_costs_to_plan ( root , result_plan , sub_tlist ) ;
}
else
{
@ -1815,6 +1796,61 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
return result_plan ;
}
/*
* add_tlist_costs_to_plan
*
* Estimate the execution costs associated with evaluating the targetlist
* expressions , and add them to the cost estimates for the Plan node .
*
* If the tlist contains set - returning functions , also inflate the Plan ' s cost
* and plan_rows estimates accordingly . ( Hence , this must be called * after *
* any logic that uses plan_rows to , eg , estimate qual evaluation costs . )
*
* Note : during initial stages of planning , we mostly consider plan nodes with
* " flat " tlists , containing just Vars . So their evaluation cost is zero
* according to the model used by cost_qual_eval ( ) ( or if you prefer , the cost
* is factored into cpu_tuple_cost ) . Thus we can avoid accounting for tlist
* cost throughout query_planner ( ) and subroutines . But once we apply a
* tlist that might contain actual operators , sub - selects , etc , we ' d better
* account for its cost . Any set - returning functions in the tlist must also
* affect the estimated rowcount .
*
* Once grouping_planner ( ) has applied a general tlist to the topmost
* scan / join plan node , any tlist eval cost for added - on nodes should be
* accounted for as we create those nodes . Presently , of the node types we
* can add on later , only Agg , WindowAgg , and Group project new tlists ( the
* rest just copy their input tuples ) - - - so make_agg ( ) , make_windowagg ( ) and
* make_group ( ) are responsible for calling this function to account for their
* tlist costs .
*/
void
add_tlist_costs_to_plan ( PlannerInfo * root , Plan * plan , List * tlist )
{
QualCost tlist_cost ;
double tlist_rows ;
cost_qual_eval ( & tlist_cost , tlist , root ) ;
plan - > startup_cost + = tlist_cost . startup ;
plan - > total_cost + = tlist_cost . startup +
tlist_cost . per_tuple * plan - > plan_rows ;
tlist_rows = tlist_returns_set_rows ( tlist ) ;
if ( tlist_rows > 1 )
{
/*
* We assume that execution costs of the tlist proper were all
* accounted for by cost_qual_eval . However , it still seems
* appropriate to charge something more for the executor ' s general
* costs of processing the added tuples . The cost is probably less
* than cpu_tuple_cost , though , so we arbitrarily use half of that .
*/
plan - > total_cost + = plan - > plan_rows * ( tlist_rows - 1 ) *
cpu_tuple_cost / 2 ;
plan - > plan_rows * = tlist_rows ;
}
}
/*
* Detect whether a plan node is a " dummy " plan created when a relation
* is deemed not to need scanning due to constraint exclusion .