aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-01-26 17:08:26 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-01-26 17:08:26 +0000
commit108a2e51c97549f3f05563ef229a44078d2ecaaf (patch)
tree06b1fccba5c7d04df9d546543c3ceaeb05b28458
parentf31a58481c209d70f6c1ff7123fe77071941afe9 (diff)
downloadpostgresql-108a2e51c97549f3f05563ef229a44078d2ecaaf.tar.gz
postgresql-108a2e51c97549f3f05563ef229a44078d2ecaaf.zip
Fix display of whole-row Var appearing at the top level of a SELECT list.
While we normally prefer the notation "foo.*" for a whole-row Var, that does not work at SELECT top level, because in that context the parser will assume that what is wanted is to expand the "*" into a list of separate target columns, yielding behavior different from a whole-row Var. We have to emit just "foo" instead in that context. Per report from Sokolov Yura.
-rw-r--r--src/backend/utils/adt/ruleutils.c81
1 files changed, 56 insertions, 25 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 82830223999..92dd03775e3 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
* back to source text
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.207.2.4 2006/01/17 17:33:21 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.207.2.5 2006/01/26 17:08:26 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -2019,6 +2019,7 @@ get_basic_select_query(Query *query, deparse_context *context,
{
TargetEntry *tle = (TargetEntry *) lfirst(l);
char *colname;
+ char *attname;
if (tle->resjunk)
continue; /* ignore junk entries */
@@ -2027,7 +2028,55 @@ get_basic_select_query(Query *query, deparse_context *context,
sep = ", ";
colno++;
- get_rule_expr((Node *) tle->expr, context, true);
+ /*
+ * We special-case Var nodes rather than using get_rule_expr.
+ * This is needed because get_rule_expr will display a whole-row Var
+ * as "foo.*", which is the preferred notation in most contexts, but
+ * at 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 want just "foo", instead.
+ */
+ if (tle->expr && IsA(tle->expr, Var))
+ {
+ Var *var = (Var *) (tle->expr);
+ char *schemaname;
+ char *refname;
+
+ get_names_for_var(var, 0, context,
+ &schemaname, &refname, &attname);
+ if (refname && (context->varprefix || attname == NULL))
+ {
+ if (schemaname)
+ appendStringInfo(buf, "%s.",
+ quote_identifier(schemaname));
+
+ if (strcmp(refname, "*NEW*") == 0)
+ appendStringInfoString(buf, "new");
+ else if (strcmp(refname, "*OLD*") == 0)
+ appendStringInfoString(buf, "old");
+ else
+ appendStringInfoString(buf, quote_identifier(refname));
+
+ if (attname)
+ appendStringInfoChar(buf, '.');
+ }
+ if (attname)
+ appendStringInfoString(buf, quote_identifier(attname));
+ else
+ {
+ /*
+ * In the whole-row Var case, refname is what the default AS
+ * name would be.
+ */
+ attname = refname;
+ }
+ }
+ else
+ {
+ get_rule_expr((Node *) tle->expr, context, true);
+ /* We'll show the AS name unless it's this: */
+ attname = "?column?";
+ }
/*
* Figure out what the result column should be called. In the context
@@ -2040,28 +2089,10 @@ get_basic_select_query(Query *query, deparse_context *context,
else
colname = tle->resname;
+ /* Show AS unless the column's name is correct as-is */
if (colname) /* resname could be NULL */
{
- /* Check if we must say AS ... */
- bool tell_as;
-
- if (!IsA(tle->expr, Var))
- tell_as = (strcmp(colname, "?column?") != 0);
- else
- {
- Var *var = (Var *) (tle->expr);
- char *schemaname;
- char *refname;
- char *attname;
-
- get_names_for_var(var, 0, context,
- &schemaname, &refname, &attname);
- tell_as = (attname == NULL ||
- strcmp(attname, colname) != 0);
- }
-
- /* and do if so */
- if (tell_as)
+ if (attname == NULL || strcmp(attname, colname) != 0)
appendStringInfo(buf, " AS %s", quote_identifier(colname));
}
}
@@ -3099,9 +3130,9 @@ get_rule_expr(Node *node, deparse_context *context,
quote_identifier(schemaname));
if (strcmp(refname, "*NEW*") == 0)
- appendStringInfo(buf, "new.");
+ appendStringInfoString(buf, "new.");
else if (strcmp(refname, "*OLD*") == 0)
- appendStringInfo(buf, "old.");
+ appendStringInfoString(buf, "old.");
else
appendStringInfo(buf, "%s.",
quote_identifier(refname));
@@ -3109,7 +3140,7 @@ get_rule_expr(Node *node, deparse_context *context,
if (attname)
appendStringInfoString(buf, quote_identifier(attname));
else
- appendStringInfo(buf, "*");
+ appendStringInfoString(buf, "*");
}
break;