diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c index 7bf78e134bc..3f48cb0b9eb 100644 --- a/src/backend/nodes/print.c +++ b/src/backend/nodes/print.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.40 2000/09/12 21:06:49 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.41 2000/09/25 18:14:55 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -172,11 +172,13 @@ print_expr(Node *expr, List *rtable) break; default: { - RangeTblEntry *rt; + RangeTblEntry *rte; - rt = rt_fetch(var->varno, rtable); - relname = rt->eref->relname; - attname = get_attname(rt->relid, var->varattno); + Assert(var->varno > 0 && + (int) var->varno <= length(rtable)); + rte = rt_fetch(var->varno, rtable); + relname = rte->eref->relname; + attname = get_rte_attribute_name(rte, var->varattno); } break; } diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c index 36c7abd85b5..9f371ff739f 100644 --- a/src/backend/optimizer/util/clauses.c +++ b/src/backend/optimizer/util/clauses.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.74 2000/09/12 21:06:58 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.75 2000/09/25 18:14:55 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -584,12 +584,9 @@ check_subplans_for_ungrouped_vars_walker(Node *node, char *attname; Assert(var->varno > 0 && - var->varno <= length(context->rtable)); + (int) var->varno <= length(context->rtable)); rte = rt_fetch(var->varno, context->rtable); - attname = get_attname(rte->relid, var->varattno); - if (!attname) - elog(ERROR, "cache lookup of attribute %d in relation %u failed", - var->varattno, rte->relid); + attname = get_rte_attribute_name(rte, var->varattno); elog(ERROR, "Sub-SELECT uses un-GROUPed attribute %s.%s from outer query", rte->eref->relname, attname); } diff --git a/src/backend/parser/parse_agg.c b/src/backend/parser/parse_agg.c index 955be022e4e..c3ac417365c 100644 --- a/src/backend/parser/parse_agg.c +++ b/src/backend/parser/parse_agg.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.40 2000/09/12 21:07:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_agg.c,v 1.41 2000/09/25 18:14:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -113,10 +113,7 @@ check_ungrouped_columns_walker(Node *node, Assert(var->varno > 0 && (int) var->varno <= length(context->pstate->p_rtable)); rte = rt_fetch(var->varno, context->pstate->p_rtable); - attname = get_attname(rte->relid, var->varattno); - if (!attname) - elog(ERROR, "cache lookup of attribute %d in relation %u failed", - var->varattno, rte->relid); + attname = get_rte_attribute_name(rte, var->varattno); elog(ERROR, "Attribute %s.%s must be GROUPed or used in an aggregate function", rte->eref->relname, attname); } diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 491cbc5ef08..baae0a578cf 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.47 2000/09/12 21:07:02 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.48 2000/09/25 18:14:54 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -713,6 +713,43 @@ expandNamesVars(ParseState *pstate, List *names, List *vars) return te_list; } +/* ---------- + * get_rte_attribute_name + * Get an attribute name from a RangeTblEntry + * + * This is unlike get_attname() because we use aliases if available. + * In particular, it will work on an RTE for a subselect, whereas + * get_attname() only works on real relations. + * ---------- + */ +char * +get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum) +{ + char *attname; + + /* + * If there is an alias, use it + */ + if (attnum > 0 && attnum <= length(rte->eref->attrs)) + return strVal(nth(attnum-1, rte->eref->attrs)); + /* + * Can get here for a system attribute (which never has an alias), + * or if alias name list is too short (which probably can't happen + * anymore). Neither of these cases is valid for a subselect RTE. + */ + if (rte->relid == InvalidOid) + elog(ERROR, "Invalid attnum %d for rangetable entry %s", + attnum, rte->eref->relname); + /* + * Use the real name of the table's column + */ + attname = get_attname(rte->relid, attnum); + if (attname == NULL) + elog(ERROR, "cache lookup of attribute %d in relation %u failed", + attnum, rte->relid); + return attname; +} + /* * given relation and att name, return id of variable * diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 45282fd94c8..2eaef859f48 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.62 2000/09/18 20:14:23 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.63 2000/09/25 18:14:54 tgl Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -110,7 +110,6 @@ static bool tleIsArrayAssign(TargetEntry *tle); static char *quote_identifier(char *ident); static char *get_relation_name(Oid relid); static char *get_relid_attribute_name(Oid relid, AttrNumber attnum); -static char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); #define only_marker(rte) ((rte)->inh ? "" : "ONLY ") @@ -2020,33 +2019,3 @@ get_relid_attribute_name(Oid relid, AttrNumber attnum) attnum, relid); return attname; } - -/* ---------- - * get_rte_attribute_name - * Get an attribute name from a RangeTblEntry - * - * This is unlike get_relid_attribute_name() because we use aliases if - * available. - * ---------- - */ -static char * -get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum) -{ - /* - * If there is an alias, use it - */ - if (attnum > 0 && attnum <= length(rte->eref->attrs)) - return strVal(nth(attnum-1, rte->eref->attrs)); - /* - * Can get here for a system attribute (which never has an alias), - * or if alias name list is too short (which probably can't happen - * anymore). Neither of these cases is valid for a subselect RTE. - */ - if (rte->relid == InvalidOid) - elog(ERROR, "Invalid attnum %d for rangetable entry %s", - attnum, rte->eref->relname); - /* - * Use the real name of the table's column - */ - return get_relid_attribute_name(rte->relid, attnum); -} diff --git a/src/include/parser/parsetree.h b/src/include/parser/parsetree.h index ff727cfd07a..4936bbdb47c 100644 --- a/src/include/parser/parsetree.h +++ b/src/include/parser/parsetree.h @@ -8,7 +8,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: parsetree.h,v 1.11 2000/09/12 21:07:12 tgl Exp $ + * $Id: parsetree.h,v 1.12 2000/09/25 18:14:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,12 +16,8 @@ #define PARSETREE_H #include "nodes/parsenodes.h" -#include "nodes/pg_list.h" +#include "nodes/pg_list.h" /* for nth(), etc */ -/* ---------------- - * need pg_list.h for definitions of nth(), etc. - * ---------------- - */ /* ---------------- * range table macros @@ -33,10 +29,9 @@ * rt_store * * Access and (destructively) replace rangetable entries. - * */ #define rt_fetch(rangetable_index, rangetable) \ - ((RangeTblEntry*) nth((rangetable_index)-1, rangetable)) + ((RangeTblEntry *) nth((rangetable_index)-1, rangetable)) #define rt_store(rangetable_index, rangetable, rt) \ set_nth(rangetable, (rangetable_index)-1, rt) @@ -45,9 +40,16 @@ * getrelid * * Given the range index of a relation, return the corresponding - * relation OID. + * relation OID. Note that InvalidOid will be returned if the + * RTE is for a sub-select rather than a relation. */ #define getrelid(rangeindex,rangetable) \ (rt_fetch(rangeindex, rangetable)->relid) +/* + * Given an RTE and an attribute number, return the appropriate + * variable name or alias for that attribute of that RTE. + */ +extern char *get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum); + #endif /* PARSETREE_H */