diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2025-05-19 18:49:12 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2025-05-19 18:49:34 +0300 |
commit | 7ee00918f7cdd76c8c1120f019288dd71d48f42d (patch) | |
tree | 2a4898b640e1de848d13cadf0b0161746f1797fe /src/backend/utils/adt | |
parent | e323d9df002debb103a58ba2479368c46804a9b6 (diff) |
Fix deparsing FETCH FIRST <expr> ROWS WITH TIES
In the grammar, <expr> is a c_expr, which accepts only a limited set
of simple constants and 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
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index de586d8da3c..660bf69a023 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -5300,9 +5300,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, ')'); appendStringInfo(buf, " ROWS WITH TIES"); } else |