@@ -2112,9 +2112,9 @@ cost_agg(Path *path, PlannerInfo *root,
2112
2112
/*
2113
2113
* The transCost.per_tuple component of aggcosts should be charged once
2114
2114
* per input tuple, corresponding to the costs of evaluating the aggregate
2115
- * transfns and their input expressions (with any startup cost of course
2116
- * charged but once). The finalCost component is charged once per output
2117
- * tuple, corresponding to the costs of evaluating the finalfns .
2115
+ * transfns and their input expressions. The finalCost.per_tuple component
2116
+ * is charged once per output tuple, corresponding to the costs of
2117
+ * evaluating the finalfns. Startup costs are of course charged but once .
2118
2118
*
2119
2119
* If we are grouping, we charge an additional cpu_operator_cost per
2120
2120
* grouping column per input tuple for grouping comparisons.
@@ -2136,7 +2136,8 @@ cost_agg(Path *path, PlannerInfo *root,
2136
2136
startup_cost = input_total_cost ;
2137
2137
startup_cost += aggcosts -> transCost .startup ;
2138
2138
startup_cost += aggcosts -> transCost .per_tuple * input_tuples ;
2139
- startup_cost += aggcosts -> finalCost ;
2139
+ startup_cost += aggcosts -> finalCost .startup ;
2140
+ startup_cost += aggcosts -> finalCost .per_tuple ;
2140
2141
/* we aren't grouping */
2141
2142
total_cost = startup_cost + cpu_tuple_cost ;
2142
2143
output_tuples = 1 ;
@@ -2155,7 +2156,8 @@ cost_agg(Path *path, PlannerInfo *root,
2155
2156
total_cost += aggcosts -> transCost .startup ;
2156
2157
total_cost += aggcosts -> transCost .per_tuple * input_tuples ;
2157
2158
total_cost += (cpu_operator_cost * numGroupCols ) * input_tuples ;
2158
- total_cost += aggcosts -> finalCost * numGroups ;
2159
+ total_cost += aggcosts -> finalCost .startup ;
2160
+ total_cost += aggcosts -> finalCost .per_tuple * numGroups ;
2159
2161
total_cost += cpu_tuple_cost * numGroups ;
2160
2162
output_tuples = numGroups ;
2161
2163
}
@@ -2168,8 +2170,9 @@ cost_agg(Path *path, PlannerInfo *root,
2168
2170
startup_cost += aggcosts -> transCost .startup ;
2169
2171
startup_cost += aggcosts -> transCost .per_tuple * input_tuples ;
2170
2172
startup_cost += (cpu_operator_cost * numGroupCols ) * input_tuples ;
2173
+ startup_cost += aggcosts -> finalCost .startup ;
2171
2174
total_cost = startup_cost ;
2172
- total_cost += aggcosts -> finalCost * numGroups ;
2175
+ total_cost += aggcosts -> finalCost . per_tuple * numGroups ;
2173
2176
total_cost += cpu_tuple_cost * numGroups ;
2174
2177
output_tuples = numGroups ;
2175
2178
}
@@ -2234,7 +2237,11 @@ cost_windowagg(Path *path, PlannerInfo *root,
2234
2237
Cost wfunccost ;
2235
2238
QualCost argcosts ;
2236
2239
2237
- wfunccost = get_func_cost (wfunc -> winfnoid ) * cpu_operator_cost ;
2240
+ argcosts .startup = argcosts .per_tuple = 0 ;
2241
+ add_function_cost (root , wfunc -> winfnoid , (Node * ) wfunc ,
2242
+ & argcosts );
2243
+ startup_cost += argcosts .startup ;
2244
+ wfunccost = argcosts .per_tuple ;
2238
2245
2239
2246
/* also add the input expressions' cost to per-input-row costs */
2240
2247
cost_qual_eval_node (& argcosts , (Node * ) wfunc -> args , root );
@@ -3864,17 +3871,17 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
3864
3871
*/
3865
3872
if (IsA (node , FuncExpr ))
3866
3873
{
3867
- context -> total . per_tuple +=
3868
- get_func_cost ((( FuncExpr * ) node ) -> funcid ) * cpu_operator_cost ;
3874
+ add_function_cost ( context -> root , (( FuncExpr * ) node ) -> funcid , node ,
3875
+ & context -> total ) ;
3869
3876
}
3870
3877
else if (IsA (node , OpExpr ) ||
3871
3878
IsA (node , DistinctExpr ) ||
3872
3879
IsA (node , NullIfExpr ))
3873
3880
{
3874
3881
/* rely on struct equivalence to treat these all alike */
3875
3882
set_opfuncid ((OpExpr * ) node );
3876
- context -> total . per_tuple +=
3877
- get_func_cost ((( OpExpr * ) node ) -> opfuncid ) * cpu_operator_cost ;
3883
+ add_function_cost ( context -> root , (( OpExpr * ) node ) -> opfuncid , node ,
3884
+ & context -> total ) ;
3878
3885
}
3879
3886
else if (IsA (node , ScalarArrayOpExpr ))
3880
3887
{
@@ -3884,10 +3891,15 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
3884
3891
*/
3885
3892
ScalarArrayOpExpr * saop = (ScalarArrayOpExpr * ) node ;
3886
3893
Node * arraynode = (Node * ) lsecond (saop -> args );
3894
+ QualCost sacosts ;
3887
3895
3888
3896
set_sa_opfuncid (saop );
3889
- context -> total .per_tuple += get_func_cost (saop -> opfuncid ) *
3890
- cpu_operator_cost * estimate_array_length (arraynode ) * 0.5 ;
3897
+ sacosts .startup = sacosts .per_tuple = 0 ;
3898
+ add_function_cost (context -> root , saop -> opfuncid , NULL ,
3899
+ & sacosts );
3900
+ context -> total .startup += sacosts .startup ;
3901
+ context -> total .per_tuple += sacosts .per_tuple *
3902
+ estimate_array_length (arraynode ) * 0.5 ;
3891
3903
}
3892
3904
else if (IsA (node , Aggref ) ||
3893
3905
IsA (node , WindowFunc ))
@@ -3913,11 +3925,13 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
3913
3925
/* check the result type's input function */
3914
3926
getTypeInputInfo (iocoerce -> resulttype ,
3915
3927
& iofunc , & typioparam );
3916
- context -> total .per_tuple += get_func_cost (iofunc ) * cpu_operator_cost ;
3928
+ add_function_cost (context -> root , iofunc , NULL ,
3929
+ & context -> total );
3917
3930
/* check the input type's output function */
3918
3931
getTypeOutputInfo (exprType ((Node * ) iocoerce -> arg ),
3919
3932
& iofunc , & typisvarlena );
3920
- context -> total .per_tuple += get_func_cost (iofunc ) * cpu_operator_cost ;
3933
+ add_function_cost (context -> root , iofunc , NULL ,
3934
+ & context -> total );
3921
3935
}
3922
3936
else if (IsA (node , ArrayCoerceExpr ))
3923
3937
{
@@ -3941,8 +3955,8 @@ cost_qual_eval_walker(Node *node, cost_qual_eval_context *context)
3941
3955
{
3942
3956
Oid opid = lfirst_oid (lc );
3943
3957
3944
- context -> total . per_tuple += get_func_cost ( get_opcode (opid )) *
3945
- cpu_operator_cost ;
3958
+ add_function_cost ( context -> root , get_opcode (opid ), NULL ,
3959
+ & context -> total ) ;
3946
3960
}
3947
3961
}
3948
3962
else if (IsA (node , MinMaxExpr ) ||
@@ -4941,7 +4955,7 @@ set_function_size_estimates(PlannerInfo *root, RelOptInfo *rel)
4941
4955
foreach (lc , rte -> functions )
4942
4956
{
4943
4957
RangeTblFunction * rtfunc = (RangeTblFunction * ) lfirst (lc );
4944
- double ntup = expression_returns_set_rows (rtfunc -> funcexpr );
4958
+ double ntup = expression_returns_set_rows (root , rtfunc -> funcexpr );
4945
4959
4946
4960
if (ntup > rel -> tuples )
4947
4961
rel -> tuples = ntup ;
0 commit comments