| Line | Hits | Source | Commit |
| 3205 |
- |
cost_windowagg(Path *path, PlannerInfo *root, |
- |
| 3206 |
- |
List *windowFuncs, WindowClause *winclause, |
- |
| 3207 |
- |
int input_disabled_nodes, |
- |
| 3208 |
- |
Cost input_startup_cost, Cost input_total_cost, |
- |
| 3209 |
- |
double input_tuples) |
- |
| 3210 |
- |
{ |
- |
| 3211 |
- |
Cost startup_cost; |
- |
| 3212 |
- |
Cost total_cost; |
- |
| 3213 |
- |
double startup_tuples; |
- |
| 3214 |
- |
int numPartCols; |
- |
| 3215 |
- |
int numOrderCols; |
- |
| 3216 |
- |
ListCell *lc; |
- |
| 3217 |
- |
|
- |
| 3218 |
- |
numPartCols = list_length(winclause->partitionClause); |
- |
| 3219 |
- |
numOrderCols = list_length(winclause->orderClause); |
- |
| 3220 |
- |
|
- |
| 3221 |
- |
startup_cost = input_startup_cost; |
- |
| 3222 |
- |
total_cost = input_total_cost; |
- |
| 3223 |
- |
|
- |
| 3224 |
- |
/* |
- |
| 3225 |
- |
* Window functions are assumed to cost their stated execution cost, plus |
- |
| 3226 |
- |
* the cost of evaluating their input expressions, per tuple. Since they |
- |
| 3227 |
- |
* may in fact evaluate their inputs at multiple rows during each cycle, |
- |
| 3228 |
- |
* this could be a drastic underestimate; but without a way to know how |
- |
| 3229 |
- |
* many rows the window function will fetch, it's hard to do better. In |
- |
| 3230 |
- |
* any case, it's a good estimate for all the built-in window functions, |
- |
| 3231 |
- |
* so we'll just do this for now. |
- |
| 3232 |
- |
* |
7521a30Row pattern recognition patch (planner). |
| 3233 |
- |
* Moreover, if row pattern recognition is used, we charge the DEFINE |
7521a30Row pattern recognition patch (planner). |
| 3234 |
- |
* expressions once per tuple for each DEFINE variable. |
b848408Tidy up row pattern recognition plumbing |
| 3235 |
- |
*/ |
- |
| 3236 |
6368 |
if (winclause->rpPattern) |
7521a30Row pattern recognition patch (planner). |
| 3237 |
- |
{ |
7521a30Row pattern recognition patch (planner). |
| 3238 |
- |
QualCost defcosts; |
7521a30Row pattern recognition patch (planner). |
| 3239 |
- |
|
7521a30Row pattern recognition patch (planner). |
| 3240 |
12423 |
foreach_node(TargetEntry, def, winclause->defineClause) |
b848408Tidy up row pattern recognition plumbing |
| 3241 |
- |
{ |
7521a30Row pattern recognition patch (planner). |
| 3242 |
8679 |
cost_qual_eval_node(&defcosts, (Node *) def->expr, root); |
b848408Tidy up row pattern recognition plumbing |
| 3243 |
8679 |
startup_cost += defcosts.startup; |
b848408Tidy up row pattern recognition plumbing |
| 3244 |
8679 |
total_cost += defcosts.per_tuple * input_tuples; |
b848408Tidy up row pattern recognition plumbing |
| 3245 |
- |
} |
7521a30Row pattern recognition patch (planner). |
| 3246 |
- |
} |
7521a30Row pattern recognition patch (planner). |
| 3247 |
- |
|
7521a30Row pattern recognition patch (planner). |
| 3248 |
- |
foreach(lc, windowFuncs) |
- |
| 3249 |
- |
{ |
- |
| 3250 |
- |
WindowFunc *wfunc = lfirst_node(WindowFunc, lc); |
- |
| 3251 |
- |
Cost wfunccost; |
- |
| 3252 |
- |
QualCost argcosts; |
- |
| 3253 |
- |
|
- |
| 3254 |
- |
argcosts.startup = argcosts.per_tuple = 0; |
- |
| 3255 |
- |
add_function_cost(root, wfunc->winfnoid, (Node *) wfunc, |
- |
| 3256 |
- |
&argcosts); |
- |
| 3257 |
- |
startup_cost += argcosts.startup; |
- |
| 3258 |
- |
wfunccost = argcosts.per_tuple; |
- |
| 3259 |
- |
|
- |
| 3260 |
- |
/* also add the input expressions' cost to per-input-row costs */ |
- |
| 3261 |
- |
cost_qual_eval_node(&argcosts, (Node *) wfunc->args, root); |
- |
| 3262 |
- |
startup_cost += argcosts.startup; |
- |
| 3263 |
- |
wfunccost += argcosts.per_tuple; |
- |
| 3264 |
- |
|
- |
| 3265 |
- |
/* |
- |
| 3266 |
- |
* Add the filter's cost to per-input-row costs. XXX We should reduce |
- |
| 3267 |
- |
* input expression costs according to filter selectivity. |
- |
| 3268 |
- |
*/ |
- |
| 3269 |
- |
cost_qual_eval_node(&argcosts, (Node *) wfunc->aggfilter, root); |
- |
| 3270 |
- |
startup_cost += argcosts.startup; |
- |
| 3271 |
- |
wfunccost += argcosts.per_tuple; |
- |
| 3272 |
- |
|
- |
| 3273 |
- |
total_cost += wfunccost * input_tuples; |
- |
| 3274 |
- |
} |
- |
| 3275 |
- |
|
- |
| 3276 |
- |
/* |
- |
| 3277 |
- |
* We also charge cpu_operator_cost per grouping column per tuple for |
- |
| 3278 |
- |
* grouping comparisons, plus cpu_tuple_cost per tuple for general |
- |
| 3279 |
- |
* overhead. |
- |
| 3280 |
- |
* |
- |
| 3281 |
- |
* XXX this neglects costs of spooling the data to disk when it overflows |
- |
| 3282 |
- |
* work_mem. Sooner or later that should get accounted for. |
- |
| 3283 |
- |
*/ |
- |
| 3284 |
- |
total_cost += cpu_operator_cost * (numPartCols + numOrderCols) * input_tuples; |
- |
| 3285 |
- |
total_cost += cpu_tuple_cost * input_tuples; |
- |
| 3286 |
- |
|
- |
| 3287 |
- |
path->rows = input_tuples; |
- |
| 3288 |
- |
path->disabled_nodes = input_disabled_nodes; |
- |
| 3289 |
- |
path->startup_cost = startup_cost; |
- |
| 3290 |
- |
path->total_cost = total_cost; |
- |
| 3291 |
- |
|
- |
| 3292 |
- |
/* |
- |
| 3293 |
- |
* Also, take into account how many tuples we need to read from the |
- |
| 3294 |
- |
* subnode in order to produce the first tuple from the WindowAgg. To do |
- |
| 3295 |
- |
* this we proportion the run cost (total cost not including startup cost) |
- |
| 3296 |
- |
* over the estimated startup tuples. We already included the startup |
- |
| 3297 |
- |
* cost of the subnode, so we only need to do this when the estimated |
- |
| 3298 |
- |
* startup tuples is above 1.0. |
- |
| 3299 |
- |
*/ |
- |
| 3300 |
- |
startup_tuples = get_windowclause_startup_tuples(root, winclause, |
- |
| 3301 |
- |
input_tuples); |
- |
| 3302 |
- |
|
- |
| 3303 |
- |
if (startup_tuples > 1.0) |
- |
| 3304 |
- |
path->startup_cost += (total_cost - startup_cost) / input_tuples * |
- |
| 3305 |
- |
(startup_tuples - 1.0); |
- |
| 3306 |
- |
} |
- |