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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy