diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 59be1044748b6eb502e3e04d8f0389d1f7a7aac4..f5324cb37355532ef4233a335bc40fb5e5eb635e 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.53 2001/03/22 03:59:41 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.54 2001/04/18 17:04:24 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -909,6 +909,9 @@ expandNamesVars(ParseState *pstate, List *names, List *vars) * In particular, it will work on an RTE for a subselect, whereas * get_attname() only works on real relations. * + * "*" is returned if the given attnum is InvalidAttrNumber --- this case + * occurs when a Var represents a whole tuple of a relation. + * * XXX Actually, this is completely bogus, because refnames of RTEs are * not guaranteed unique, and may not even have scope across the whole * query. Cleanest fix would be to add refname/attname to Var nodes and @@ -920,6 +923,9 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum) { char *attname; + if (attnum == InvalidAttrNumber) + return "*"; + /* * If there is an alias, use it */ diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 474ebdfec745102abc6ef83aa32b347749c633cc..5635b90a9fb8ad7e0dd997bccb9ffcf84dcb5a52 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.76 2001/04/15 03:14:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.77 2001/04/18 17:04:24 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -1051,7 +1051,8 @@ get_basic_select_query(Query *query, deparse_context *context) char *attname; get_names_for_var(var, context, &refname, &attname); - tell_as = (strcmp(attname, tle->resdom->resname) != 0); + tell_as = (attname == NULL || + strcmp(attname, tle->resdom->resname) != 0); } /* and do if so */ @@ -1380,6 +1381,9 @@ get_utility_query_def(Query *query, deparse_context *context) /* * Get the relation refname and attname for a (possibly nonlocal) Var. * + * attname will be returned as NULL if the Var represents a whole tuple + * of the relation. + * * This is trickier than it ought to be because of the possibility of aliases * and limited scope of refnames. We have to try to return the correct alias * with respect to the current namespace given by the context. @@ -1414,7 +1418,10 @@ get_names_for_var(Var *var, deparse_context *context, */ rte = rt_fetch(var->varno, dpns->rtable); *refname = rte->eref->relname; - *attname = get_rte_attribute_name(rte, var->varattno); + if (var->varattno == InvalidAttrNumber) + *attname = NULL; + else + *attname = get_rte_attribute_name(rte, var->varattno); } /* @@ -1474,7 +1481,10 @@ find_alias_in_namespace(Node *nsnode, Node *expr, RangeTblEntry *rte = rt_fetch(rtindex, rangetable); *refname = rte->eref->relname; - *attname = get_rte_attribute_name(rte, var->varattno); + if (var->varattno == InvalidAttrNumber) + *attname = NULL; + else + *attname = get_rte_attribute_name(rte, var->varattno); return true; } } @@ -1684,17 +1694,20 @@ get_rule_expr(Node *node, deparse_context *context) char *attname; get_names_for_var(var, context, &refname, &attname); - if (context->varprefix) + if (context->varprefix || attname == NULL) { if (strcmp(refname, "*NEW*") == 0) - appendStringInfo(buf, "new."); + appendStringInfo(buf, "new"); else if (strcmp(refname, "*OLD*") == 0) - appendStringInfo(buf, "old."); + appendStringInfo(buf, "old"); else - appendStringInfo(buf, "%s.", + appendStringInfo(buf, "%s", quote_identifier(refname)); + if (attname) + appendStringInfoChar(buf, '.'); } - appendStringInfo(buf, "%s", quote_identifier(attname)); + if (attname) + appendStringInfo(buf, "%s", quote_identifier(attname)); } break;