nocfbot-absorb-bounded-outer-test.txt

text/plain

Filename: nocfbot-absorb-bounded-outer-test.txt
Type: text/plain
Part: 0
Message: Re: Row pattern recognition
diff --git a/src/test/regress/expected/rpr_explain.out b/src/test/regress/expected/rpr_explain.out
index d8343c9accc..11c51d6f764 100644
--- a/src/test/regress/expected/rpr_explain.out
+++ b/src/test/regress/expected/rpr_explain.out
@@ -906,6 +906,50 @@ WINDOW w AS (
    ->  Function Scan on generate_series s (actual rows=50.00 loops=1)
 (10 rows)
 
+-- Context absorption with a bounded outer group whose body starts with A+
+-- The outer count {2,3} is bounded, but A+ is still the first unbounded portion
+-- of the pattern, so it remains the absorption comparison point (a+ keeps the "
+-- marker and contexts are absorbed).  A bounded outer group must not, by itself,
+-- disable absorption of the leading unbounded child.
+CREATE VIEW rpr_ev_ctx_absorb_bounded_outer AS
+SELECT count(*) OVER w
+FROM generate_series(1, 50) AS s(v)
+WINDOW w AS (
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN ((A+ B){2,3})
+    DEFINE A AS v % 5 <> 0, B AS v % 5 = 0
+);
+SELECT line FROM unnest(string_to_array(pg_get_viewdef('rpr_ev_ctx_absorb_bounded_outer'), E'\n')) AS line WHERE line ~ 'PATTERN';
+           line           
+--------------------------
+   PATTERN ((a+ b){2,3}) 
+(1 row)
+
+SELECT rpr_explain_filter('
+EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF)
+SELECT count(*) OVER w
+FROM generate_series(1, 50) AS s(v)
+WINDOW w AS (
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN ((A+ B){2,3})
+    DEFINE A AS v % 5 <> 0, B AS v % 5 = 0
+);');
+                          rpr_explain_filter                          
+----------------------------------------------------------------------
+ WindowAgg (actual rows=50.00 loops=1)
+   Window: w AS (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING)
+   Pattern: (a+" b){2,3}
+   Nav Mark Lookback: 0
+   Storage: Memory  Maximum Storage: NkB
+   NFA States: 6 peak, 118 total, 0 merged
+   NFA Contexts: 3 peak, 51 total, 4 pruned
+   NFA: 3 matched (len 15/15/15.0), 1 mismatched (len 5/5/5.0)
+   NFA: 30 absorbed (len 1/1/1.0), 12 skipped (len 1/5/3.0)
+   ->  Function Scan on generate_series s (actual rows=50.00 loops=1)
+(10 rows)
+
 -- Contexts skipped by SKIP PAST LAST ROW
 CREATE VIEW rpr_ev_ctx_skip AS
 SELECT count(*) OVER w
diff --git a/src/test/regress/sql/rpr_explain.sql b/src/test/regress/sql/rpr_explain.sql
index 3cd94af6bb8..5a9c83e7886 100644
--- a/src/test/regress/sql/rpr_explain.sql
+++ b/src/test/regress/sql/rpr_explain.sql
@@ -570,6 +570,32 @@ WINDOW w AS (
     DEFINE A AS v % 5 <> 0, B AS v % 5 = 0
 );');
 
+-- Context absorption with a bounded outer group whose body starts with A+
+-- The outer count {2,3} is bounded, but A+ is still the first unbounded portion
+-- of the pattern, so it remains the absorption comparison point (a+ keeps the "
+-- marker and contexts are absorbed).  A bounded outer group must not, by itself,
+-- disable absorption of the leading unbounded child.
+CREATE VIEW rpr_ev_ctx_absorb_bounded_outer AS
+SELECT count(*) OVER w
+FROM generate_series(1, 50) AS s(v)
+WINDOW w AS (
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN ((A+ B){2,3})
+    DEFINE A AS v % 5 <> 0, B AS v % 5 = 0
+);
+SELECT line FROM unnest(string_to_array(pg_get_viewdef('rpr_ev_ctx_absorb_bounded_outer'), E'\n')) AS line WHERE line ~ 'PATTERN';
+SELECT rpr_explain_filter('
+EXPLAIN (ANALYZE, BUFFERS OFF, COSTS OFF, TIMING OFF, SUMMARY OFF)
+SELECT count(*) OVER w
+FROM generate_series(1, 50) AS s(v)
+WINDOW w AS (
+    ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+    AFTER MATCH SKIP PAST LAST ROW
+    PATTERN ((A+ B){2,3})
+    DEFINE A AS v % 5 <> 0, B AS v % 5 = 0
+);');
+
 -- Contexts skipped by SKIP PAST LAST ROW
 CREATE VIEW rpr_ev_ctx_skip AS
 SELECT count(*) OVER w