aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/nodeWindowAgg.c35
-rw-r--r--src/test/regress/expected/window.out10
-rw-r--r--src/test/regress/sql/window.sql7
3 files changed, 34 insertions, 18 deletions
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c
index e75e8576725..70a7025818f 100644
--- a/src/backend/executor/nodeWindowAgg.c
+++ b/src/backend/executor/nodeWindowAgg.c
@@ -2354,6 +2354,23 @@ ExecWindowAgg(PlanState *pstate)
if (winstate->use_pass_through)
{
/*
+ * When switching into a pass-through mode, we'd better
+ * NULLify the aggregate results as these are no longer
+ * updated and NULLifying them 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 always
+ * 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;
+ }
+
+ /*
* STRICT pass-through mode is required for the top window
* when there is a PARTITION BY clause. Otherwise we must
* ensure we store tuples that don't match the
@@ -2367,24 +2384,6 @@ ExecWindowAgg(PlanState *pstate)
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/test/regress/expected/window.out b/src/test/regress/expected/window.out
index 8b447aa01e5..23d1463df22 100644
--- a/src/test/regress/expected/window.out
+++ b/src/test/regress/expected/window.out
@@ -4136,6 +4136,16 @@ WHERE c = 1;
-> Seq Scan on empsalary
(3 rows)
+-- Try another case with a WindowFunc with a byref return type
+SELECT * FROM
+ (SELECT row_number() OVER (PARTITION BY salary) AS rn,
+ lead(depname) OVER (PARTITION BY salary) || ' Department' AS n_dep
+ FROM empsalary) emp
+WHERE rn < 1;
+ rn | n_dep
+----+-------
+(0 rows)
+
-- Some more complex cases with multiple window clauses
EXPLAIN (COSTS OFF)
SELECT * FROM
diff --git a/src/test/regress/sql/window.sql b/src/test/regress/sql/window.sql
index 6de5493b05b..02f105f070e 100644
--- a/src/test/regress/sql/window.sql
+++ b/src/test/regress/sql/window.sql
@@ -1345,6 +1345,13 @@ SELECT * FROM
FROM empsalary) emp
WHERE c = 1;
+-- Try another case with a WindowFunc with a byref return type
+SELECT * FROM
+ (SELECT row_number() OVER (PARTITION BY salary) AS rn,
+ lead(depname) OVER (PARTITION BY salary) || ' Department' AS n_dep
+ FROM empsalary) emp
+WHERE rn < 1;
+
-- Some more complex cases with multiple window clauses
EXPLAIN (COSTS OFF)
SELECT * FROM