diff options
Diffstat (limited to 'src/backend/optimizer/plan')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 4 | ||||
-rw-r--r-- | src/backend/optimizer/plan/initsplan.c | 5 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 9 |
3 files changed, 13 insertions, 5 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 243e41d0cde..d138728e679 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -5307,7 +5307,8 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, * that we treat Aggrefs as if they were variables; this is * necessary when attempting to sort the output from an Agg node * for use in a WindowFunc (since grouping_planner will have - * treated the Aggrefs as variables, too). + * treated the Aggrefs as variables, too). Likewise, if we find a + * WindowFunc in a sort expression, treat it as a variable. */ Expr *sortexpr = NULL; @@ -5336,6 +5337,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, sortexpr = em->em_expr; exprvars = pull_var_clause((Node *) sortexpr, PVC_INCLUDE_AGGREGATES | + PVC_INCLUDE_WINDOWFUNCS | PVC_INCLUDE_PLACEHOLDERS); foreach(k, exprvars) { diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 4cbaa5a8816..64bc8a8e597 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -147,6 +147,7 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist) { List *tlist_vars = pull_var_clause((Node *) final_tlist, PVC_RECURSE_AGGREGATES | + PVC_RECURSE_WINDOWFUNCS | PVC_INCLUDE_PLACEHOLDERS); if (tlist_vars != NIL) @@ -156,7 +157,8 @@ build_base_rel_tlists(PlannerInfo *root, List *final_tlist) } /* - * If there's a HAVING clause, we'll need the Vars it uses, too. + * If there's a HAVING clause, we'll need the Vars it uses, too. Note + * that HAVING can contain Aggrefs but not WindowFuncs. */ if (root->parse->havingQual) { @@ -1788,6 +1790,7 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause, { List *vars = pull_var_clause(clause, PVC_RECURSE_AGGREGATES | + PVC_RECURSE_WINDOWFUNCS | PVC_INCLUDE_PLACEHOLDERS); add_vars_to_targetlist(root, vars, relids, false); diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0161acf5223..a2cd6deb612 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -3837,11 +3837,12 @@ make_group_input_target(PlannerInfo *root, List *tlist) * add them to the result tlist if not already present. (A Var used * directly as a GROUP BY item will be present already.) Note this * includes Vars used in resjunk items, so we are covering the needs of - * ORDER BY and window specifications. Vars used within Aggrefs will be - * pulled out here, too. + * ORDER BY and window specifications. Vars used within Aggrefs and + * WindowFuncs will be pulled out here, too. */ non_group_vars = pull_var_clause((Node *) non_group_cols, PVC_RECURSE_AGGREGATES | + PVC_RECURSE_WINDOWFUNCS | PVC_INCLUDE_PLACEHOLDERS); sub_tlist = add_to_flat_tlist(sub_tlist, non_group_vars); @@ -4086,10 +4087,12 @@ make_window_input_target(PlannerInfo *root, * * Note: it's essential to use PVC_INCLUDE_AGGREGATES here, so that the * Aggrefs are placed in the Agg node's tlist and not left to be computed - * at higher levels. + * at higher levels. On the other hand, we should recurse into + * WindowFuncs to make sure their input expressions are available. */ flattenable_vars = pull_var_clause((Node *) flattenable_cols, PVC_INCLUDE_AGGREGATES | + PVC_RECURSE_WINDOWFUNCS | PVC_INCLUDE_PLACEHOLDERS); new_tlist = add_to_flat_tlist(new_tlist, flattenable_vars); |