From 178fe9979b1a5c18e06af67a696e12f0ee9da107 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Fri, 5 Jun 2026 12:32:38 +0900 Subject: [PATCH 46/68] Tidy up forward declarations and helper placement for row pattern recognition Bring the row pattern recognition code in line with the surrounding conventions for static helpers: - each static helper has a forward declaration; - static helpers are defined above the "API exposed" banner, public entry points below; - the forward-declaration block uses a single banner, not per-group labels; - forward declarations follow definition order. Pure code movement and comments, no behavior change. Per review comments from Tatsuo Ishii and Jian He. --- src/backend/executor/execRPR.c | 110 +++---- src/backend/executor/nodeWindowAgg.c | 454 +++++++++++++-------------- src/backend/optimizer/plan/rpr.c | 12 +- src/backend/parser/parse_rpr.c | 2 +- 4 files changed, 289 insertions(+), 289 deletions(-) diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 580b25f398d..56399c0c7fd 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -83,8 +83,6 @@ static bool nfa_eval_var_match(WindowAggState *winstate, RPRPatternElement *elem, bool *varMatched); static void nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched); -static void nfa_advance_state(WindowAggState *winstate, RPRNFAContext *ctx, - RPRNFAState *state, int64 currentPos); static void nfa_route_to_elem(WindowAggState *winstate, RPRNFAContext *ctx, RPRNFAState *state, RPRPatternElement *nextElem, int64 currentPos); @@ -100,9 +98,15 @@ static void nfa_advance_end(WindowAggState *winstate, RPRNFAContext *ctx, static void nfa_advance_var(WindowAggState *winstate, RPRNFAContext *ctx, RPRNFAState *state, RPRPatternElement *elem, int64 currentPos); +static void nfa_advance_state(WindowAggState *winstate, RPRNFAContext *ctx, + RPRNFAState *state, int64 currentPos); static void nfa_advance(WindowAggState *winstate, RPRNFAContext *ctx, int64 currentPos); +static void nfa_reevaluate_dependent_vars(WindowAggState *winstate, + RPRNFAContext *ctx, + int64 currentPos); + /* * NFA-based pattern matching implementation * @@ -1552,6 +1556,57 @@ nfa_advance(WindowAggState *winstate, RPRNFAContext *ctx, int64 currentPos) } } +/* + * nfa_reevaluate_dependent_vars + * Re-evaluate match_start-dependent DEFINE variables for a specific + * context whose matchStartRow differs from the shared evaluation's + * nav_match_start. + * + * Only variables in defineMatchStartDependent are re-evaluated. The + * current row's slot (ecxt_outertuple) must already be set up by + * nfa_evaluate_row(). + */ +static void +nfa_reevaluate_dependent_vars(WindowAggState *winstate, RPRNFAContext *ctx, + int64 currentPos) +{ + ExprContext *econtext = winstate->ss.ps.ps_ExprContext; + int64 saved_match_start = winstate->nav_match_start; + int64 saved_pos = winstate->currentpos; + int varIdx = 0; + ListCell *lc; + + /* Temporarily set nav_match_start and currentpos for FIRST/LAST */ + winstate->nav_match_start = ctx->matchStartRow; + winstate->currentpos = currentPos; + + /* Invalidate nav_slot cache since match_start changed */ + winstate->nav_slot_pos = -1; + + foreach(lc, winstate->defineClauseList) + { + if (bms_is_member(varIdx, winstate->defineMatchStartDependent)) + { + ExprState *exprState = (ExprState *) lfirst(lc); + Datum result; + bool isnull; + + /* Per-tuple context; scratch freed by the per-row reset */ + result = ExecEvalExprSwitchContext(exprState, econtext, &isnull); + winstate->nfaVarMatched[varIdx] = (!isnull && DatumGetBool(result)); + } + + varIdx++; + if (varIdx >= list_length(winstate->defineVariableList)) + break; + } + + /* Restore original match_start, currentpos, and invalidate cache */ + winstate->nav_match_start = saved_match_start; + winstate->currentpos = saved_pos; + winstate->nav_slot_pos = -1; +} + /*********************************************************************** * API exposed to nodeWindowAgg.c @@ -1696,57 +1751,6 @@ ExecRPRRecordContextFailure(WindowAggState *winstate, int64 failedLen) } } -/* - * nfa_reevaluate_dependent_vars - * Re-evaluate match_start-dependent DEFINE variables for a specific - * context whose matchStartRow differs from the shared evaluation's - * nav_match_start. - * - * Only variables in defineMatchStartDependent are re-evaluated. The - * current row's slot (ecxt_outertuple) must already be set up by - * nfa_evaluate_row(). - */ -static void -nfa_reevaluate_dependent_vars(WindowAggState *winstate, RPRNFAContext *ctx, - int64 currentPos) -{ - ExprContext *econtext = winstate->ss.ps.ps_ExprContext; - int64 saved_match_start = winstate->nav_match_start; - int64 saved_pos = winstate->currentpos; - int varIdx = 0; - ListCell *lc; - - /* Temporarily set nav_match_start and currentpos for FIRST/LAST */ - winstate->nav_match_start = ctx->matchStartRow; - winstate->currentpos = currentPos; - - /* Invalidate nav_slot cache since match_start changed */ - winstate->nav_slot_pos = -1; - - foreach(lc, winstate->defineClauseList) - { - if (bms_is_member(varIdx, winstate->defineMatchStartDependent)) - { - ExprState *exprState = (ExprState *) lfirst(lc); - Datum result; - bool isnull; - - /* Per-tuple context; scratch freed by the per-row reset */ - result = ExecEvalExprSwitchContext(exprState, econtext, &isnull); - winstate->nfaVarMatched[varIdx] = (!isnull && DatumGetBool(result)); - } - - varIdx++; - if (varIdx >= list_length(winstate->defineVariableList)) - break; - } - - /* Restore original match_start, currentpos, and invalidate cache */ - winstate->nav_match_start = saved_match_start; - winstate->currentpos = saved_pos; - winstate->nav_slot_pos = -1; -} - /* * ExecRPRProcessRow * diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index 408bbc120b7..86b39bf7f61 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -4627,6 +4627,233 @@ nfa_evaluate_row(WindowObject winobj, int64 pos, bool *varMatched) return true; /* Row exists */ } +/* + * WinGetSlotInFrame + * slot: TupleTableSlot to store the result + * relpos: signed rowcount offset from the seek position + * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL + * set_mark: If the row is found/in frame and set_mark is true, the mark is + * moved to the row as a side-effect. + * isnull: output argument, receives isnull status of result + * isout: output argument, set to indicate whether target row position + * is out of frame (can pass NULL if caller doesn't care about this) + * + * Returns 0 if we successfully got the slot, or nonzero if out of frame. + * (isout is also set in the latter case.) + */ +static int +WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, + int relpos, int seektype, bool set_mark, + bool *isnull, bool *isout) +{ + WindowAggState *winstate; + int64 abs_pos; + int64 mark_pos; + int64 num_reduced_frame; + + Assert(WindowObjectIsValid(winobj)); + winstate = winobj->winstate; + + switch (seektype) + { + case WINDOW_SEEK_CURRENT: + elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); + abs_pos = mark_pos = 0; /* keep compiler quiet */ + break; + case WINDOW_SEEK_HEAD: + /* rejecting relpos < 0 is easy and simplifies code below */ + if (relpos < 0) + goto out_of_frame; + update_frameheadpos(winstate); + abs_pos = winstate->frameheadpos + relpos; + mark_pos = abs_pos; + + /* + * Account for exclusion option if one is active, but advance only + * abs_pos not mark_pos. This prevents changes of the current + * row's peer group from resulting in trying to fetch a row before + * some previous mark position. + * + * Note that in some corner cases such as current row being + * outside frame, these calculations are theoretically too simple, + * but it doesn't matter because we'll end up deciding the row is + * out of frame. We do not attempt to avoid fetching rows past + * end of frame; that would happen in some cases anyway. + */ + switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) + { + case 0: + /* no adjustment needed */ + break; + case FRAMEOPTION_EXCLUDE_CURRENT_ROW: + if (abs_pos >= winstate->currentpos && + winstate->currentpos >= winstate->frameheadpos) + abs_pos++; + break; + case FRAMEOPTION_EXCLUDE_GROUP: + update_grouptailpos(winstate); + if (abs_pos >= winstate->groupheadpos && + winstate->grouptailpos > winstate->frameheadpos) + { + int64 overlapstart = Max(winstate->groupheadpos, + winstate->frameheadpos); + + abs_pos += winstate->grouptailpos - overlapstart; + } + break; + case FRAMEOPTION_EXCLUDE_TIES: + update_grouptailpos(winstate); + if (abs_pos >= winstate->groupheadpos && + winstate->grouptailpos > winstate->frameheadpos) + { + int64 overlapstart = Max(winstate->groupheadpos, + winstate->frameheadpos); + + if (abs_pos == overlapstart) + abs_pos = winstate->currentpos; + else + abs_pos += winstate->grouptailpos - overlapstart - 1; + } + break; + default: + elog(ERROR, "unrecognized frame option state: 0x%x", + winstate->frameOptions); + break; + } + num_reduced_frame = row_is_in_reduced_frame(winobj, + winstate->frameheadpos); + if (num_reduced_frame < 0) + goto out_of_frame; + else if (num_reduced_frame > 0) + if (relpos >= num_reduced_frame) + goto out_of_frame; + break; + case WINDOW_SEEK_TAIL: + /* rejecting relpos > 0 is easy and simplifies code below */ + if (relpos > 0) + goto out_of_frame; + + /* + * RPR cares about frame head pos. Need to call + * update_frameheadpos + */ + update_frameheadpos(winstate); + + update_frametailpos(winstate); + abs_pos = winstate->frametailpos - 1 + relpos; + + /* + * Account for exclusion option if one is active. If there is no + * exclusion, we can safely set the mark at the accessed row. But + * if there is, we can only mark the frame start, because we can't + * be sure how far back in the frame the exclusion might cause us + * to fetch in future. Furthermore, we have to actually check + * against frameheadpos here, since it's unsafe to try to fetch a + * row before frame start if the mark might be there already. + */ + switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) + { + case 0: + /* no adjustment needed */ + mark_pos = abs_pos; + break; + case FRAMEOPTION_EXCLUDE_CURRENT_ROW: + if (abs_pos <= winstate->currentpos && + winstate->currentpos < winstate->frametailpos) + abs_pos--; + update_frameheadpos(winstate); + if (abs_pos < winstate->frameheadpos) + goto out_of_frame; + mark_pos = winstate->frameheadpos; + break; + case FRAMEOPTION_EXCLUDE_GROUP: + update_grouptailpos(winstate); + if (abs_pos < winstate->grouptailpos && + winstate->groupheadpos < winstate->frametailpos) + { + int64 overlapend = Min(winstate->grouptailpos, + winstate->frametailpos); + + abs_pos -= overlapend - winstate->groupheadpos; + } + update_frameheadpos(winstate); + if (abs_pos < winstate->frameheadpos) + goto out_of_frame; + mark_pos = winstate->frameheadpos; + break; + case FRAMEOPTION_EXCLUDE_TIES: + update_grouptailpos(winstate); + if (abs_pos < winstate->grouptailpos && + winstate->groupheadpos < winstate->frametailpos) + { + int64 overlapend = Min(winstate->grouptailpos, + winstate->frametailpos); + + if (abs_pos == overlapend - 1) + abs_pos = winstate->currentpos; + else + abs_pos -= overlapend - 1 - winstate->groupheadpos; + } + update_frameheadpos(winstate); + if (abs_pos < winstate->frameheadpos) + goto out_of_frame; + mark_pos = winstate->frameheadpos; + break; + default: + elog(ERROR, "unrecognized frame option state: 0x%x", + winstate->frameOptions); + mark_pos = 0; /* keep compiler quiet */ + break; + } + + num_reduced_frame = row_is_in_reduced_frame(winobj, + winstate->frameheadpos); + if (num_reduced_frame < 0) + goto out_of_frame; + else if (num_reduced_frame > 0) + { + if (-relpos >= num_reduced_frame) + goto out_of_frame; + abs_pos = winstate->frameheadpos + relpos + + num_reduced_frame - 1; + } + break; + default: + elog(ERROR, "unrecognized window seek type: %d", seektype); + abs_pos = mark_pos = 0; /* keep compiler quiet */ + break; + } + + if (!window_gettupleslot(winobj, abs_pos, slot)) + goto out_of_frame; + + /* The code above does not detect all out-of-frame cases, so check */ + if (row_is_in_frame(winobj, abs_pos, slot, false) <= 0) + goto out_of_frame; + + 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: + if (isout) + *isout = true; + *isnull = true; + return -1; +} + /*********************************************************************** * API exposed to window functions @@ -5019,233 +5246,6 @@ WinGetFuncArgInFrame(WindowObject winobj, int argno, return (Datum) 0; } -/* - * WinGetSlotInFrame - * slot: TupleTableSlot to store the result - * relpos: signed rowcount offset from the seek position - * seektype: WINDOW_SEEK_HEAD or WINDOW_SEEK_TAIL - * set_mark: If the row is found/in frame and set_mark is true, the mark is - * moved to the row as a side-effect. - * isnull: output argument, receives isnull status of result - * isout: output argument, set to indicate whether target row position - * is out of frame (can pass NULL if caller doesn't care about this) - * - * Returns 0 if we successfully got the slot, or nonzero if out of frame. - * (isout is also set in the latter case.) - */ -static int -WinGetSlotInFrame(WindowObject winobj, TupleTableSlot *slot, - int relpos, int seektype, bool set_mark, - bool *isnull, bool *isout) -{ - WindowAggState *winstate; - int64 abs_pos; - int64 mark_pos; - int64 num_reduced_frame; - - Assert(WindowObjectIsValid(winobj)); - winstate = winobj->winstate; - - switch (seektype) - { - case WINDOW_SEEK_CURRENT: - elog(ERROR, "WINDOW_SEEK_CURRENT is not supported for WinGetFuncArgInFrame"); - abs_pos = mark_pos = 0; /* keep compiler quiet */ - break; - case WINDOW_SEEK_HEAD: - /* rejecting relpos < 0 is easy and simplifies code below */ - if (relpos < 0) - goto out_of_frame; - update_frameheadpos(winstate); - abs_pos = winstate->frameheadpos + relpos; - mark_pos = abs_pos; - - /* - * Account for exclusion option if one is active, but advance only - * abs_pos not mark_pos. This prevents changes of the current - * row's peer group from resulting in trying to fetch a row before - * some previous mark position. - * - * Note that in some corner cases such as current row being - * outside frame, these calculations are theoretically too simple, - * but it doesn't matter because we'll end up deciding the row is - * out of frame. We do not attempt to avoid fetching rows past - * end of frame; that would happen in some cases anyway. - */ - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) - { - case 0: - /* no adjustment needed */ - break; - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: - if (abs_pos >= winstate->currentpos && - winstate->currentpos >= winstate->frameheadpos) - abs_pos++; - break; - case FRAMEOPTION_EXCLUDE_GROUP: - update_grouptailpos(winstate); - if (abs_pos >= winstate->groupheadpos && - winstate->grouptailpos > winstate->frameheadpos) - { - int64 overlapstart = Max(winstate->groupheadpos, - winstate->frameheadpos); - - abs_pos += winstate->grouptailpos - overlapstart; - } - break; - case FRAMEOPTION_EXCLUDE_TIES: - update_grouptailpos(winstate); - if (abs_pos >= winstate->groupheadpos && - winstate->grouptailpos > winstate->frameheadpos) - { - int64 overlapstart = Max(winstate->groupheadpos, - winstate->frameheadpos); - - if (abs_pos == overlapstart) - abs_pos = winstate->currentpos; - else - abs_pos += winstate->grouptailpos - overlapstart - 1; - } - break; - default: - elog(ERROR, "unrecognized frame option state: 0x%x", - winstate->frameOptions); - break; - } - num_reduced_frame = row_is_in_reduced_frame(winobj, - winstate->frameheadpos); - if (num_reduced_frame < 0) - goto out_of_frame; - else if (num_reduced_frame > 0) - if (relpos >= num_reduced_frame) - goto out_of_frame; - break; - case WINDOW_SEEK_TAIL: - /* rejecting relpos > 0 is easy and simplifies code below */ - if (relpos > 0) - goto out_of_frame; - - /* - * RPR cares about frame head pos. Need to call - * update_frameheadpos - */ - update_frameheadpos(winstate); - - update_frametailpos(winstate); - abs_pos = winstate->frametailpos - 1 + relpos; - - /* - * Account for exclusion option if one is active. If there is no - * exclusion, we can safely set the mark at the accessed row. But - * if there is, we can only mark the frame start, because we can't - * be sure how far back in the frame the exclusion might cause us - * to fetch in future. Furthermore, we have to actually check - * against frameheadpos here, since it's unsafe to try to fetch a - * row before frame start if the mark might be there already. - */ - switch (winstate->frameOptions & FRAMEOPTION_EXCLUSION) - { - case 0: - /* no adjustment needed */ - mark_pos = abs_pos; - break; - case FRAMEOPTION_EXCLUDE_CURRENT_ROW: - if (abs_pos <= winstate->currentpos && - winstate->currentpos < winstate->frametailpos) - abs_pos--; - update_frameheadpos(winstate); - if (abs_pos < winstate->frameheadpos) - goto out_of_frame; - mark_pos = winstate->frameheadpos; - break; - case FRAMEOPTION_EXCLUDE_GROUP: - update_grouptailpos(winstate); - if (abs_pos < winstate->grouptailpos && - winstate->groupheadpos < winstate->frametailpos) - { - int64 overlapend = Min(winstate->grouptailpos, - winstate->frametailpos); - - abs_pos -= overlapend - winstate->groupheadpos; - } - update_frameheadpos(winstate); - if (abs_pos < winstate->frameheadpos) - goto out_of_frame; - mark_pos = winstate->frameheadpos; - break; - case FRAMEOPTION_EXCLUDE_TIES: - update_grouptailpos(winstate); - if (abs_pos < winstate->grouptailpos && - winstate->groupheadpos < winstate->frametailpos) - { - int64 overlapend = Min(winstate->grouptailpos, - winstate->frametailpos); - - if (abs_pos == overlapend - 1) - abs_pos = winstate->currentpos; - else - abs_pos -= overlapend - 1 - winstate->groupheadpos; - } - update_frameheadpos(winstate); - if (abs_pos < winstate->frameheadpos) - goto out_of_frame; - mark_pos = winstate->frameheadpos; - break; - default: - elog(ERROR, "unrecognized frame option state: 0x%x", - winstate->frameOptions); - mark_pos = 0; /* keep compiler quiet */ - break; - } - - num_reduced_frame = row_is_in_reduced_frame(winobj, - winstate->frameheadpos); - if (num_reduced_frame < 0) - goto out_of_frame; - else if (num_reduced_frame > 0) - { - if (-relpos >= num_reduced_frame) - goto out_of_frame; - abs_pos = winstate->frameheadpos + relpos + - num_reduced_frame - 1; - } - break; - default: - elog(ERROR, "unrecognized window seek type: %d", seektype); - abs_pos = mark_pos = 0; /* keep compiler quiet */ - break; - } - - if (!window_gettupleslot(winobj, abs_pos, slot)) - goto out_of_frame; - - /* The code above does not detect all out-of-frame cases, so check */ - if (row_is_in_frame(winobj, abs_pos, slot, false) <= 0) - goto out_of_frame; - - 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: - if (isout) - *isout = true; - *isnull = true; - return -1; -} - /* * WinGetFuncArgCurrent * Evaluate a window function's argument expression on the current row. diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 3205559c03a..43114088c3f 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -44,14 +44,12 @@ #include "nodes/nodeFuncs.h" #include "optimizer/rpr.h" -/* Forward declarations - pattern comparison */ +/* Forward declarations */ static bool rprPatternEqual(RPRPatternNode *a, RPRPatternNode *b); static bool rprPatternChildrenEqual(List *a, List *b); -/* Forward declarations - pattern optimization (shared) */ static RPRPatternNode *tryUnwrapSingleChild(RPRPatternNode *pattern); -/* Forward declarations - SEQ optimization */ static List *flattenSeqChildren(List *children); static List *mergeConsecutiveVars(List *children); static List *mergeConsecutiveGroups(List *children); @@ -59,20 +57,16 @@ static List *mergeConsecutiveAlts(List *children); static List *mergeGroupPrefixSuffix(List *children); static RPRPatternNode *optimizeSeqPattern(RPRPatternNode *pattern); -/* Forward declarations - ALT optimization */ static List *flattenAltChildren(List *children); static List *removeDuplicateAlternatives(List *children); static RPRPatternNode *optimizeAltPattern(RPRPatternNode *pattern); -/* Forward declarations - GROUP optimization */ static RPRPatternNode *tryMultiplyQuantifiers(RPRPatternNode *pattern); static RPRPatternNode *tryUnwrapGroup(RPRPatternNode *pattern); static RPRPatternNode *optimizeGroupPattern(RPRPatternNode *pattern); -/* Forward declarations - optimization dispatcher */ static RPRPatternNode *optimizeRPRPattern(RPRPatternNode *pattern); -/* Forward declarations - pattern compilation */ static int collectDefineVariables(List *defineVariableList, char **varNames); static void scanRPRPatternRecursive(RPRPatternNode *node, char **varNames, int *numVars, int *numElements, @@ -92,7 +86,6 @@ static bool fillRPRPattern(RPRPatternNode *node, RPRPattern *pat, int *idx, RPRDepth depth); static void finalizeRPRPattern(RPRPattern *result); -/* Forward declarations - context absorption */ static bool isFixedLengthChildren(RPRPattern *pattern, RPRElemIdx idx, RPRDepth scopeDepth); static bool isUnboundedStart(RPRPattern *pattern, RPRElemIdx idx); @@ -101,6 +94,9 @@ static void computeAbsorbabilityRecursive(RPRPattern *pattern, bool *hasAbsorbable); static void computeAbsorbability(RPRPattern *pattern); +static void collectPatternVariablesRecursive(RPRPatternNode *node, + List **varNames); + /* * rprPatternEqual * Compare two RPRPatternNode trees for equality. diff --git a/src/backend/parser/parse_rpr.c b/src/backend/parser/parse_rpr.c index 3872035110a..c9469b56b7b 100644 --- a/src/backend/parser/parse_rpr.c +++ b/src/backend/parser/parse_rpr.c @@ -61,8 +61,8 @@ static void validateRPRPatternVarCount(ParseState *pstate, RPRPatternNode *node, List *rpDefs, List **varNames); static List *transformDefineClause(ParseState *pstate, WindowClause *wc, WindowDef *windef, List **targetlist); -static bool define_walker(Node *node, void *context); static bool nav_volatile_func_checker(Oid funcid, void *context); +static bool define_walker(Node *node, void *context); /* * transformRPR -- 2.50.1 (Apple Git-155)