From ddf11ac02969b003d1f9b4296d2806dd64c88469 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Fri, 20 Mar 2026 13:39:20 +0900 Subject: [PATCH] Fix window_last_value set_mark to not advance mark during RPR window_last_value passes set_mark=true to WinGetFuncArgInFrame, which is correct for normal use: advancing the mark allows the tuplestore to discard rows no longer needed, reducing memory usage. However, when RPR is active, the reduced frame changes row by row. Advancing the mark would prevent revisiting earlier rows that still fall within a future row's reduced frame, producing incorrect results. Rather than requiring each caller to know about RPR, add an override in WinGetFuncArgInFrame: if RPR is defined, force set_mark=false regardless of what the caller passed. This keeps the fix localized and transparent to existing callers. --- src/backend/executor/nodeWindowAgg.c | 7 +++++++ src/backend/utils/adt/windowfuncs.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 0a9ba5bd4e7..d3ce9897a4f 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -4700,6 +4700,13 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, econtext = winstate->ss.ps.ps_ExprContext; slot = winstate->temp_slot_1; + /* + * When RPR is active, the reduced frame changes row by row, so we must + * not advance the mark — doing so would prevent revisiting earlier rows. + */ + if (rpr_is_defined(winstate)) + set_mark = false; + if (winobj->ignore_nulls == IGNORE_NULLS) return ignorenulls_getfuncarginframe(winobj, argno, relpos, seektype, set_mark, isnull, isout); diff --git a/src/backend/utils/adt/windowfuncs.c b/src/backend/utils/adt/windowfuncs.c index efb60c99052..74ef109f72e 100644 --- a/src/backend/utils/adt/windowfuncs.c +++ b/src/backend/utils/adt/windowfuncs.c @@ -682,7 +682,7 @@ window_last_value(PG_FUNCTION_ARGS) WinCheckAndInitializeNullTreatment(winobj, true, fcinfo); result = WinGetFuncArgInFrame(winobj, 0, - 0, WINDOW_SEEK_TAIL, false, + 0, WINDOW_SEEK_TAIL, true, &isnull, NULL); if (isnull) PG_RETURN_NULL(); -- 2.50.1 (Apple Git-155)