0001-Fix-non-ASCII-characters-in-RPR-code-and-comments.txt

text/plain

Filename: 0001-Fix-non-ASCII-characters-in-RPR-code-and-comments.txt
Type: text/plain
Part: 0
Message: Re: Row pattern recognition
From 1cc2ebd59597c672b752d7b6912dedc2bde88d66 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Tue, 3 Feb 2026 17:30:06 +0900
Subject: [PATCH 1/1] 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)