dont_remove_srf_windowfuncs.patch
text/plain
Filename: dont_remove_srf_windowfuncs.patch
Type: text/plain
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/allpaths.c | 52 | 3 |
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 7ac116a791..5dab40f6ff 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -3933,6 +3933,44 @@ recurse_push_qual(Node *setOp, Query *topquery,
* SIMPLIFYING SUBQUERY TARGETLISTS
*****************************************************************************/
+/*
+ * has_set_returning_window_clauses
+ * Returns true if 'node' contains any WindowFuncs which reference a
+ * WindowClause where the PARTITION BY or ORDER BY clause contains any
+ * set returning functions.
+ */
+static bool
+has_set_returning_window_clauses(Query *subquery, Node *node)
+{
+ WindowFuncLists *wflists;
+
+ wflists = find_window_functions(node,
+ list_length(subquery->windowClause));
+
+ if (wflists->numWindowFuncs == 0)
+ return false;
+
+ for (int i = 1; i <= wflists->maxWinRef; i++)
+ {
+ WindowClause *wclause;
+
+ if (wflists->windowFuncs[i] == NIL)
+ continue;
+
+ wclause = (WindowClause *) list_nth(subquery->windowClause, i - 1);
+
+ if (expression_returns_set((Node *) get_sortgrouplist_exprs(wclause->partitionClause,
+ subquery->targetList)))
+ return true;
+
+ if (expression_returns_set((Node *) get_sortgrouplist_exprs(wclause->orderClause,
+ subquery->targetList)))
+ return true;
+ }
+
+ return false;
+}
+
/*
* remove_unused_subquery_outputs
* Remove subquery targetlist items we don't need
@@ -4028,9 +4066,20 @@ remove_unused_subquery_outputs(Query *subquery, RelOptInfo *rel)
* If it contains a set-returning function, we can't remove it since
* that could change the number of rows returned by the subquery.
*/
- if (subquery->hasTargetSRFs &&
- expression_returns_set(texpr))
- continue;
+ if (subquery->hasTargetSRFs)
+ {
+ if (expression_returns_set(texpr))
+ continue;
+
+ /*
+ * Check if the target entry contains any WindowFunc references
+ * which have a WindowClause where the PARTITION BY or ORDER BY
+ * clause contain any SRFs
+ */
+ if (subquery->hasWindowFuncs &&
+ has_set_returning_window_clauses(subquery, (Node *) texpr))
+ continue;
+ }
/*
* If it contains volatile functions, we daren't remove it for fear