From 0bc60ef4dc9cba045f6ee82d8cfcb48e2f5cf712 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Fri, 19 Jun 2026 13:04:00 +0900 Subject: [PATCH 11/13] Rename absorption "judgment point" to "comparison point" in comments The absorption analysis comments described the ABSORBABLE element flag as a "judgment point". Use "comparison point" instead, which says more directly what happens there: where consecutive iterations are compared. This touches comments and the executor README only, across the planner, executor, and EXPLAIN deparse, plus the rpr_base test comments; the "equivalence judgment" wording and all identifiers are unchanged. No change to behavior or to query output. --- src/backend/commands/explain.c | 2 +- src/backend/executor/README.rpr | 4 ++-- src/backend/executor/execRPR.c | 29 +++++++++++++------------- src/backend/optimizer/plan/rpr.c | 14 ++++++------- src/include/optimizer/rpr.h | 2 +- src/test/regress/expected/rpr_base.out | 6 +++--- src/test/regress/sql/rpr_base.sql | 6 +++--- 7 files changed, 32 insertions(+), 31 deletions(-) diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c index 423cf352125..b3fc324718d 100644 --- a/src/backend/commands/explain.c +++ b/src/backend/commands/explain.c @@ -2937,7 +2937,7 @@ append_rpr_quantifier(StringInfo buf, RPRPatternElement *elem) appendStringInfoChar(buf, '?'); } - /* Append absorption markers: " for judgment point, ' for branch only */ + /* Append absorption markers: " for comparison point, ' for branch only */ if (RPRElemIsAbsorbable(elem)) { Assert(elem->max == RPR_QUANTITY_INF); diff --git a/src/backend/executor/README.rpr b/src/backend/executor/README.rpr index 713ad84e1d9..50d1ff87f7e 100644 --- a/src/backend/executor/README.rpr +++ b/src/backend/executor/README.rpr @@ -285,7 +285,7 @@ Element flags (1 byte, bitmask): absorption. 0x08 RPR_ELEM_ABSORBABLE (VAR, END) - Absorption judgment point. Where to compare consecutive + Absorption comparison point. Where to compare consecutive iterations for absorption. - Simple unbounded VAR (A+): set on the VAR itself - Unbounded GROUP ((A B)+): set on the END element only @@ -1393,7 +1393,7 @@ XII-5. Execution Optimization Summary counts) combination through multiple paths. Additionally, for group absorption, nfa_match performs inline advance from bounded VARs (count >= max) within the absorbable region (ABSORBABLE_BRANCH) - through END chains to reach the judgment point (ABSORBABLE END). + through END chains to reach the comparison point (ABSORBABLE END). This process can also produce duplicate states reaching the same END. nfa_add_state_unique() blocks duplicate addition of identical states in both cases. diff --git a/src/backend/executor/execRPR.c b/src/backend/executor/execRPR.c index 099b81aeb81..90e3a068f04 100644 --- a/src/backend/executor/execRPR.c +++ b/src/backend/executor/execRPR.c @@ -578,7 +578,7 @@ nfa_update_absorption_flags(RPRNFAContext *ctx) /* * Iterate through all states to check absorption status. Uses * state->isAbsorbable which tracks if state is in absorbable region. This - * is different from RPRElemIsAbsorbable(elem) which checks judgment + * is different from RPRElemIsAbsorbable(elem) which checks comparison * point. */ for (state = ctx->states; state != NULL; state = state->next) @@ -625,8 +625,8 @@ nfa_states_covered(RPRPattern *pattern, RPRNFAContext *older, RPRNFAContext *new depth = elem->depth; /* - * Only compare at absorption judgment points (RPR_ELEM_ABSORBABLE). - * Judgment points are where count-dominance guarantees the newer + * Only compare at absorption comparison points (RPR_ELEM_ABSORBABLE). + * Comparison points are where count-dominance guarantees the newer * context's future matches are a subset of the older's. */ if (!RPRElemIsAbsorbable(elem)) @@ -782,7 +782,8 @@ nfa_eval_var_match(WindowAggState *winstate, RPRPatternElement *elem, * previous advance when count >= min was satisfied) * * For VARs that reached max count followed by END: - * - Advance through the END-element chain to the absorption judgment point + * - Advance through the END-element chain to the absorption + * comparison point * - Only deterministic exits (count >= max, max != INF) are handled * - Chains through END elements while count >= max (must-exit path) * @@ -800,7 +801,7 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) /* * Evaluate VAR elements against current row. For VARs that reach max * count with END next, advance through the chain of END elements inline - * so absorb phase can compare states at judgment points. + * so absorb phase can compare states at comparison points. */ for (state = ctx->states; state != NULL; state = nextState) { @@ -831,7 +832,7 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) /* * For VAR at max count with END next, advance through END - * chain to reach the absorption judgment point. Only + * chain to reach the absorption comparison point. Only * deterministic exits (count >= max, max finite) are handled; * unbounded VARs stay for advance phase. * @@ -841,10 +842,10 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) * to the next outer END. The loop below walks this chain. * * ABSORBABLE_BRANCH marks elements inside the absorbable - * region; ABSORBABLE marks the outermost judgment point where - * count-dominance is evaluated. We chain through BRANCH - * elements until reaching the ABSORBABLE point or an element - * that can still loop (count < max). + * region; ABSORBABLE marks the outermost comparison point + * where count-dominance is evaluated. We chain through + * BRANCH elements until reaching the ABSORBABLE point or an + * element that can still loop (count < max). */ if (RPRElemIsAbsorbableBranch(elem) && !RPRElemIsAbsorbable(elem) && @@ -876,7 +877,7 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) /* * Chain through END elements within the absorbable region - * (ABSORBABLE_BRANCH) until reaching the judgment point + * (ABSORBABLE_BRANCH) until reaching the comparison point * (ABSORBABLE). Continue only on must-exit path (count * >= max) with END next. */ @@ -892,9 +893,9 @@ nfa_match(WindowAggState *winstate, RPRNFAContext *ctx, bool *varMatched) /* * Exit this intermediate group: clear its own count * (count-clear policy). It sits below the absorbable - * judgment point, so it is excluded from the - * dominance comparison; the judgment point where the - * chain stops keeps its count. + * comparison point, so it is excluded from the + * dominance comparison; the comparison point where + * the chain stops keeps its count. */ state->counts[endDepth] = 0; diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 597a966c7b1..ebba8e50b1d 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -19,7 +19,7 @@ * complexity from O(n^2) to O(n) for patterns like A+ B. * * The absorption analysis uses two element flags: - * - RPR_ELEM_ABSORBABLE: marks WHERE to compare (judgment point) + * - RPR_ELEM_ABSORBABLE: marks WHERE to compare (comparison point) * - RPR_ELEM_ABSORBABLE_BRANCH: marks the absorbable region * * See computeAbsorbability() and the detailed comments before @@ -1484,7 +1484,7 @@ finalizeRPRPattern(RPRPattern *result) * than Ctx2's match (1 to current). So Ctx2 can be safely eliminated. * * Two Flags: - * 1. RPR_ELEM_ABSORBABLE - "Absorption judgment point" + * 1. RPR_ELEM_ABSORBABLE - "Absorption comparison point" * WHERE contexts can be compared for absorption. * - Simple unbounded VAR (A+): the VAR element itself * - Unbounded GROUP ((A B)+): the END element only @@ -1506,20 +1506,20 @@ finalizeRPRPattern(RPRPattern *result) * -> Both at END, comparable! Ctx1 absorbs Ctx2. * * Contexts synchronize at END every group-length rows. Therefore: - * - ABSORBABLE marks END as judgment point (where to compare) + * - ABSORBABLE marks END as comparison point (where to compare) * - ABSORBABLE_BRANCH keeps state.isAbsorbable=true through A->B->END * * Pattern Examples: * * Pattern: A+ B - * Element 0 (A): ABSORBABLE | ABSORBABLE_BRANCH <- judgment point + * Element 0 (A): ABSORBABLE | ABSORBABLE_BRANCH <- comparison point * Element 1 (B): (none) * -> Compare at A every row. When contexts move to B, absorption stops. * * Pattern: (A B)+ C * Element 0 (A): ABSORBABLE_BRANCH * Element 1 (B): ABSORBABLE_BRANCH - * Element 2 (END): ABSORBABLE | ABSORBABLE_BRANCH <- judgment point + * Element 2 (END): ABSORBABLE | ABSORBABLE_BRANCH <- comparison point * Element 3 (C): (none) * -> Compare at END every 2 rows. When contexts move to C, absorption stops. * @@ -1629,7 +1629,7 @@ isFixedLengthChildren(RPRPattern *pattern, RPRElemIdx idx, RPRDepth scopeDepth) * All children must have min == max (recursively for nested subgroups). * This is equivalent to unrolling to {1,1} VARs, e.g., (A B B)+ C. * All elements within the group get ABSORBABLE_BRANCH. - * Only the unbounded END gets ABSORBABLE (judgment point). + * Only the unbounded END gets ABSORBABLE (comparison point). * Examples: * (A B{2})+ C - B{2} has min==max, step=3 * (A (B C){2} D)+ E - nested {2} subgroup, step=6 @@ -1791,7 +1791,7 @@ computeAbsorbabilityRecursive(RPRPattern *pattern, RPRElemIdx startIdx, * decrease property required for safe absorption. * * This function sets two flags: - * RPR_ELEM_ABSORBABLE: Absorption judgment point + * RPR_ELEM_ABSORBABLE: Absorption comparison point * - Simple unbounded VAR: the VAR itself (e.g., A in A+) * - Unbounded GROUP: the END element (e.g., END in (A B)+) * RPR_ELEM_ABSORBABLE_BRANCH: All elements in absorbable region diff --git a/src/include/optimizer/rpr.h b/src/include/optimizer/rpr.h index 23763442b65..83d3cd29b07 100644 --- a/src/include/optimizer/rpr.h +++ b/src/include/optimizer/rpr.h @@ -53,7 +53,7 @@ * optimizer/plan/rpr.c. */ #define RPR_ELEM_ABSORBABLE_BRANCH 0x04 /* element in absorbable region */ -#define RPR_ELEM_ABSORBABLE 0x08 /* absorption judgment point */ +#define RPR_ELEM_ABSORBABLE 0x08 /* absorption comparison point */ /* Accessor macros for RPRPatternElement */ #define RPRElemIsReluctant(e) (((e)->flags & RPR_ELEM_RELUCTANT) != 0) diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out index 80fabde514c..b385e972e7f 100644 --- a/src/test/regress/expected/rpr_base.out +++ b/src/test/regress/expected/rpr_base.out @@ -5472,9 +5472,9 @@ WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -- Absorption Flag Display Tests -- ============================================================ -- Tests absorption marker display in EXPLAIN output --- Markers: ' = branch element, " = judgment point +-- Markers: ' = branch element, " = comparison point -- Files: explain.c (append_rpr_quantifier, deparse_rpr_pattern) --- Simple VAR: A+ -> a+" (judgment point) +-- Simple VAR: A+ -> a+" (comparison point) EXPLAIN (COSTS OFF) SELECT COUNT(*) OVER w FROM rpr_plan WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING @@ -5490,7 +5490,7 @@ WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -> Seq Scan on rpr_plan (7 rows) --- GROUP unbounded: (A B)+ -> (a' b')+" (branch + judgment) +-- GROUP unbounded: (A B)+ -> (a' b')+" (branch + comparison) EXPLAIN (COSTS OFF) SELECT COUNT(*) OVER w FROM rpr_plan WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING diff --git a/src/test/regress/sql/rpr_base.sql b/src/test/regress/sql/rpr_base.sql index 21840aa77be..af498fffb66 100644 --- a/src/test/regress/sql/rpr_base.sql +++ b/src/test/regress/sql/rpr_base.sql @@ -3254,16 +3254,16 @@ WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -- Absorption Flag Display Tests -- ============================================================ -- Tests absorption marker display in EXPLAIN output --- Markers: ' = branch element, " = judgment point +-- Markers: ' = branch element, " = comparison point -- Files: explain.c (append_rpr_quantifier, deparse_rpr_pattern) --- Simple VAR: A+ -> a+" (judgment point) +-- Simple VAR: A+ -> a+" (comparison point) EXPLAIN (COSTS OFF) SELECT COUNT(*) OVER w FROM rpr_plan WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING AFTER MATCH SKIP PAST LAST ROW PATTERN (A+) DEFINE A AS val > 0); --- GROUP unbounded: (A B)+ -> (a' b')+" (branch + judgment) +-- GROUP unbounded: (A B)+ -> (a' b')+" (branch + comparison) EXPLAIN (COSTS OFF) SELECT COUNT(*) OVER w FROM rpr_plan WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING -- 2.50.1 (Apple Git-155)