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)