From d4c87cb2d5b7f35223dc3bfa9d71809c9fcb135e Mon Sep 17 00:00:00 2001 From: Henson Choi 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)