summaryrefslogtreecommitdiff
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.c51
1 files changed, 43 insertions, 8 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 1e4dd27dbaf..eaee9eda771 100644
--- a/src/backend/optimizer/plan/planner.c
+++ b/src/backend/optimizer/plan/planner.c
@@ -5999,6 +5999,9 @@ make_window_input_target(PlannerInfo *root,
* Create a pathkeys list describing the required input ordering
* for the given WindowClause.
*
+ * Modifies wc's partitionClause to remove any clauses which are deemed
+ * redundant by the pathkey logic.
+ *
* The required ordering is first the PARTITION keys, then the ORDER keys.
* In the future we might try to implement windowing using hashing, in which
* case the ordering could be relaxed, but for now we always sort.
@@ -6007,8 +6010,7 @@ static List *
make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc,
List *tlist)
{
- List *window_pathkeys;
- List *window_sortclauses;
+ List *window_pathkeys = NIL;
/* Throw error if can't sort */
if (!grouping_is_sortable(wc->partitionClause))
@@ -6022,12 +6024,45 @@ make_pathkeys_for_window(PlannerInfo *root, WindowClause *wc,
errmsg("could not implement window ORDER BY"),
errdetail("Window ordering columns must be of sortable datatypes.")));
- /* Okay, make the combined pathkeys */
- window_sortclauses = list_concat_copy(wc->partitionClause, wc->orderClause);
- window_pathkeys = make_pathkeys_for_sortclauses(root,
- window_sortclauses,
- tlist);
- list_free(window_sortclauses);
+ /*
+ * First fetch the pathkeys for the PARTITION BY clause. We can safely
+ * remove any clauses from the wc->partitionClause for redundant pathkeys.
+ */
+ if (wc->partitionClause != NIL)
+ {
+ bool sortable;
+
+ window_pathkeys = make_pathkeys_for_sortclauses_extended(root,
+ &wc->partitionClause,
+ tlist,
+ true,
+ &sortable);
+
+ Assert(sortable);
+ }
+
+ /*
+ * In principle, we could also consider removing redundant ORDER BY items
+ * too as doing so does not alter the result of peer row checks done by
+ * the executor. However, we must *not* remove the ordering column for
+ * RANGE OFFSET cases, as the executor needs that for in_range tests even
+ * if it's known to be equal to some partitioning column.
+ */
+ if (wc->orderClause != NIL)
+ {
+ List *orderby_pathkeys;
+
+ orderby_pathkeys = make_pathkeys_for_sortclauses(root,
+ wc->orderClause,
+ tlist);
+
+ /* Okay, make the combined pathkeys */
+ if (window_pathkeys != NIL)
+ window_pathkeys = append_pathkeys(window_pathkeys, orderby_pathkeys);
+ else
+ window_pathkeys = orderby_pathkeys;
+ }
+
return window_pathkeys;
}