0009-fix-window-dedup.txt
text/plain
From d4c87cb2d5b7f35223dc3bfa9d71809c9fcb135e Mon Sep 17 00:00:00 2001
From: Henson Choi <assam258@gmail.com>
Date: Sun, 8 Mar 2026 18:30:21 +0900
Subject: [PATCH 09/12] Fix window deduplication for RPR windows at parse time
---
src/backend/parser/parse_agg.c | 3 ++-
src/test/regress/expected/rpr_base.out | 26 ++++++++++++++++++++++++++
src/test/regress/sql/rpr_base.sql | 20 ++++++++++++++++++++
3 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c
index 81e1d70ffc1..5e942075444 100644
--- a/src/backend/parser/parse_agg.c
+++ b/src/backend/parser/parse_agg.c
@@ -1110,7 +1110,8 @@ transformWindowFuncCall(ParseState *pstate, WindowFunc *wfunc,
equal(refwin->orderClause, windef->orderClause) &&
refwin->frameOptions == windef->frameOptions &&
equal(refwin->startOffset, windef->startOffset) &&
- equal(refwin->endOffset, windef->endOffset))
+ equal(refwin->endOffset, windef->endOffset) &&
+ equal(refwin->rpCommonSyntax, windef->rpCommonSyntax))
{
/* found a duplicate window specification */
wfunc->winref = winref;
diff --git a/src/test/regress/expected/rpr_base.out b/src/test/regress/expected/rpr_base.out
index 2fefb933c71..09d079b05c6 100644
--- a/src/test/regress/expected/rpr_base.out
+++ b/src/test/regress/expected/rpr_base.out
@@ -14,6 +14,7 @@
-- SKIP TO / INITIAL Tests
-- Serialization/Deserialization Tests (objects kept for pg_upgrade/pg_dump)
-- Error Cases Tests
+-- Window Deduplication Tests
--
-- Planner Layer:
-- Pattern Optimization Tests
@@ -2968,6 +2969,31 @@ ORDER BY id;
(3 rows)
DROP TABLE rpr_null;
+-- ============================================================
+-- Window Deduplication Tests
+-- ============================================================
+-- non-RPR and RPR windows with identical base frame are kept separate.
+SELECT id, val,
+ first_value(id) OVER (
+ ORDER BY id
+ ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ ) AS fv_normal,
+ first_value(id) OVER w1 AS fv_rpr
+FROM (VALUES (1, 10), (2, 20), (3, 30), (4, 40)) AS t(id, val)
+WINDOW w1 AS (
+ ORDER BY id
+ ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ PATTERN (A+)
+ DEFINE A AS val > 10
+);
+ id | val | fv_normal | fv_rpr
+----+-----+-----------+--------
+ 1 | 10 | 1 |
+ 2 | 20 | 2 | 2
+ 3 | 30 | 3 |
+ 4 | 40 | 4 |
+(4 rows)
+
-- ============================================================
-- Pattern Optimization Tests
-- ============================================================
diff --git a/src/test/regress/sql/rpr_base.sql b/src/test/regress/sql/rpr_base.sql
index 453860c1499..95cfb4b86fe 100644
--- a/src/test/regress/sql/rpr_base.sql
+++ b/src/test/regress/sql/rpr_base.sql
@@ -14,6 +14,7 @@
-- SKIP TO / INITIAL Tests
-- Serialization/Deserialization Tests (objects kept for pg_upgrade/pg_dump)
-- Error Cases Tests
+-- Window Deduplication Tests
--
-- Planner Layer:
-- Pattern Optimization Tests
@@ -2080,6 +2081,25 @@ ORDER BY id;
DROP TABLE rpr_null;
+-- ============================================================
+-- Window Deduplication Tests
+-- ============================================================
+
+-- non-RPR and RPR windows with identical base frame are kept separate.
+SELECT id, val,
+ first_value(id) OVER (
+ ORDER BY id
+ ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ ) AS fv_normal,
+ first_value(id) OVER w1 AS fv_rpr
+FROM (VALUES (1, 10), (2, 20), (3, 30), (4, 40)) AS t(id, val)
+WINDOW w1 AS (
+ ORDER BY id
+ ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
+ PATTERN (A+)
+ DEFINE A AS val > 10
+);
+
-- ============================================================
-- Pattern Optimization Tests
-- ============================================================
--
2.50.1 (Apple Git-155)