From cd08e4296f499b9c3db3b7926a625f63455a815e Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Mon, 1 Jun 2026 22:15:04 +0900 Subject: [PATCH 38/68] Demote dead runtime checks in the RPR executor to assertions Three checks in the row pattern recognition NFA executor can never fail, given how the planner builds the pattern: - The final arm of nfa_advance_var's loop/exit cascade tested canExit, but reaching it implies !canLoop, which with min <= max forces canExit true. - nfa_state_clone guarded the counts memcpy with counts != NULL && maxDepth > 0, but every caller passes a live state's counts and the stored maxDepth is always >= 1. - nfa_advance_alt bounded the branch walk with altIdx < numElements, but every jump/next link is -1 or a valid index, and the altIdx >= 0 test and the depth break already terminate the walk. Replace each with an assertion that documents the invariant and drop the runtime branch. Also document why the nullable fast-forward path in nfa_advance_end intentionally omits the isAbsorbable update: it runs only for EMPTY_LOOP groups, which are never inside an absorbable region. Per a report from a static analysis tool. --- src/backend/executor/execRPR.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 9e45920de9c..eac0c04c38d 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -279,8 +279,9 @@ nfa_state_clone(WindowAggState *winstate, int16 elemIdx, RPRPatternElement *elem = &pattern->elements[elemIdx]; state->elemIdx = elemIdx; - if (counts != NULL && maxDepth > 0) - memcpy(state->counts, counts, sizeof(int32) * maxDepth); + /* Every reachable caller passes a live state's counts; maxDepth >= 1. */ + Assert(counts != NULL && maxDepth > 0); + memcpy(state->counts, counts, sizeof(int32) * maxDepth); /* * Compute isAbsorbable immediately at transition time. isAbsorbable = @@ -981,11 +982,15 @@ nfa_advance_alt(WindowAggState *winstate, RPRNFAContext *ctx, RPRPatternElement *elements = pattern->elements; RPRElemIdx altIdx = elem->next; - while (altIdx >= 0 && altIdx < pattern->numElements) + while (altIdx >= 0) { - RPRPatternElement *altElem = &elements[altIdx]; + RPRPatternElement *altElem; RPRNFAState *newState; + /* Branch jump/next links are always -1 or a valid index */ + Assert(altIdx < pattern->numElements); + altElem = &elements[altIdx]; + /* * Stop if element is outside ALT scope (not a branch). The check * fires when the last branch is a quantified group whose BEGIN.jump @@ -1147,6 +1152,13 @@ nfa_advance_end(WindowAggState *winstate, RPRNFAContext *ctx, ffState->elemIdx = elem->next; nextElem = &elements[ffState->elemIdx]; + /* + * Unlike the must-exit path, no isAbsorbable update is needed: + * the fast-forward path runs only for EMPTY_LOOP (nullable) + * groups, which are never inside an absorbable region, so + * isAbsorbable is already false here. + */ + /* END->END: increment outer END's count */ if (RPRElemIsEnd(nextElem) && ffState->counts[nextElem->depth] < RPR_COUNT_MAX) @@ -1353,11 +1365,12 @@ nfa_advance_var(WindowAggState *winstate, RPRNFAContext *ctx, /* Loop only: keep state as-is */ nfa_add_state_unique(winstate, ctx, state); } - else if (canExit) + else { - /* Exit only: advance to next element */ + /* Exit only: advance to next element (canExit necessarily true) */ RPRPatternElement *nextElem; + Assert(canExit); /* Exit: clear the VAR's own count (count-clear policy) */ state->counts[depth] = 0; state->elemIdx = elem->next; -- 2.50.1 (Apple Git-155)