nocfbot-0020-Add-reluctant-bounded-mid-band-test-to-rpr_nfa.txt

text/plain

Filename: nocfbot-0020-Add-reluctant-bounded-mid-band-test-to-rpr_nfa.txt
Type: text/plain
Part: 19
Message: Re: Row pattern recognition
From 2e062833fb363874896bc2ba2d931d6f522a55c4 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Wed, 27 May 2026 14:15:09 +0900
Subject: [PATCH 20/26] Add reluctant bounded mid-band test to rpr_nfa

PATTERN (A{3,5}? B) drives the VAR-level count in nfa_advance_var
through 3, 4, 5 within a single match attempt -- a band the
existing A{1,3}? B test does not exercise, because A and B match
the same row there and advance's early-termination path frees the
loop state before nfa_advance_var sees count > 2.

This explicitly exercises the count > 2 && reluctant &&
!isAbsorbable path that absorbability analysis structurally
constrains (reluctant quantifiers are excluded, so isAbsorbable
stays false).
---
 src/test/regress/expected/rpr_nfa.out | 38 +++++++++++++++++++++++++++
 src/test/regress/sql/rpr_nfa.sql      | 29 ++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/src/test/regress/expected/rpr_nfa.out b/src/test/regress/expected/rpr_nfa.out
index fe5bb324df0..1f494d2db34 100644
--- a/src/test/regress/expected/rpr_nfa.out
+++ b/src/test/regress/expected/rpr_nfa.out
@@ -2237,6 +2237,44 @@ WINDOW w AS (
   4 | {B,_} |             |          
 (4 rows)
 
+-- A{3,5}? B (reluctant bounded mid-band): the VAR-level count in
+-- nfa_advance_var cycles through 3, 4, 5 within a single match
+-- attempt.  Exercises the count > 2 && reluctant && !isAbsorbable
+-- branch (absorbability analysis excludes reluctant quantifiers, so
+-- isAbsorbable stays false for A).
+WITH test_reluctant_mid_band AS (
+    SELECT * FROM (VALUES
+        (1, ARRAY['A']),
+        (2, ARRAY['A']),
+        (3, ARRAY['A']),
+        (4, ARRAY['A']),
+        (5, ARRAY['A']),
+        (6, ARRAY['B'])
+    ) AS t(id, flags)
+)
+SELECT id, flags,
+       first_value(id) OVER w AS match_start,
+       last_value(id) OVER w AS match_end
+FROM test_reluctant_mid_band
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN (A{3,5}? B)
+    DEFINE
+        A AS 'A' = ANY(flags),
+        B AS 'B' = ANY(flags)
+);
+ id | flags | match_start | match_end 
+----+-------+-------------+-----------
+  1 | {A}   |           1 |         6
+  2 | {A}   |             |          
+  3 | {A}   |             |          
+  4 | {A}   |             |          
+  5 | {A}   |             |          
+  6 | {B}   |             |          
+(6 rows)
+
 -- ============================================================
 -- Pathological Pattern Runtime Protection
 -- ============================================================
diff --git a/src/test/regress/sql/rpr_nfa.sql b/src/test/regress/sql/rpr_nfa.sql
index 7a5b5c41b24..76dfc4d88bc 100644
--- a/src/test/regress/sql/rpr_nfa.sql
+++ b/src/test/regress/sql/rpr_nfa.sql
@@ -1554,6 +1554,35 @@ WINDOW w AS (
         B AS 'B' = ANY(flags)
 );
 
+-- A{3,5}? B (reluctant bounded mid-band): the VAR-level count in
+-- nfa_advance_var cycles through 3, 4, 5 within a single match
+-- attempt.  Exercises the count > 2 && reluctant && !isAbsorbable
+-- branch (absorbability analysis excludes reluctant quantifiers, so
+-- isAbsorbable stays false for A).
+WITH test_reluctant_mid_band AS (
+    SELECT * FROM (VALUES
+        (1, ARRAY['A']),
+        (2, ARRAY['A']),
+        (3, ARRAY['A']),
+        (4, ARRAY['A']),
+        (5, ARRAY['A']),
+        (6, ARRAY['B'])
+    ) AS t(id, flags)
+)
+SELECT id, flags,
+       first_value(id) OVER w AS match_start,
+       last_value(id) OVER w AS match_end
+FROM test_reluctant_mid_band
+WINDOW w AS (
+    ORDER BY id
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN (A{3,5}? B)
+    DEFINE
+        A AS 'A' = ANY(flags),
+        B AS 'B' = ANY(flags)
+);
+
 -- ============================================================
 -- Pathological Pattern Runtime Protection
 -- ============================================================
-- 
2.50.1 (Apple Git-155)