From ec057a4380b7e4637c971ce902539723eaaf01a8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 26 Jan 2006 17:08:19 +0000 Subject: [PATCH] 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. --- src/backend/utils/adt/ruleutils.c | 81 +++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 25 deletions(-) diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 7c47054633..05e817ecc0 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.212 2005/12/30 18:34:22 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.213 2006/01/26 17:08:19 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -2018,6 +2018,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 */ @@ -2026,7 +2027,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 @@ -2039,28 +2088,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)); } } @@ -3098,9 +3129,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)); @@ -3108,7 +3139,7 @@ get_rule_expr(Node *node, deparse_context *context, if (attname) appendStringInfoString(buf, quote_identifier(attname)); else - appendStringInfo(buf, "*"); + appendStringInfoString(buf, "*"); } break; -- 2.11.0