summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorDavid Rowley2024-05-05 00:54:46 +0000
committerDavid Rowley2024-05-05 00:54:46 +0000
commit7d2c7f08d9c5ad02101c0fb47cd8e859dd89083b (patch)
treea84db7d521410918fab94680bff9bdce1ae7643d /src/include
parent01df14763431df1506cbae206945cd165c66d1d3 (diff)
Fix query pullup issue with WindowClause runCondition
94985c210 added code to detect when WindowFuncs were monotonic and allowed additional quals to be "pushed down" into the subquery to be used as WindowClause runConditions in order to short-circuit execution in nodeWindowAgg.c. The Node representation of runConditions wasn't well selected and because we do qual pushdown before planning the subquery, the planning of the subquery could perform subquery pull-up of nested subqueries. For WindowFuncs with args, the arguments could be changed after pushing the qual down to the subquery. This was made more difficult by the fact that the code duplicated the WindowFunc inside an OpExpr to include in the WindowClauses runCondition field. This could result in duplication of subqueries and a pull-up of such a subquery could result in another initplan parameter being issued for the 2nd version of the subplan. This could result in errors such as: ERROR: WindowFunc not found in subplan target lists To fix this, we change the node representation of these run conditions and instead of storing an OpExpr containing the WindowFunc in a list inside WindowClause, we now store a new node type named WindowFuncRunCondition within a new field in the WindowFunc. These get transformed into OpExprs later in planning once subquery pull-up has been performed. This problem did exist in v15 and v16, but that was fixed by 9d36b883b and e5d20bbd. Cat version bump due to new node type and modifying WindowFunc struct. Bug: #18305 Reported-by: Zuming Jiang Discussion: https://postgr.es/m/18305-33c49b4c830b37b3%40postgresql.org
Diffstat (limited to 'src/include')
-rw-r--r--src/include/catalog/catversion.h2
-rw-r--r--src/include/nodes/parsenodes.h2
-rw-r--r--src/include/nodes/pathnodes.h1
-rw-r--r--src/include/nodes/primnodes.h30
-rw-r--r--src/include/optimizer/pathnode.h1
5 files changed, 33 insertions, 3 deletions
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index 8618ea59076..5a1dd1cb8f1 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -57,6 +57,6 @@
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202404291
+#define CATALOG_VERSION_NO 202405051
#endif
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index af80a5d38e0..3ca06fc3af6 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1549,8 +1549,6 @@ typedef struct WindowClause
int frameOptions; /* frame_clause options, see WindowDef */
Node *startOffset; /* expression for starting bound, if any */
Node *endOffset; /* expression for ending bound, if any */
- /* qual to help short-circuit execution */
- List *runCondition pg_node_attr(query_jumble_ignore);
/* in_range function for startOffset */
Oid startInRangeFunc pg_node_attr(query_jumble_ignore);
/* in_range function for endOffset */
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 91a6ce90d83..c7a415b23d8 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -2308,6 +2308,7 @@ typedef struct WindowAggPath
Path *subpath; /* path representing input source */
WindowClause *winclause; /* WindowClause we'll be using */
List *qual; /* lower-level WindowAgg runconditions */
+ List *runCondition; /* OpExpr List to short-circuit execution */
bool topwindow; /* false for all apart from the WindowAgg
* that's closest to the root of the plan */
} WindowAggPath;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 43f5766d732..4830efc5738 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -575,6 +575,8 @@ typedef struct WindowFunc
List *args;
/* FILTER expression, if any */
Expr *aggfilter;
+ /* List of WindowFuncRunConditions to help short-circuit execution */
+ List *runCondition pg_node_attr(query_jumble_ignore);
/* index of associated WindowClause */
Index winref;
/* true if argument list was really '*' */
@@ -586,6 +588,34 @@ typedef struct WindowFunc
} WindowFunc;
/*
+ * WindowFuncRunCondition
+ *
+ * Represents intermediate OpExprs which will be used by WindowAgg to
+ * short-circuit execution.
+ */
+typedef struct WindowFuncRunCondition
+{
+ Expr xpr;
+
+ /* PG_OPERATOR OID of the operator */
+ Oid opno;
+ /* OID of collation that operator should use */
+ Oid inputcollid pg_node_attr(query_jumble_ignore);
+
+ /*
+ * true of WindowFunc belongs on the left of the resulting OpExpr or false
+ * if the WindowFunc is on the right.
+ */
+ bool wfunc_left;
+
+ /*
+ * The Expr being compared to the WindowFunc to use in the OpExpr in the
+ * WindowAgg's runCondition
+ */
+ Expr *arg;
+} WindowFuncRunCondition;
+
+/*
* MergeSupportFunc
*
* A MergeSupportFunc is a merge support function expression that can only
diff --git a/src/include/optimizer/pathnode.h b/src/include/optimizer/pathnode.h
index c5c4756b0fc..112e7c23d4e 100644
--- a/src/include/optimizer/pathnode.h
+++ b/src/include/optimizer/pathnode.h
@@ -250,6 +250,7 @@ extern WindowAggPath *create_windowagg_path(PlannerInfo *root,
Path *subpath,
PathTarget *target,
List *windowFuncs,
+ List *runCondition,
WindowClause *winclause,
List *qual,
bool topwindow);