diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c index 89ca4e08bf1..5a221214b21 100644 --- a/src/backend/optimizer/path/costsize.c +++ b/src/backend/optimizer/path/costsize.c @@ -103,6 +103,7 @@ #include "optimizer/placeholder.h" #include "optimizer/plancat.h" #include "optimizer/restrictinfo.h" +#include "optimizer/rpr.h" #include "parser/parsetree.h" #include "utils/lsyscache.h" #include "utils/selfuncs.h" @@ -3227,12 +3228,16 @@ cost_windowagg(Path *path, PlannerInfo *root, * many rows the window function will fetch, it's hard to do better. In * any case, it's a good estimate for all the built-in window functions, * so we'll just do this for now. + * + * Moreover, if DEFINE/PATTERN clause exists, we charge their expressions + * per tuple. */ foreach(lc, windowFuncs) { WindowFunc *wfunc = lfirst_node(WindowFunc, lc); Cost wfunccost; QualCost argcosts; + QualCost defcosts; argcosts.startup = argcosts.per_tuple = 0; add_function_cost(root, wfunc->winfnoid, (Node *) wfunc, @@ -3245,6 +3250,37 @@ cost_windowagg(Path *path, PlannerInfo *root, startup_cost += argcosts.startup; wfunccost += argcosts.per_tuple; + /* also add DEFINE clause expressions' cost to per-input-row costs */ + if (winclause->rpPattern) + { + List *pattern_vars; /* list of pattern variable names */ + ListCell *lc2; + + pattern_vars = collectPatternVariables(winclause->rpPattern); + + /* iterate according to the pattern variable */ + foreach(lc2, pattern_vars) + { + char *ptname = strVal((char *) lfirst(lc2)); + + /* iterate according to the DEFINE clause */ + foreach_node(TargetEntry, def, winclause->defineClause) + { + if (!strcmp(ptname, def->resname)) + { + /* + * varname found. Add DEFINE clause expressions' cost + * to per-input-row costs. + */ + cost_qual_eval_node(&defcosts, (Node *) def->expr, root); + startup_cost += defcosts.startup; + wfunccost += defcosts.per_tuple; + } + } + } + list_free_deep(pattern_vars); + } + /* * Add the filter's cost to per-input-row costs. XXX We should reduce * input expression costs according to filter selectivity.