Skip to content

Commit fe1a7e1

Browse files
tglsfdcreshke
authored andcommitted
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 2963d35 commit fe1a7e1

3 files changed

Lines changed: 20 additions & 17 deletions

File tree

src/backend/utils/adt/ruleutils.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8304,11 +8304,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
83048304
{
83058305
case T_FuncExpr:
83068306
{
8307-
/* special handling for casts */
8307+
/* special handling for casts and COERCE_SQL_SYNTAX */
83088308
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
83098309

83108310
if (type == COERCE_EXPLICIT_CAST ||
8311-
type == COERCE_IMPLICIT_CAST)
8311+
type == COERCE_IMPLICIT_CAST ||
8312+
type == COERCE_SQL_SYNTAX)
83128313
return false;
83138314
return true; /* own parentheses */
83148315
}
@@ -8356,11 +8357,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
83568357
return false;
83578358
case T_FuncExpr:
83588359
{
8359-
/* special handling for casts */
8360+
/* special handling for casts and COERCE_SQL_SYNTAX */
83608361
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
83618362

83628363
if (type == COERCE_EXPLICIT_CAST ||
8363-
type == COERCE_IMPLICIT_CAST)
8364+
type == COERCE_IMPLICIT_CAST ||
8365+
type == COERCE_SQL_SYNTAX)
83648366
return false;
83658367
return true; /* own parentheses */
83668368
}
@@ -10432,9 +10434,11 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1043210434
case F_TIMEZONE_TEXT_TIMETZ:
1043310435
/* AT TIME ZONE ... note reversed argument order */
1043410436
appendStringInfoChar(buf, '(');
10435-
get_rule_expr((Node *) lsecond(expr->args), context, false);
10437+
get_rule_expr_paren((Node *) lsecond(expr->args), context, false,
10438+
(Node *) expr);
1043610439
appendStringInfoString(buf, " AT TIME ZONE ");
10437-
get_rule_expr((Node *) linitial(expr->args), context, false);
10440+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10441+
(Node *) expr);
1043810442
appendStringInfoChar(buf, ')');
1043910443
return true;
1044010444

@@ -10486,9 +10490,10 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1048610490

1048710491
case F_IS_NORMALIZED:
1048810492
/* IS xxx NORMALIZED */
10489-
appendStringInfoString(buf, "((");
10490-
get_rule_expr((Node *) linitial(expr->args), context, false);
10491-
appendStringInfoString(buf, ") IS");
10493+
appendStringInfoString(buf, "(");
10494+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10495+
(Node *) expr);
10496+
appendStringInfoString(buf, " IS");
1049210497
if (list_length(expr->args) == 2)
1049310498
{
1049410499
Const *con = (Const *) lsecond(expr->args);
@@ -10509,11 +10514,6 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1050910514
appendStringInfoChar(buf, ')');
1051010515
return true;
1051110516

10512-
/*
10513-
* XXX EXTRACT, a/k/a date_part(), is intentionally not covered
10514-
* yet. Add it after we change the return type to numeric.
10515-
*/
10516-
1051710517
case F_NORMALIZE:
1051810518
/* NORMALIZE() */
1051910519
appendStringInfoString(buf, "NORMALIZE(");

src/test/regress/expected/create_view.out

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,7 @@ select pg_get_viewdef('tt20v', true);
17971797
-- reverse-listing of various special function syntaxes required by SQL
17981798
create view tt201v as
17991799
select
1800+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
18001801
extract(day from now()) as extr,
18011802
(now(), '1 day'::interval) overlaps
18021803
(current_timestamp(2), '1 day'::interval) as o,
@@ -1819,10 +1820,11 @@ select
18191820
select pg_get_viewdef('tt201v', true);
18201821
pg_get_viewdef
18211822
-----------------------------------------------------------------------------------------------
1822-
SELECT EXTRACT(day FROM now()) AS extr, +
1823+
SELECT (('12-01-2022'::date + '@ 1 day'::interval) AT TIME ZONE 'UTC'::text) AS atz, +
1824+
EXTRACT(day FROM now()) AS extr, +
18231825
((now(), '@ 1 day'::interval) OVERLAPS (CURRENT_TIMESTAMP(2), '@ 1 day'::interval)) AS o,+
1824-
(('foo'::text) IS NORMALIZED) AS isn, +
1825-
(('foo'::text) IS NFKC NORMALIZED) AS isnn, +
1826+
('foo'::text IS NORMALIZED) AS isn, +
1827+
('foo'::text IS NFKC NORMALIZED) AS isnn, +
18261828
NORMALIZE('foo'::text) AS n, +
18271829
NORMALIZE('foo'::text, NFKD) AS nfkd, +
18281830
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
@@ -615,6 +615,7 @@ select pg_get_viewdef('tt20v', true);
615615

616616
create view tt201v as
617617
select
618+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
618619
extract(day from now()) as extr,
619620
(now(), '1 day'::interval) overlaps
620621
(current_timestamp(2), '1 day'::interval) as o,

0 commit comments

Comments
 (0)