From 876c0b8fb52c5bde2e1a0c3e9dd9d1ac50396496 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Wed, 25 Mar 2026 00:37:50 +0900 Subject: [PATCH 5/8] Fix mark handling for last_value() under RPR Enable mark advancement in window_last_value() for better tuplestore memory usage in non-RPR cases, while adding a guard in WinGetFuncArgInFrame to suppress it for RPR SEEK_TAIL to prevent position invalidation from reduced frame shifts. --- src/backend/executor/nodeWindowAgg.c | 10 ++++++++++ src/backend/utils/adt/windowfuncs.c | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 185d7a0d5ae..aed7cbef99a 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -4932,7 +4932,17 @@ WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, if (isout) *isout = false; if (set_mark) + { + /* + * If RPR is enabled and seek type is WINDOW_SEEK_TAIL, we set the + * mark position unconditionally to frameheadpos. In this case the + * frame always starts at CURRENT_ROW and never goes back, thus + * setting the mark at the position is safe. + */ + if (winstate->rpPattern != NULL && seektype == WINDOW_SEEK_TAIL) + mark_pos = winstate->frameheadpos; WinSetMarkPosition(winobj, mark_pos); + } return 0; out_of_frame: 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)