git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 9d1a623)
Fix deparsing FETCH FIRST <expr> ROWS WITH TIES
2025年5月19日 15:50:26 +0000 (18:50 +0300)
2025年5月19日 15:50:52 +0000 (18:50 +0300)
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


diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 035faf418f01152030a24603564e62262e350552..59c9fba3827b0ed94c69d46726899e364e988983 100644 (file)
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -5772,9 +5772,19 @@ get_select_query_def(Query *query, deparse_context *context,
{
if (query->limitOption == LIMIT_OPTION_WITH_TIES)
{
+ /*
+ * The limitCount arg is a c_expr, so it needs parens. Simple
+ * literals and function expressions would not need parens, but
+ * unfortunately it's hard to tell if the expression will be
+ * printed as a simple literal like 123 or as a typecast
+ * expression, like '-123'::int4. The grammar accepts the former
+ * without quoting, but not the latter.
+ */
appendContextKeyword(context, " FETCH FIRST ",
-PRETTYINDENT_STD, PRETTYINDENT_STD, 0);
+ appendStringInfoChar(buf, '(');
get_rule_expr(query->limitCount, context, false);
+ appendStringInfoChar(buf, ')');
appendStringInfoString(buf, " ROWS WITH TIES");
}
else
diff --git a/src/test/regress/expected/limit.out b/src/test/regress/expected/limit.out
index 8a98bbea8eb97ce6cc66526a106fda6210f1db24..d10c912d12e402a757105b8fc77587f843525085 100644 (file)
--- a/src/test/regress/expected/limit.out
+++ b/src/test/regress/expected/limit.out
@@ -643,7 +643,7 @@ View definition:
WHERE onek.thousand < 995
ORDER BY onek.thousand
OFFSET 10
- FETCH FIRST 5 ROWS WITH TIES;
+ FETCH FIRST (5) ROWS WITH TIES;
CREATE VIEW limit_thousand_v_2 AS SELECT thousand FROM onek WHERE thousand < 995
ORDER BY thousand OFFSET 10 FETCH FIRST 5 ROWS ONLY;
@@ -675,15 +675,29 @@ View definition:
FROM onek
WHERE onek.thousand < 995
ORDER BY onek.thousand
- FETCH FIRST (NULL::integer + 1) ROWS WITH TIES;
+ FETCH FIRST ((NULL::integer + 1)) ROWS WITH TIES;
CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995
- ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
+ ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES;
\d+ limit_thousand_v_4
View "public.limit_thousand_v_4"
Column | Type | Collation | Nullable | Default | Storage | Description
----------+---------+-----------+----------+---------+---------+-------------
thousand | integer | | | | plain |
+View definition:
+ SELECT onek.thousand
+ FROM onek
+ WHERE onek.thousand < 995
+ ORDER BY onek.thousand
+ FETCH FIRST (5::bigint) ROWS WITH TIES;
+
+CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995
+ ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
+\d+ limit_thousand_v_5
+ View "public.limit_thousand_v_5"
+ Column | Type | Collation | Nullable | Default | Storage | Description
+----------+---------+-----------+----------+---------+---------+-------------
+ thousand | integer | | | | plain |
View definition:
SELECT onek.thousand
FROM onek
diff --git a/src/test/regress/sql/limit.sql b/src/test/regress/sql/limit.sql
index 6f0cda98701559d13d620d68855f24a15914f0ba..603910fe6d11c10350a0f6e148a1f50b52504268 100644 (file)
--- a/src/test/regress/sql/limit.sql
+++ b/src/test/regress/sql/limit.sql
@@ -196,6 +196,9 @@ CREATE VIEW limit_thousand_v_3 AS SELECT thousand FROM onek WHERE thousand < 995
ORDER BY thousand FETCH FIRST (NULL+1) ROWS WITH TIES;
\d+ limit_thousand_v_3
CREATE VIEW limit_thousand_v_4 AS SELECT thousand FROM onek WHERE thousand < 995
- ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
+ ORDER BY thousand FETCH FIRST (5::bigint) ROWS WITH TIES;
\d+ limit_thousand_v_4
+CREATE VIEW limit_thousand_v_5 AS SELECT thousand FROM onek WHERE thousand < 995
+ ORDER BY thousand FETCH FIRST NULL ROWS ONLY;
+\d+ limit_thousand_v_5
-- leave these views
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /