From 252b1e9b361feb82a12931787bb6108b11063598 Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Tue, 7 Jul 2026 08:10:58 -0700 Subject: [PATCH v1] Fix duplicate detection for null-treatment window functions `ExecInitWindowAgg()` checks `perfunc[i].ignore_nulls` when deciding whether a window function call can reuse an existing `WindowStatePerFunc` entry. However, that field was never initialized when filling the `perfuncstate` data, so it remained zero from `palloc0_array()`. As a result, duplicate calls using `IGNORE NULLS` or explicit `RESPECT NULLS` failed to reuse the existing entry, because their `wfunc->ignore_nulls` value did not match the zeroed per-function state. Plain calls were unaffected because their null-treatment value is also zero. Copy `wfunc->ignore_nulls` into `perfuncstate->ignore_nulls` during initialization so duplicate null-treatment window function calls are deduplicated as intended. Oversight in 25a30bbd423. Author: Chao Li --- src/backend/executor/nodeWindowAgg.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index f1c524d00df..676fe024965 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -2749,11 +2749,23 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) } if (i <= wfuncno && wfunc->ignore_nulls == perfunc[i].ignore_nulls) { + /* TODO: remove this log before pushing */ + elog(INFO, "WindowAgg duplicate cache hit: existing wfuncno %d, ignore_nulls %d", + i, wfunc->ignore_nulls); + /* Found a match to an existing entry, so just mark it */ wfuncstate->wfuncno = i; continue; } + /* TODO: remove this log before pushing */ + if (i <= wfuncno) + elog(INFO, "WindowAgg duplicate cache miss: matched wfuncno %d, ignore_nulls %d, cached ignore_nulls %d", + i, wfunc->ignore_nulls, perfunc[i].ignore_nulls); + else + elog(INFO, "WindowAgg duplicate cache miss: no previous match, ignore_nulls %d", + wfunc->ignore_nulls); + /* Nope, so assign a new PerAgg record */ perfuncstate = &perfunc[++wfuncno]; @@ -2773,6 +2785,7 @@ ExecInitWindowAgg(WindowAgg *node, EState *estate, int eflags) perfuncstate->wfunc = wfunc; perfuncstate->numArguments = list_length(wfuncstate->args); perfuncstate->winCollation = wfunc->inputcollid; + perfuncstate->ignore_nulls = wfunc->ignore_nulls; get_typlenbyval(wfunc->wintype, &perfuncstate->resulttypeLen, -- 2.50.1 (Apple Git-155)