0005-Disallow-RANGE-and-GROUPS-frame-types-with-RPR.txt

text/plain

Filename: 0005-Disallow-RANGE-and-GROUPS-frame-types-with-RPR.txt
Type: text/plain
Part: 2
Message: Re: Row pattern recognition
From be455295ab82ccc2ae80d6cb633b114a7c345ae4 Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Fri, 13 Feb 2026 21:57:59 +0900
Subject: [PATCH 1/1] Disallow RANGE and GROUPS frame types with row pattern
 recognition

---
 src/backend/parser/parse_rpr.c         | 19 ++++++++++
 src/test/regress/expected/rpr_base.out | 52 ++++++++------------------
 2 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/src/backend/parser/parse_rpr.c b/src/backend/parser/parse_rpr.c
index 048e84bd7bd..80ebf3c33f8 100644
--- a/src/backend/parser/parse_rpr.c
+++ b/src/backend/parser/parse_rpr.c
@@ -68,6 +68,25 @@ transformRPR(ParseState *pstate, WindowClause *wc, WindowDef *windef,
 		return;
 
 	/* Check Frame options */
+
+	/* Frame type must be "ROW" */
+	if (wc->frameOptions & FRAMEOPTION_GROUPS)
+		ereport(ERROR,
+				(errcode(ERRCODE_SYNTAX_ERROR),
+				 errmsg("FRAME option GROUP is not permitted when row pattern recognition is used"),
+				 errhint("Use: ROWS instead"),
+				 parser_errposition(pstate,
+									windef->frameLocation >= 0 ?
+									windef->frameLocation : windef->location)));
+	if (wc->frameOptions & FRAMEOPTION_RANGE)
+		ereport(ERROR,
+				(errcode(ERRCODE_SYNTAX_ERROR),
+				 errmsg("FRAME option RANGE is not permitted when row pattern recognition is used"),
+				 errhint("Use: ROWS instead"),
+				 parser_errposition(pstate,
+									windef->frameLocation >= 0 ?
+									windef->frameLocation : windef->location)));
+
 	/* Frame must start at current row */
 	if ((wc->frameOptions & FRAMEOPTION_START_CURRENT_ROW) == 0)
 	{
diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out
index c269ab99651..a1f11bd61ce 100644
--- a/src/test/regress/expected/rpr_base.out
+++ b/src/test/regress/expected/rpr_base.out
@@ -434,11 +434,10 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS val > 0
 );
-ERROR:  FRAME must start at CURRENT ROW when row pattern recognition is used
+ERROR:  FRAME option RANGE is not permitted when row pattern recognition is used
 LINE 5:     RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWIN...
             ^
-DETAIL:  Current frame starts with UNBOUNDED PRECEDING.
-HINT:  Use: RANGE BETWEEN CURRENT ROW AND ...
+HINT:  Use: ROWS instead
 -- Expected: ERROR: FRAME must start at current row when row pattern recognition is used
 -- GROUPS frame not starting at CURRENT ROW
 SELECT COUNT(*) OVER w
@@ -449,11 +448,10 @@ WINDOW w AS (
     PATTERN (A+)
     DEFINE A AS val > 0
 );
-ERROR:  FRAME must start at CURRENT ROW when row pattern recognition is used
+ERROR:  FRAME option GROUP is not permitted when row pattern recognition is used
 LINE 5:     GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWI...
             ^
-DETAIL:  Current frame starts with UNBOUNDED PRECEDING.
-HINT:  Use: GROUPS BETWEEN CURRENT ROW AND ...
+HINT:  Use: ROWS instead
 -- Expected: ERROR: FRAME must start at current row when row pattern recognition is used
 -- Starting with N PRECEDING
 SELECT COUNT(*) OVER w
@@ -614,16 +612,10 @@ WINDOW w AS (
     DEFINE A AS val >= 0, B AS val >= 0
 )
 ORDER BY id;
- id | val | cnt 
-----+-----+-----
-  1 |  10 |   2
-  2 |  10 |   0
-  3 |  10 |   0
-  4 |  20 |   2
-  5 |  20 |   0
-  6 |  30 |   1
-(6 rows)
-
+ERROR:  FRAME option RANGE is not permitted when row pattern recognition is used
+LINE 5:     RANGE BETWEEN CURRENT ROW AND 10 FOLLOWING
+            ^
+HINT:  Use: ROWS instead
 -- 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)
@@ -642,16 +634,10 @@ WINDOW w AS (
     DEFINE A AS val >= 0, B AS val >= 0
 )
 ORDER BY id;
- id | val | cnt 
-----+-----+-----
-  1 |  10 |   2
-  2 |  10 |   0
-  3 |  10 |   0
-  4 |  20 |   2
-  5 |  20 |   0
-  6 |  30 |   1
-(6 rows)
-
+ERROR:  FRAME option GROUP is not permitted when row pattern recognition is used
+LINE 5:     GROUPS BETWEEN CURRENT ROW AND 1 FOLLOWING
+            ^
+HINT:  Use: ROWS instead
 DROP TABLE rpr_frame;
 -- ============================================================
 -- PARTITION BY + FRAME Tests
@@ -697,16 +683,10 @@ WINDOW w AS (
     DEFINE A AS val >= 10, B AS val >= 20
 )
 ORDER BY id;
- id | grp | val | cnt 
-----+-----+-----+-----
-  1 |   1 |  10 |   2
-  2 |   1 |  20 |   2
-  3 |   1 |  30 |   1
-  4 |   2 |  15 |   2
-  5 |   2 |  25 |   2
-  6 |   2 |  35 |   1
-(6 rows)
-
+ERROR:  FRAME option RANGE is not permitted when row pattern recognition is used
+LINE 6:     RANGE BETWEEN CURRENT ROW AND 10 FOLLOWING
+            ^
+HINT:  Use: ROWS instead
 DROP TABLE rpr_partition;
 -- ============================================================
 -- PATTERN Syntax Tests
-- 
2.50.1 (Apple Git-155)