Skip to content

Commit

Permalink
Deparser: Add parenthesis around AT LOCAL / AT TIMEZONE if needed
Browse files Browse the repository at this point in the history
This fixes a correctness issue where the deparsed SQL is not parsable,
since the table DEFAULT expression is a b_expr, not an a_expr.
  • Loading branch information
lfittl committed Dec 18, 2024
1 parent a203082 commit 6e60a4f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
10 changes: 10 additions & 0 deletions src/postgres_deparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2723,6 +2723,11 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call, DeparseNodeCont
else
e = lsecond(func_call->args);

// If we're not inside an a_expr context, we must add wrapping parenthesis around the AT ... syntax
if (context != DEPARSE_NODE_CONTEXT_A_EXPR) {
appendStringInfoChar(str, '(');
}

if (IsA(e, A_Expr)) {
appendStringInfoChar(str, '(');
}
Expand All @@ -2739,6 +2744,11 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call, DeparseNodeCont
appendStringInfoString(str, " AT TIME ZONE ");
deparseExpr(str, linitial(func_call->args), DEPARSE_NODE_CONTEXT_A_EXPR);
}

if (context != DEPARSE_NODE_CONTEXT_A_EXPR) {
appendStringInfoChar(str, ')');
}

return;
} else if (func_call->funcformat == COERCE_SQL_SYNTAX &&
list_length(func_call->funcname) == 2 &&
Expand Down
6 changes: 5 additions & 1 deletion test/deparse_tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,11 @@ const char* tests[] = {
"CREATE INDEX myindex ON public.mytable USING btree (col1, (col2::varchar) varchar_pattern_ops)",
"SELECT * FROM CAST(1 AS text)",
"DECLARE \"Foo1\" SCROLL CURSOR FOR SELECT * FROM tenk1 ORDER BY unique2",
"FETCH BACKWARD 23 \"Foo1\""
"FETCH BACKWARD 23 \"Foo1\"",
"CREATE TABLE my_table (created_at timestamptz NOT NULL DEFAULT (now() AT TIME ZONE 'UTC'))",
"CREATE TABLE my_table (created_at timestamptz NOT NULL DEFAULT (now() AT LOCAL))",
"CREATE TABLE my_table (created_at timestamptz NOT NULL DEFAULT '1 hour'::interval + (current_timestamp AT TIME ZONE 'UTC'))",
"CREATE TABLE my_table (created_at int NOT NULL DEFAULT 1 + 2)"
};

size_t testsLength = __LINE__ - 4;

0 comments on commit 6e60a4f

Please sign in to comment.