Skip to content

Commit 72fe74c

Browse files
committed
Fix deparsing FETCH FIRST <expr> ROWS WITH TIES
In the grammar, <expr> is a c_expr, which accepts only a limited set of integer literals and simple expressions without parens. The deparsing logic didn't quite match the grammar rule, and failed to use parens e.g. for "5::bigint". To fix, always surround the expression with parens. Would be nice to omit the parens in simple cases, but unfortunately it's non-trivial to detect such simple cases. Even if the expression is a simple literal 123 in the original query, after parse analysis it becomes a FuncExpr with COERCE_IMPLICIT_CAST rather than a simple Const. Reported-by: yonghao lee Backpatch-through: 13 Discussion: https://www.postgresql.org/message-id/18929-077d6b7093b176e2@postgresql.org
1 parent 9d1a623 commit 72fe74c

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5772,9 +5772,19 @@ get_select_query_def(Query *query, deparse_context *context,
57725772
{
57735773
if (query->limitOption == LIMIT_OPTION_WITH_TIES)
57745774
{
5775+
/*
5776+
* The limitCount arg is a c_expr, so it needs parens. Simple
5777+
* literals and function expressions would not need parens, but
5778+
* unfortunately it's hard to tell if the expression will be
5779+
* printed as a simple literal like 123 or as a typecast
5780+
* expression, like '-123'::int4. The grammar accepts the former
5781+
* without quoting, but not the latter.
5782+
*/
57755783
appendContextKeyword(context, " FETCH FIRST ",
57765784
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
5785+
appendStringInfoChar(buf, '(');
57775786
get_rule_expr(query->limitCount, context, false);
5787+
appendStringInfoChar(buf, ')');
57785788
appendStringInfoString(buf, " ROWS WITH TIES");
57795789
}
57805790
else

src/test/regress/expected/limit.out

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ View definition:
643643
WHERE onek.thousand < 995
644644
ORDER BY onek.thousand
645645
OFFSET 10
646-
FETCH FIRST 5 ROWS WITH TIES;
646+
FETCH FIRST (5) ROWS WITH TIES;
647647

648648
CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995
649649
ORDER BY thousand OFFSET 10 FETCH FIRST 5 ROWS ONLY;
@@ -675,15 +675,29 @@ View definition:
675675
FROM onek
676676
WHERE onek.thousand < 995
677677
ORDER BY onek.thousand
678-
FETCH FIRST (NULL::integer + 1) ROWS WITH TIES;
678+
FETCH FIRST ((NULL::integer + 1)) ROWS WITH TIES;
679679

680680
CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995
681-
ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
681+
ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES;
682682
\d+ limit_thousand_v_4
683683
View "public.limit_thousand_v_4"
684684
Column | Type | Collation | Nullable | Default | Storage | Description
685685
----------+---------+-----------+----------+---------+---------+-------------
686686
thousand | integer | | | | plain |
687+
View definition:
688+
SELECT onek.thousand
689+
FROM onek
690+
WHERE onek.thousand < 995
691+
ORDER BY onek.thousand
692+
FETCH FIRST (5::bigint) ROWS WITH TIES;
693+
694+
CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995
695+
ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
696+
\d+ limit_thousand_v_5
697+
View "public.limit_thousand_v_5"
698+
Column | Type | Collation | Nullable | Default | Storage | Description
699+
----------+---------+-----------+----------+---------+---------+-------------
700+
thousand | integer | | | | plain |
687701
View definition:
688702
SELECT onek.thousand
689703
FROM onek

src/test/regress/sql/limit.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995
196196
ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES;
197197
\d+ limit_thousand_v_3
198198
CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995
199-
ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
199+
ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES;
200200
\d+ limit_thousand_v_4
201+
CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995
202+
ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
203+
\d+ limit_thousand_v_5
201204
-- leave these views

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy