From c1c65ad8b32c3a4862ab57dc1bcf2cd4b4c5337c Mon Sep 17 00:00:00 2001 From: Tyler Gannon Date: Sun, 15 Dec 2024 18:02:32 -0600 Subject: [PATCH] Fix: deparse DEFAULT (xxx AT TIME ZONE yyy) This commit has been submitted upstream at https://github.com/pganalyze/libpg_query/pull/269. Here I commit it in order to incorporate the fix into downstream dependents. --- parser/postgres_deparse.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/parser/postgres_deparse.c b/parser/postgres_deparse.c index fd4e0ad..f62363f 100644 --- a/parser/postgres_deparse.c +++ b/parser/postgres_deparse.c @@ -2703,6 +2703,30 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call) */ Expr* e; bool isLocal = list_length(func_call->args) == 1; + /* + * time values expressed `AT TIME ZONE` inside a DEFAULT value expression must be surrounded by parentheses + * in order for the deparsed DEFAULT to be valid syntax. + * The following is a simple lookback into the deparsed SQL, to see if is expression immediately follows + * a DEFAULT declaration. + */ + bool isDefaultValue = false; + + { + int end = str->len; + // Step back over trailing spaces + while (end > 0 && isspace((unsigned char) str->data[end - 1])) + end--; + + // Now check if, just before these trailing spaces, we have "DEFAULT" + if (end >= 7 && strncmp(str->data + (end - 7), "DEFAULT", 7) == 0) + { + isDefaultValue = true; + } + } + + if (isDefaultValue) { + appendStringInfoChar(str, '('); + } if (isLocal) e = linitial(func_call->args); @@ -2725,6 +2749,9 @@ static void deparseFuncCall(StringInfo str, FuncCall *func_call) appendStringInfoString(str, " AT TIME ZONE "); deparseExpr(str, linitial(func_call->args)); } + if (isDefaultValue) { + appendStringInfoChar(str, ')'); + } return; } else if (func_call->funcformat == COERCE_SQL_SYNTAX && list_length(func_call->funcname) == 2 &&