From 1cc2ebd59597c672b752d7b6912dedc2bde88d66 Mon Sep 17 00:00:00 2001 From: Henson Choi Date: Tue, 3 Feb 2026 17:30:06 +0900 Subject: [PATCH] Fix non-ASCII characters in RPR code and comments --- src/backend/executor/nodeWindowAgg.c | 10 ++++----- src/backend/optimizer/plan/rpr.c | 2 +- src/include/nodes/execnodes.h | 8 ++++---- src/test/regress/expected/rpr.out | 14 ++++++------- src/test/regress/expected/rpr_base.out | 28 +++++++++++++------------- src/test/regress/sql/rpr.sql | 14 ++++++------- src/test/regress/sql/rpr_base.sql | 28 +++++++++++++------------- 7 files changed, 52 insertions(+), 52 deletions(-) diff --git a/src/backend/executor/nodeWindowAgg.c b/src/backend/executor/nodeWindowAgg.c index bcdf8b6db81..1176df04b2c 100644 --- a/src/backend/executor/nodeWindowAgg.c +++ b/src/backend/executor/nodeWindowAgg.c @@ -4977,7 +4977,7 @@ register_result: * These functions implement direct NFA execution using the compiled * RPRPattern structure, avoiding regex compilation overhead. * - * Execution Flow: match → absorb → advance + * Execution Flow: match -> absorb -> advance * ----------------------------------------- * The NFA execution follows a three-phase cycle for each row: * @@ -4997,7 +4997,7 @@ register_result: * * Key Design Decisions: * --------------------- - * - VAR→END transition in match phase: When a simple VAR (max=1) matches + * - VAR->END transition in match phase: When a simple VAR (max=1) matches * and the next element is END, we transition immediately in the match * phase rather than waiting for advance. This is necessary for correct * absorption: states must be at END to be marked absorbable before the @@ -5008,7 +5008,7 @@ register_result: * This ensures patterns like "A B? C" work correctly - we need a state * waiting for B AND a state that has already skipped to C. * - * - END→END count increment: When transitioning from one END to another + * - END->END count increment: When transitioning from one END to another * END within advance, we must increment the outer END's count. This * handles nested groups like "((A|B)+)+" correctly - exiting the inner * group counts as one iteration of the outer group. @@ -6092,7 +6092,7 @@ nfa_advance_end(WindowAggState *winstate, RPRNFAContext *ctx, state->elemIdx = elem->next; nextElem = &elements[state->elemIdx]; - /* END→END: increment outer END's count */ + /* END->END: increment outer END's count */ if (RPRElemIsEnd(nextElem) && state->counts[nextElem->depth] < RPR_COUNT_MAX) state->counts[nextElem->depth]++; @@ -6123,7 +6123,7 @@ nfa_advance_end(WindowAggState *winstate, RPRNFAContext *ctx, exitState->counts[depth] = 0; nextElem = &elements[exitState->elemIdx]; - /* END→END: increment outer END's count */ + /* END->END: increment outer END's count */ if (RPRElemIsEnd(nextElem) && exitState->counts[nextElem->depth] < RPR_COUNT_MAX) exitState->counts[nextElem->depth]++; diff --git a/src/backend/optimizer/plan/rpr.c b/src/backend/optimizer/plan/rpr.c index 230c545a631..50043c416c6 100644 --- a/src/backend/optimizer/plan/rpr.c +++ b/src/backend/optimizer/plan/rpr.c @@ -1379,7 +1379,7 @@ isUnboundedStart(RPRPattern *pattern, RPRElemIdx idx, RPRDepth parentDepth) * * Context absorption eliminates redundant match searches by absorbing * newer contexts that cannot produce longer matches than older contexts. - * This achieves O(n²) → O(n) performance improvement. + * This achieves O(n^2) -> O(n) performance improvement. * * Only greedy unbounded quantifiers at pattern start can be absorbable. * Reluctant quantifiers are excluded because they don't maintain monotonic diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index b6d6d942de9..e0704742d16 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -2545,11 +2545,11 @@ typedef struct RPRNFAState * RPRNFAContext - context for NFA pattern matching execution * * Two-flag absorption design: - * hasAbsorbableState: can this context absorb others? (≥1 absorbable state) - * - Monotonic: true→false only, cannot recover once false + * hasAbsorbableState: can this context absorb others? (>=1 absorbable state) + * - Monotonic: true->false only, cannot recover once false * - Used to skip absorption attempts once all absorbable states are gone * allStatesAbsorbable: can this context be absorbed? (ALL states absorbable) - * - Dynamic: can change false→true (when non-absorbable states die) + * - Dynamic: can change false->true (when non-absorbable states die) * - Used to determine if this context is eligible for absorption */ typedef struct RPRNFAContext @@ -2564,7 +2564,7 @@ typedef struct RPRNFAContext RPRNFAState *matchedState; /* FIN state for greedy fallback (cloned) */ /* Two-flag absorption optimization */ - bool hasAbsorbableState; /* can absorb others (≥1 absorbable + bool hasAbsorbableState; /* can absorb others (>=1 absorbable * state) */ bool allStatesAbsorbable; /* can be absorbed (ALL states * absorbable) */ diff --git a/src/test/regress/expected/rpr.out b/src/test/regress/expected/rpr.out index c4794c5cd88..d4298860865 100644 --- a/src/test/regress/expected/rpr.out +++ b/src/test/regress/expected/rpr.out @@ -3099,11 +3099,11 @@ WINDOW w AS ( 5 | {E,_} | | (5 rows) --- Row 1: A=T, B=T → matches A --- Row 2: B=T, C=T → matches B --- Row 3: C=T, D=T → matches C --- Row 4: D=T, E=T → matches D --- Row 5: E=T → matches E +-- Row 1: A=T, B=T -> matches A +-- Row 2: B=T, C=T -> matches B +-- Row 3: C=T, D=T -> matches C +-- Row 4: D=T, E=T -> matches D +-- Row 5: E=T -> matches E -- Result: match 1-5 (A B C D E) -- Test 6: Diagonal pattern with multi-TRUE (shifted overlap) WITH test_diagonal AS ( @@ -3138,8 +3138,8 @@ WINDOW w AS ( (5 rows) -- Possible matches: --- Start Row 1: A(1) B(2) C(3) D(4) → 1-4 --- Start Row 2: A(2) B(3) C(4) D(5) → 2-5 (because Row 2 has A too!) +-- Start Row 1: A(1) B(2) C(3) D(4) -> 1-4 +-- Start Row 2: A(2) B(3) C(4) D(5) -> 2-5 (because Row 2 has A too!) -- =================================================================== -- Context Absorption Tests -- =================================================================== diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out index b34b9e59d25..23851c5a11c 100644 --- a/src/test/regress/expected/rpr_base.out +++ b/src/test/regress/expected/rpr_base.out @@ -336,9 +336,9 @@ INSERT INTO rpr_frame VALUES -- Valid frame options -- ROWS: counts physical rows (1 FOLLOWING = next 1 physical row) -- Expected result: Each row can see 1 physical row ahead --- id=1,2,3 (val=10): can see next row → cnt=2 --- id=4,5 (val=20): can see next row → cnt=2 --- id=6 (val=30): no next row → cnt=1 +-- id=1,2,3 (val=10): can see next row -> cnt=2 +-- id=4,5 (val=20): can see next row -> cnt=2 +-- id=6 (val=30): no next row -> cnt=1 -- Result: [2,2,2,2,2,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -598,11 +598,11 @@ ORDER BY id; -- RANGE: includes all rows with same ORDER BY value -- Expected result: Includes peer rows (same val) in range calculation --- id=1 (val=10): range [10,20] includes all val=10 and val=20 peers → cnt=2 (only first in peer group gets match) --- id=2,3 (val=10): already matched by id=1 → cnt=0 --- id=4 (val=20): range [20,30] includes all val=20 and val=30 peers → cnt=2 --- id=5 (val=20): already matched by id=4 → cnt=0 --- id=6 (val=30): range [30,40] includes only val=30 → cnt=1 +-- id=1 (val=10): range [10,20] includes all val=10 and val=20 peers -> cnt=2 (only first in peer group gets match) +-- id=2,3 (val=10): already matched by id=1 -> cnt=0 +-- id=4 (val=20): range [20,30] includes all val=20 and val=30 peers -> cnt=2 +-- id=5 (val=20): already matched by id=4 -> cnt=0 +-- id=6 (val=30): range [30,40] includes only val=30 -> cnt=1 -- Result: [2,0,0,2,0,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -626,11 +626,11 @@ ORDER BY id; -- GROUPS: treats rows with same value as one group (1 FOLLOWING = next group) -- Expected result: 1 FOLLOWING means current group + 1 next group --- id=1 (val=10): groups [val=10, val=20] → cnt=2 (only first in group gets match) --- id=2,3 (val=10): already matched by id=1 → cnt=0 --- id=4 (val=20): groups [val=20, val=30] → cnt=2 --- id=5 (val=20): already matched by id=4 → cnt=0 --- id=6 (val=30): groups [val=30] (no next group) → cnt=1 +-- id=1 (val=10): groups [val=10, val=20] -> cnt=2 (only first in group gets match) +-- id=2,3 (val=10): already matched by id=1 -> cnt=0 +-- id=4 (val=20): groups [val=20, val=30] -> cnt=2 +-- id=5 (val=20): already matched by id=4 -> cnt=0 +-- id=6 (val=30): groups [val=30] (no next group) -> cnt=1 -- Result: [2,0,0,2,0,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -3549,7 +3549,7 @@ WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING -- ============================================================ -- Absorption Analysis Tests -- ============================================================ --- Tests context absorption optimization (O(n²) → O(n)) +-- Tests context absorption optimization (O(n^2) -> O(n)) -- Files: rpr.c (computeAbsorbability) -- Simple Absorbable Pattern: A+ B -- Pattern starts with unbounded VAR diff --git a/src/test/regress/sql/rpr.sql b/src/test/regress/sql/rpr.sql index 8ab1daf87d6..788a77e5279 100644 --- a/src/test/regress/sql/rpr.sql +++ b/src/test/regress/sql/rpr.sql @@ -1527,11 +1527,11 @@ WINDOW w AS ( D AS 'D' = ANY(flags), E AS 'E' = ANY(flags) ); --- Row 1: A=T, B=T → matches A --- Row 2: B=T, C=T → matches B --- Row 3: C=T, D=T → matches C --- Row 4: D=T, E=T → matches D --- Row 5: E=T → matches E +-- Row 1: A=T, B=T -> matches A +-- Row 2: B=T, C=T -> matches B +-- Row 3: C=T, D=T -> matches C +-- Row 4: D=T, E=T -> matches D +-- Row 5: E=T -> matches E -- Result: match 1-5 (A B C D E) -- Test 6: Diagonal pattern with multi-TRUE (shifted overlap) @@ -1558,8 +1558,8 @@ WINDOW w AS ( D AS 'D' = ANY(flags) ); -- Possible matches: --- Start Row 1: A(1) B(2) C(3) D(4) → 1-4 --- Start Row 2: A(2) B(3) C(4) D(5) → 2-5 (because Row 2 has A too!) +-- Start Row 1: A(1) B(2) C(3) D(4) -> 1-4 +-- Start Row 2: A(2) B(3) C(4) D(5) -> 2-5 (because Row 2 has A too!) -- =================================================================== -- Context Absorption Tests diff --git a/src/test/regress/sql/rpr_base.sql b/src/test/regress/sql/rpr_base.sql index 88f0a2c2083..a5a66d2ca81 100644 --- a/src/test/regress/sql/rpr_base.sql +++ b/src/test/regress/sql/rpr_base.sql @@ -280,9 +280,9 @@ INSERT INTO rpr_frame VALUES -- ROWS: counts physical rows (1 FOLLOWING = next 1 physical row) -- Expected result: Each row can see 1 physical row ahead --- id=1,2,3 (val=10): can see next row → cnt=2 --- id=4,5 (val=20): can see next row → cnt=2 --- id=6 (val=30): no next row → cnt=1 +-- id=1,2,3 (val=10): can see next row -> cnt=2 +-- id=4,5 (val=20): can see next row -> cnt=2 +-- id=6 (val=30): no next row -> cnt=1 -- Result: [2,2,2,2,2,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -464,11 +464,11 @@ ORDER BY id; -- RANGE: includes all rows with same ORDER BY value -- Expected result: Includes peer rows (same val) in range calculation --- id=1 (val=10): range [10,20] includes all val=10 and val=20 peers → cnt=2 (only first in peer group gets match) --- id=2,3 (val=10): already matched by id=1 → cnt=0 --- id=4 (val=20): range [20,30] includes all val=20 and val=30 peers → cnt=2 --- id=5 (val=20): already matched by id=4 → cnt=0 --- id=6 (val=30): range [30,40] includes only val=30 → cnt=1 +-- id=1 (val=10): range [10,20] includes all val=10 and val=20 peers -> cnt=2 (only first in peer group gets match) +-- id=2,3 (val=10): already matched by id=1 -> cnt=0 +-- id=4 (val=20): range [20,30] includes all val=20 and val=30 peers -> cnt=2 +-- id=5 (val=20): already matched by id=4 -> cnt=0 +-- id=6 (val=30): range [30,40] includes only val=30 -> cnt=1 -- Result: [2,0,0,2,0,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -483,11 +483,11 @@ ORDER BY id; -- GROUPS: treats rows with same value as one group (1 FOLLOWING = next group) -- Expected result: 1 FOLLOWING means current group + 1 next group --- id=1 (val=10): groups [val=10, val=20] → cnt=2 (only first in group gets match) --- id=2,3 (val=10): already matched by id=1 → cnt=0 --- id=4 (val=20): groups [val=20, val=30] → cnt=2 --- id=5 (val=20): already matched by id=4 → cnt=0 --- id=6 (val=30): groups [val=30] (no next group) → cnt=1 +-- id=1 (val=10): groups [val=10, val=20] -> cnt=2 (only first in group gets match) +-- id=2,3 (val=10): already matched by id=1 -> cnt=0 +-- id=4 (val=20): groups [val=20, val=30] -> cnt=2 +-- id=5 (val=20): already matched by id=4 -> cnt=0 +-- id=6 (val=30): groups [val=30] (no next group) -> cnt=1 -- Result: [2,0,0,2,0,1] SELECT id, val, COUNT(*) OVER w as cnt FROM rpr_frame @@ -2331,7 +2331,7 @@ WINDOW w AS (ORDER BY id ROWS BETWEEN CURRENT ROW AND 10 FOLLOWING -- ============================================================ -- Absorption Analysis Tests -- ============================================================ --- Tests context absorption optimization (O(n²) → O(n)) +-- Tests context absorption optimization (O(n^2) -> O(n)) -- Files: rpr.c (computeAbsorbability) -- Simple Absorbable Pattern: A+ B -- 2.50.1 (Apple Git-155)