Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ec057a4

Browse files
committed
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.
1 parent 97ec950 commit ec057a4

File tree

1 file changed

+56
-25
lines changed

1 file changed

+56
-25
lines changed

src/backend/utils/adt/ruleutils.c

+56-25
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* back to source text
44
*
55
* IDENTIFICATION
6-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.212 2005/12/30 18:34:22 tgl Exp $
6+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.213 2006/01/26 17:08:19 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -2018,6 +2018,7 @@ get_basic_select_query(Query *query, deparse_context *context,
20182018
{
20192019
TargetEntry *tle = (TargetEntry *) lfirst(l);
20202020
char *colname;
2021+
char *attname;
20212022

20222023
if (tle->resjunk)
20232024
continue; /* ignore junk entries */
@@ -2026,7 +2027,55 @@ get_basic_select_query(Query *query, deparse_context *context,
20262027
sep = ", ";
20272028
colno++;
20282029

2029-
get_rule_expr((Node *) tle->expr, context, true);
2030+
/*
2031+
* We special-case Var nodes rather than using get_rule_expr.
2032+
* This is needed because get_rule_expr will display a whole-row Var
2033+
* as "foo.*", which is the preferred notation in most contexts, but
2034+
* at the top level of a SELECT list it's not right (the parser will
2035+
* expand that notation into multiple columns, yielding behavior
2036+
* different from a whole-row Var). We want just "foo", instead.
2037+
*/
2038+
if (tle->expr && IsA(tle->expr, Var))
2039+
{
2040+
Var *var = (Var *) (tle->expr);
2041+
char *schemaname;
2042+
char *refname;
2043+
2044+
get_names_for_var(var, 0, context,
2045+
&schemaname, &refname, &attname);
2046+
if (refname && (context->varprefix || attname == NULL))
2047+
{
2048+
if (schemaname)
2049+
appendStringInfo(buf, "%s.",
2050+
quote_identifier(schemaname));
2051+
2052+
if (strcmp(refname, "*NEW*") == 0)
2053+
appendStringInfoString(buf, "new");
2054+
else if (strcmp(refname, "*OLD*") == 0)
2055+
appendStringInfoString(buf, "old");
2056+
else
2057+
appendStringInfoString(buf, quote_identifier(refname));
2058+
2059+
if (attname)
2060+
appendStringInfoChar(buf, '.');
2061+
}
2062+
if (attname)
2063+
appendStringInfoString(buf, quote_identifier(attname));
2064+
else
2065+
{
2066+
/*
2067+
* In the whole-row Var case, refname is what the default AS
2068+
* name would be.
2069+
*/
2070+
attname = refname;
2071+
}
2072+
}
2073+
else
2074+
{
2075+
get_rule_expr((Node *) tle->expr, context, true);
2076+
/* We'll show the AS name unless it's this: */
2077+
attname = "?column?";
2078+
}
20302079

20312080
/*
20322081
* Figure out what the result column should be called. In the context
@@ -2039,28 +2088,10 @@ get_basic_select_query(Query *query, deparse_context *context,
20392088
else
20402089
colname = tle->resname;
20412090

2091+
/* Show AS unless the column's name is correct as-is */
20422092
if (colname) /* resname could be NULL */
20432093
{
2044-
/* Check if we must say AS ... */
2045-
bool tell_as;
2046-
2047-
if (!IsA(tle->expr, Var))
2048-
tell_as = (strcmp(colname, "?column?") != 0);
2049-
else
2050-
{
2051-
Var *var = (Var *) (tle->expr);
2052-
char *schemaname;
2053-
char *refname;
2054-
char *attname;
2055-
2056-
get_names_for_var(var, 0, context,
2057-
&schemaname, &refname, &attname);
2058-
tell_as = (attname == NULL ||
2059-
strcmp(attname, colname) != 0);
2060-
}
2061-
2062-
/* and do if so */
2063-
if (tell_as)
2094+
if (attname == NULL || strcmp(attname, colname) != 0)
20642095
appendStringInfo(buf, " AS %s", quote_identifier(colname));
20652096
}
20662097
}
@@ -3098,17 +3129,17 @@ get_rule_expr(Node *node, deparse_context *context,
30983129
quote_identifier(schemaname));
30993130

31003131
if (strcmp(refname, "*NEW*") == 0)
3101-
appendStringInfo(buf, "new.");
3132+
appendStringInfoString(buf, "new.");
31023133
else if (strcmp(refname, "*OLD*") == 0)
3103-
appendStringInfo(buf, "old.");
3134+
appendStringInfoString(buf, "old.");
31043135
else
31053136
appendStringInfo(buf, "%s.",
31063137
quote_identifier(refname));
31073138
}
31083139
if (attname)
31093140
appendStringInfoString(buf, quote_identifier(attname));
31103141
else
3111-
appendStringInfo(buf, "*");
3142+
appendStringInfoString(buf, "*");
31123143
}
31133144
break;
31143145

0 commit comments

Comments
 (0)