aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r--src/backend/utils/adt/ruleutils.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 51391f6a4e0..3388f7c17ea 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -391,6 +391,8 @@ static void appendContextKeyword(deparse_context *context, const char *str,
static void removeStringInfoSpaces(StringInfo str);
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_oper_expr(OpExpr *expr, deparse_context *context);
static void get_func_expr(FuncExpr *expr, deparse_context *context,
bool showimplicit);
@@ -4347,10 +4349,10 @@ get_values_def(List *values_lists, deparse_context *context)
/*
* Strip any top-level nodes representing indirection assignments,
- * then print the result.
+ * then print the result. Whole-row Vars need special treatment.
*/
- get_rule_expr(processIndirection(col, context, false),
- context, false);
+ get_rule_expr_toplevel(processIndirection(col, context, false),
+ context, false);
}
appendStringInfoChar(buf, ')');
}
@@ -4771,7 +4773,8 @@ get_target_list(List *targetList, deparse_context *context,
* the top level of a SELECT list it's not right (the parser will
* expand that notation into multiple columns, yielding behavior
* different from a whole-row Var). We need to call get_variable
- * directly so that we can tell it to do the right thing.
+ * directly so that we can tell it to do the right thing, and so that
+ * we can get the attribute name which is the default AS label.
*/
if (tle->expr && (IsA(tle->expr, Var)))
{
@@ -7515,7 +7518,8 @@ get_rule_expr(Node *node, deparse_context *context,
!tupdesc->attrs[i]->attisdropped)
{
appendStringInfoString(buf, sep);
- get_rule_expr(e, context, true);
+ /* Whole-row Vars need special treatment here */
+ get_rule_expr_toplevel(e, context, true);
sep = ", ";
}
i++;
@@ -7941,6 +7945,27 @@ get_rule_expr(Node *node, deparse_context *context,
}
}
+/*
+ * get_rule_expr_toplevel - Parse back a toplevel expression
+ *
+ * Same as get_rule_expr(), except that if the expr is just a Var, we pass
+ * istoplevel = true not false to get_variable(). This causes whole-row Vars
+ * to get printed with decoration that will prevent expansion of "*".
+ * We need to use this in contexts such as ROW() and VALUES(), where the
+ * parser would expand "foo.*" appearing at top level. (In principle we'd
+ * use this in get_target_list() too, but that has additional worries about
+ * whether to print AS, so it needs to invoke get_variable() directly anyway.)
+ */
+static void
+get_rule_expr_toplevel(Node *node, deparse_context *context,
+ bool showimplicit)
+{
+ if (node && IsA(node, Var))
+ (void) get_variable((Var *) node, 0, true, context);
+ else
+ get_rule_expr(node, context, showimplicit);
+}
+
/*
* get_oper_expr - Parse back an OpExpr node