diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2022-01-13 17:49:25 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2022-01-13 17:49:46 -0500 |
commit | 43c2175121c829c8591fc5117b725f1f22bfb670 (patch) | |
tree | e1a5d6307968bc4438d4acb0b9415d54deee7745 /src/backend/utils/adt/ruleutils.c | |
parent | dfc0cb3940cd4d1f19fcf6c7545dc6cc01c6c92c (diff) | |
download | postgresql-43c2175121c829c8591fc5117b725f1f22bfb670.tar.gz postgresql-43c2175121c829c8591fc5117b725f1f22bfb670.zip |
Fix ruleutils.c's dumping of whole-row Vars in more contexts.
Commit 7745bc352 intended to ensure that whole-row Vars would be
printed with "::type" decoration in all contexts where plain
"var.*" notation would result in star-expansion, notably in
ROW() and VALUES() constructs. However, it missed the case of
INSERT with a single-row VALUES, as reported by Timur Khanjanov.
Nosing around ruleutils.c, I found a second oversight: the
code for RowCompareExpr generates ROW() notation without benefit
of an actual RowExpr, and naturally it wasn't in sync :-(.
(The code for FieldStore also does this, but we don't expect that
to generate strictly parsable SQL anyway, so I left it alone.)
Back-patch to all supported branches.
Discussion: https://postgr.es/m/efaba6f9-4190-56be-8ff2-7a1674f9194f@intrans.baku.az
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 56 |
1 files changed, 34 insertions, 22 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 63b85566822..039b1d2b951 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -438,6 +438,8 @@ static void get_rule_expr(Node *node, deparse_context *context, bool showimplicit); static void get_rule_expr_toplevel(Node *node, deparse_context *context, bool showimplicit); +static void get_rule_list_toplevel(List *lst, deparse_context *context, + bool showimplicit); static void get_rule_expr_funccall(Node *node, deparse_context *context, bool showimplicit); static bool looks_like_function(Node *node); @@ -6632,7 +6634,7 @@ get_insert_query_def(Query *query, deparse_context *context) /* Add the single-VALUES expression list */ appendContextKeyword(context, "VALUES (", -PRETTYINDENT_STD, PRETTYINDENT_STD, 2); - get_rule_expr((Node *) strippedexprs, context, false); + get_rule_list_toplevel(strippedexprs, context, false); appendStringInfoChar(buf, ')'); } else @@ -8996,23 +8998,15 @@ get_rule_expr(Node *node, deparse_context *context, case T_RowCompareExpr: { RowCompareExpr *rcexpr = (RowCompareExpr *) node; - ListCell *arg; - char *sep; /* * SQL99 allows "ROW" to be omitted when there is more than - * one column, but for simplicity we always print it. + * one column, but for simplicity we always print it. Within + * a ROW expression, whole-row Vars need special treatment, so + * use get_rule_list_toplevel. */ appendStringInfoString(buf, "(ROW("); - sep = ""; - foreach(arg, rcexpr->largs) - { - Node *e = (Node *) lfirst(arg); - - appendStringInfoString(buf, sep); - get_rule_expr(e, context, true); - sep = ", "; - } + get_rule_list_toplevel(rcexpr->largs, context, true); /* * We assume that the name of the first-column operator will @@ -9025,15 +9019,7 @@ get_rule_expr(Node *node, deparse_context *context, generate_operator_name(linitial_oid(rcexpr->opnos), exprType(linitial(rcexpr->largs)), exprType(linitial(rcexpr->rargs)))); - sep = ""; - foreach(arg, rcexpr->rargs) - { - Node *e = (Node *) lfirst(arg); - - appendStringInfoString(buf, sep); - get_rule_expr(e, context, true); - sep = ", "; - } + get_rule_list_toplevel(rcexpr->rargs, context, true); appendStringInfoString(buf, "))"); } break; @@ -9579,6 +9565,32 @@ get_rule_expr_toplevel(Node *node, deparse_context *context, } /* + * get_rule_list_toplevel - Parse back a list of toplevel expressions + * + * Apply get_rule_expr_toplevel() to each element of a List. + * + * This adds commas between the expressions, but caller is responsible + * for printing surrounding decoration. + */ +static void +get_rule_list_toplevel(List *lst, deparse_context *context, + bool showimplicit) +{ + const char *sep; + ListCell *lc; + + sep = ""; + foreach(lc, lst) + { + Node *e = (Node *) lfirst(lc); + + appendStringInfoString(context->buf, sep); + get_rule_expr_toplevel(e, context, showimplicit); + sep = ", "; + } +} + +/* * get_rule_expr_funccall - Parse back a function-call expression * * Same as get_rule_expr(), except that we guarantee that the output will |