Skip to content

Commit 1dd6700

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 4dd00b0 commit 1dd6700

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
@@ -8254,11 +8254,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
82548254
{
82558255
case T_FuncExpr:
82568256
{
8257-
/* special handling for casts */
8257+
/* special handling for casts and COERCE_SQL_SYNTAX */
82588258
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
82598259

82608260
if (type == COERCE_EXPLICIT_CAST ||
8261-
type == COERCE_IMPLICIT_CAST)
8261+
type == COERCE_IMPLICIT_CAST ||
8262+
type == COERCE_SQL_SYNTAX)
82628263
return false;
82638264
return true; /* own parentheses */
82648265
}
@@ -8306,11 +8307,12 @@ isSimpleNode(Node *node, Node *parentNode, int prettyFlags)
83068307
return false;
83078308
case T_FuncExpr:
83088309
{
8309-
/* special handling for casts */
8310+
/* special handling for casts and COERCE_SQL_SYNTAX */
83108311
CoercionForm type = ((FuncExpr *) parentNode)->funcformat;
83118312

83128313
if (type == COERCE_EXPLICIT_CAST ||
8313-
type == COERCE_IMPLICIT_CAST)
8314+
type == COERCE_IMPLICIT_CAST ||
8315+
type == COERCE_SQL_SYNTAX)
83148316
return false;
83158317
return true; /* own parentheses */
83168318
}
@@ -10046,9 +10048,11 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1004610048
case F_TIMEZONE_TEXT_TIMETZ:
1004710049
/* AT TIME ZONE ... note reversed argument order */
1004810050
appendStringInfoChar(buf, '(');
10049-
get_rule_expr((Node *) lsecond(expr->args), context, false);
10051+
get_rule_expr_paren((Node *) lsecond(expr->args), context, false,
10052+
(Node *) expr);
1005010053
appendStringInfoString(buf, " AT TIME ZONE ");
10051-
get_rule_expr((Node *) linitial(expr->args), context, false);
10054+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10055+
(Node *) expr);
1005210056
appendStringInfoChar(buf, ')');
1005310057
return true;
1005410058

@@ -10100,9 +10104,10 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1010010104

1010110105
case F_IS_NORMALIZED:
1010210106
/* IS xxx NORMALIZED */
10103-
appendStringInfoString(buf, "((");
10104-
get_rule_expr((Node *) linitial(expr->args), context, false);
10105-
appendStringInfoString(buf, ") IS");
10107+
appendStringInfoString(buf, "(");
10108+
get_rule_expr_paren((Node *) linitial(expr->args), context, false,
10109+
(Node *) expr);
10110+
appendStringInfoString(buf, " IS");
1010610111
if (list_length(expr->args) == 2)
1010710112
{
1010810113
Const *con = (Const *) lsecond(expr->args);
@@ -10123,11 +10128,6 @@ get_func_sql_syntax(FuncExpr *expr, deparse_context *context)
1012310128
appendStringInfoChar(buf, ')');
1012410129
return true;
1012510130

10126-
/*
10127-
* XXX EXTRACT, a/k/a date_part(), is intentionally not covered
10128-
* yet. Add it after we change the return type to numeric.
10129-
*/
10130-
1013110131
case F_NORMALIZE:
1013210132
/* NORMALIZE() */
1013310133
appendStringInfoString(buf, "NORMALIZE(");

src/test/regress/expected/create_view.out

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1922,6 +1922,7 @@ select pg_get_viewdef('tt20v', true);
19221922
-- reverse-listing of various special function syntaxes required by SQL
19231923
create view tt201v as
19241924
select
1925+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
19251926
extract(day from now()) as extr,
19261927
(now(), '1 day'::interval) overlaps
19271928
(current_timestamp(2), '1 day'::interval) as o,
@@ -1976,10 +1977,11 @@ select
19761977
select pg_get_viewdef('tt201v', true);
19771978
pg_get_viewdef
19781979
-----------------------------------------------------------------------------------------------
1979-
SELECT EXTRACT(day FROM now()) AS extr, +
1980+
SELECT (('12-01-2022'::date + '@ 1 day'::interval) AT TIME ZONE 'UTC'::text) AS atz, +
1981+
EXTRACT(day FROM now()) AS extr, +
19801982
((now(), '@ 1 day'::interval) OVERLAPS (CURRENT_TIMESTAMP(2), '@ 1 day'::interval)) AS o,+
1981-
(('foo'::text) IS NORMALIZED) AS isn, +
1982-
(('foo'::text) IS NFKC NORMALIZED) AS isnn, +
1983+
('foo'::text IS NORMALIZED) AS isn, +
1984+
('foo'::text IS NFKC NORMALIZED) AS isnn, +
19831985
NORMALIZE('foo'::text) AS n, +
19841986
NORMALIZE('foo'::text, NFKD) AS nfkd, +
19851987
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
@@ -703,6 +703,7 @@ select pg_get_viewdef('tt20v', true);
703703

704704
create view tt201v as
705705
select
706+
('2022-12-01'::date + '1 day'::interval) at time zone 'UTC' as atz,
706707
extract(day from now()) as extr,
707708
(now(), '1 day'::interval) overlaps
708709
(current_timestamp(2), '1 day'::interval) as o,

0 commit comments

Comments
 (0)