From afe2e7b503d135f72f006072fb7e1aab8ce8fce8 Mon Sep 17 00:00:00 2001 From: jian he Date: Thu, 28 May 2026 21:15:43 +0800 Subject: [PATCH v47 1/1] misc refactor for v47 ExecRPRProcessRow --- src/backend/executor/README.rpr | 2 +- src/backend/executor/execRPR.c | 7 +++---- src/backend/executor/nodeWindowAgg.c | 11 ++++++----- src/include/executor/execRPR.h | 3 +-- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/backend/executor/README.rpr b/src/backend/executor/README.rpr index 52bcd77390c..2bf7703c777 100644 --- a/src/backend/executor/README.rpr +++ b/src/backend/executor/README.rpr @@ -1048,7 +1048,7 @@ X-3. INITIAL vs SEEK X-4. Bounded Frame Handling When the frame is bounded (e.g., ROWS BETWEEN CURRENT ROW AND 5 - FOLLOWING), ExecRPRProcessRow receives hasLimitedFrame=true and + FOLLOWING), ExecRPRProcessRow receives (frameOffset > 0) and frameOffset indicating the upper bound. Before the match phase, any context whose match has exceeded the frame boundary (currentPos >= matchStartRow + frameOffset + 1) is finalized early diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 242ae9c6dcf..f381a84961d 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -1620,8 +1620,7 @@ nfa_reevaluate_dependent_vars(WindowAggState *winstate, RPRNFAContext *ctx, * 3. Advance all contexts (divergence) - create new states for next row */ void -ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, - bool hasLimitedFrame, int64 frameOffset) +ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, int64 frameOffset) { RPRNFAContext *ctx; bool *varMatched = winstate->nfaVarMatched; @@ -1640,7 +1639,7 @@ ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, continue; /* Check frame boundary - finalize if exceeded */ - if (hasLimitedFrame) + if (frameOffset > 0) { int64 ctxFrameEnd; @@ -1696,7 +1695,7 @@ ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, * states are at VAR positions after advance). So any surviving * context here must be within its frame boundary. */ - Assert(!hasLimitedFrame || + Assert(frameOffset == 0 || ctx->matchStartRow > PG_INT64_MAX - frameOffset - 1 || currentPos < ctx->matchStartRow + frameOffset + 1); diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index f1cd9b66098..d4d57ffd795 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -4383,7 +4383,6 @@ update_reduced_frame(WindowObject winobj, int64 pos) int64 currentPos; int64 startPos; int frameOptions = winstate->frameOptions; - bool hasLimitedFrame; int64 frameOffset = 0; int64 matchLen; @@ -4391,11 +4390,13 @@ update_reduced_frame(WindowObject winobj, int64 pos) * Check if we have a limited frame (ROWS ... N FOLLOWING). Each context * needs its own frame end based on matchStartRow + offset. */ - hasLimitedFrame = (frameOptions & FRAMEOPTION_ROWS) && - !(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING); - if (hasLimitedFrame && winstate->endOffsetValue != 0) + Assert(frameOptions & FRAMEOPTION_ROWS); + + if (!(frameOptions & FRAMEOPTION_END_UNBOUNDED_FOLLOWING)) frameOffset = DatumGetInt64(winstate->endOffsetValue); + Assert(frameOffset >= 0); + /* * Case 1: pos is before any existing context's start position. This means * the position was already processed and determined unmatched. Head is @@ -4488,7 +4489,7 @@ update_reduced_frame(WindowObject winobj, int64 pos) * 2. Absorb redundant * 3. Advance all (divergence) */ - ExecRPRProcessRow(winstate, currentPos, hasLimitedFrame, frameOffset); + ExecRPRProcessRow(winstate, currentPos, frameOffset); /* * Create a new context for the next potential start position. This diff --git a/src/include/executor/execRPR.h b/src/include/executor/execRPR.h index 7b2b0febb76..a9700f56209 100644 --- a/src/include/executor/execRPR.h +++ b/src/include/executor/execRPR.h @@ -25,8 +25,7 @@ extern RPRNFAContext *ExecRPRGetHeadContext(WindowAggState *winstate, extern void ExecRPRFreeContext(WindowAggState *winstate, RPRNFAContext *ctx); /* NFA processing */ -extern void ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, - bool hasLimitedFrame, int64 frameOffset); +extern void ExecRPRProcessRow(WindowAggState *winstate, int64 currentPos, int64 frameOffset); extern void ExecRPRCleanupDeadContexts(WindowAggState *winstate, RPRNFAContext *excludeCtx); extern void ExecRPRFinalizeAllContexts(WindowAggState *winstate, int64 lastPos); -- 2.34.1