Skip to content

Commit de0ff60

Browse files
committed
Fix under-parenthesized display of AT TIME ZONE constructs.
In commit 40c24bf, I forgot to use get_rule_expr_paren() for the arguments of AT TIME ZONE, resulting in possibly not printing parens for expressions that need it. But get_rule_expr_paren() wouldn't have gotten it right anyway, because isSimpleNode() hadn't been taught that COERCE_SQL_SYNTAX parent nodes don't guarantee sufficient parentheses. Improve all that. Also use this methodology for F_IS_NORMALIZED, so that we don't print useless parens for that. In passing, remove a comment that was obsoleted later. Per report from Duncan Sands. Back-patch to v14 where this code came in. (Before that, we didn't try to print AT TIME ZONE that way, so there was no bug just ugliness.) Discussion: https://postgr.es/m/f41566aa-a057-6628-4b7c-b48770ecb84a@deepbluecap.com
1 parent cf9bcb0 commit de0ff60

File tree

3 files changed

+20
-17
lines changed

3 files changed

+20
-17
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8189,11 +8189,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
81898189
{
81908190
case T_FuncExpr:
81918191
{
8192-
/* special handling for casts */
8192+
/* special handling for casts and COERCE_SQL_SYNTAX */
81938193
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
81948194

81958195
if (type == COERCE_EXPLICIT_CAST ||
8196-
type == COERCE_IMPLICIT_CAST)
8196+
type == COERCE_IMPLICIT_CAST ||
8197+
type == COERCE_SQL_SYNTAX)
81978198
return false;
81988199
return true; /* own parentheses */
81998200
}
@@ -8241,11 +8242,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
82418242
return false;
82428243
case T_FuncExpr:
82438244
{
8244-
/* special handling for casts */
8245+
/* special handling for casts and COERCE_SQL_SYNTAX */
82458246
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
82468247

82478248
if (type == COERCE_EXPLICIT_CAST ||
8248-
type == COERCE_IMPLICIT_CAST)
8249+
type == COERCE_IMPLICIT_CAST ||
8250+
type == COERCE_SQL_SYNTAX)
82498251
return false;
82508252
return true; /* own parentheses */
82518253
}
@@ -10017,9 +10019,11 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1001710019
case F_TIMEZONE_TEXT_TIMETZ:
1001810020
/* AT TIME ZONE ... note reversed argument order */
1001910021
appendStringInfoChar(buf, '(');
10020-
get_rule_expr((Node *) lsecond(expr->args), context, false);
10022+
get_rule_expr_paren((Node *) lsecond(expr->args), context, false,
10023+
(Node *) expr);
1002110024
appendStringInfoString(buf, " AT TIME ZONE ");
10022-
get_rule_expr((Node *) linitial(expr->args), context, false);
10025+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10026+
(Node *) expr);
1002310027
appendStringInfoChar(buf, ')');
1002410028
return true;
1002510029

@@ -10071,9 +10075,10 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1007110075

1007210076
case F_IS_NORMALIZED:
1007310077
/* IS xxx NORMALIZED */
10074-
appendStringInfoString(buf, "((");
10075-
get_rule_expr((Node *) linitial(expr->args), context, false);
10076-
appendStringInfoString(buf, ") IS");
10078+
appendStringInfoString(buf, "(");
10079+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10080+
(Node *) expr);
10081+
appendStringInfoString(buf, " IS");
1007710082
if (list_length(expr->args) == 2)
1007810083
{
1007910084
Const *con = (Const *) lsecond(expr->args);
@@ -10094,11 +10099,6 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1009410099
appendStringInfoChar(buf, ')');
1009510100
return true;
1009610101

10097-
/*
10098-
* XXX EXTRACT, a/k/a date_part(), is intentionally not covered
10099-
* yet. Add it after we change the return type to numeric.
10100-
*/
10101-
1010210102
case F_NORMALIZE:
1010310103
/* NORMALIZE() */
1010410104
appendStringInfoString(buf, "NORMALIZE(");

src/test/regress/expected/create_view.out

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1790,6 +1790,7 @@ select pg_get_viewdef('tt20v', true);
17901790
-- reverse-listing of various special function syntaxes required by SQL
17911791
create view tt201v as
17921792
select
1793+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
17931794
extract(day from now()) as extr,
17941795
(now(), '1 day'::interval) overlaps
17951796
(current_timestamp(2), '1 day'::interval) as o,
@@ -1812,10 +1813,11 @@ select
18121813
select pg_get_viewdef('tt201v', true);
18131814
pg_get_viewdef
18141815
-----------------------------------------------------------------------------------------------
1815-
SELECT EXTRACT(day FROM now()) AS extr, +
1816+
SELECT (('12-01-2022'::date + '@ 1 day'::interval) AT TIME ZONE 'UTC'::text) AS atz, +
1817+
EXTRACT(day FROM now()) AS extr, +
18161818
((now(), '@ 1 day'::interval) OVERLAPS (CURRENT_TIMESTAMP(2), '@ 1 day'::interval)) AS o,+
1817-
(('foo'::text) IS NORMALIZED) AS isn, +
1818-
(('foo'::text) IS NFKC NORMALIZED) AS isnn, +
1819+
('foo'::text IS NORMALIZED) AS isn, +
1820+
('foo'::text IS NFKC NORMALIZED) AS isnn, +
18191821
NORMALIZE('foo'::text) AS n, +
18201822
NORMALIZE('foo'::text, NFKD) AS nfkd, +
18211823
OVERLAY('foo'::text PLACING 'bar'::text FROM 2) AS ovl, +

src/test/regress/sql/create_view.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ select pg_get_viewdef('tt20v', true);
608608

609609
create view tt201v as
610610
select
611+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
611612
extract(day from now()) as extr,
612613
(now(), '1 day'::interval) overlaps
613614
(current_timestamp(2), '1 day'::interval) as o,

0 commit comments

Comments
 (0)