aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 5320da51a06..032818423f6 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -870,9 +870,6 @@ subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root,
EXPRKIND_LIMIT);
wc->endOffset = preprocess_expression(root, wc->endOffset,
EXPRKIND_LIMIT);
- wc->runCondition = (List *) preprocess_expression(root,
- (Node *) wc->runCondition,
- EXPRKIND_TARGET);
}
parse->limitOffset = preprocess_expression(root, parse->limitOffset,
@@ -4527,9 +4524,11 @@ create_one_window_path(PlannerInfo *root,
{
WindowClause *wc = lfirst_node(WindowClause, l);
List *window_pathkeys;
+ List *runcondition = NIL;
int presorted_keys;
bool is_sorted;
bool topwindow;
+ ListCell *lc2;
window_pathkeys = make_pathkeys_for_window(root,
wc,
@@ -4577,7 +4576,6 @@ create_one_window_path(PlannerInfo *root,
* we do need to account for the increase in tlist width.
*/
int64 tuple_width = window_target->width;
- ListCell *lc2;
window_target = copy_pathtarget(window_target);
foreach(lc2, wflists->windowFuncs[wc->winref])
@@ -4599,17 +4597,53 @@ create_one_window_path(PlannerInfo *root,
topwindow = foreach_current_index(l) == list_length(activeWindows) - 1;
/*
- * Accumulate all of the runConditions from each intermediate
- * WindowClause. The top-level WindowAgg must pass these as a qual so
- * that it filters out unwanted tuples correctly.
+ * Collect the WindowFuncRunConditions from each WindowFunc and
+ * convert them into OpExprs
*/
- if (!topwindow)
- topqual = list_concat(topqual, wc->runCondition);
+ foreach(lc2, wflists->windowFuncs[wc->winref])
+ {
+ ListCell *lc3;
+ WindowFunc *wfunc = lfirst_node(WindowFunc, lc2);
+
+ foreach(lc3, wfunc->runCondition)
+ {
+ WindowFuncRunCondition *wfuncrc =
+ lfirst_node(WindowFuncRunCondition, lc3);
+ Expr *opexpr;
+ Expr *leftop;
+ Expr *rightop;
+
+ if (wfuncrc->wfunc_left)
+ {
+ leftop = (Expr *) copyObject(wfunc);
+ rightop = copyObject(wfuncrc->arg);
+ }
+ else
+ {
+ leftop = copyObject(wfuncrc->arg);
+ rightop = (Expr *) copyObject(wfunc);
+ }
+
+ opexpr = make_opclause(wfuncrc->opno,
+ BOOLOID,
+ false,
+ leftop,
+ rightop,
+ InvalidOid,
+ wfuncrc->inputcollid);
+
+ runcondition = lappend(runcondition, opexpr);
+
+ if (!topwindow)
+ topqual = lappend(topqual, opexpr);
+ }
+ }
path = (Path *)
create_windowagg_path(root, window_rel, path, window_target,
wflists->windowFuncs[wc->winref],
- wc, topwindow ? topqual : NIL, topwindow);
+ runcondition, wc,
+ topwindow ? topqual : NIL, topwindow);
}
add_path(window_rel, path);