diff options
-rw-r--r-- | src/backend/executor/nodeWindowAgg.c | 35 | ||||
-rw-r--r-- | src/test/regress/expected/window.out | 10 | ||||
-rw-r--r-- | src/test/regress/sql/window.sql | 7 |
3 files changed, 34 insertions, 18 deletions
diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 418d6d9c426..3e7436f4918 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -2295,6 +2295,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 @@ -2308,24 +2325,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 f8914c0401c..d626591a05d 100644 --- a/src/test/regress/expected/window.out +++ b/src/test/regress/expected/window.out @@ -3663,6 +3663,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 2a5aa38d29a..edf17e50a47 100644 --- a/src/test/regress/sql/window.sql +++ b/src/test/regress/sql/window.sql @@ -1161,6 +1161,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 |