aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/nodeWindowAgg.c20
-rw-r--r--src/backend/optimizer/path/allpaths.c12
2 files changed, 32 insertions, 0 deletions
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index 4b104c4d98a..75f0a031348 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -2305,7 +2305,27 @@ ExecWindowAgg(PlanState *pstate)
continue;
}
else
+ {
winstate->status = WINDOWAGG_PASSTHROUGH;
+
+ /*
+ * If we're not the top-window, we'd better NULLify
+ * the aggregate results. In pass-through mode we no
+ * longer update these and this avoids the old stale
+ * results lingering. Some of these might be byref
+ * types so we can't have them pointing to free'd
+ * memory. The planner insisted that quals used in
+ * the runcondition are strict, so the top-level
+ * WindowAgg will filter these NULLs out in the filter
+ * clause.
+ */
+ numfuncs = winstate->numfuncs;
+ for (i = 0; i < numfuncs; i++)
+ {
+ econtext->ecxt_aggvalues[i] = (Datum) 0;
+ econtext->ecxt_aggnulls[i] = true;
+ }
+ }
}
else
{
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 5682fd276ed..511452bc1c7 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -2400,6 +2400,18 @@ check_and_push_window_quals(Query *subquery, RangeTblEntry *rte, Index rti,
return true;
/*
+ * Currently, we restrict this optimization to strict OpExprs. The reason
+ * for this is that during execution, once the runcondition becomes false,
+ * we stop evaluating WindowFuncs. To avoid leaving around stale window
+ * function result values, we set them to NULL. Having only strict
+ * OpExprs here ensures that we properly filter out the tuples with NULLs
+ * in the top-level WindowAgg.
+ */
+ set_opfuncid(opexpr);
+ if (!func_strict(opexpr->opfuncid))
+ return true;
+
+ /*
* Check for plain Vars that reference window functions in the subquery.
* If we find any, we'll ask find_window_run_conditions() if 'opexpr' can
* be used as part of the run condition.