* back to source text
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.61 2000/09/12 21:07:05 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.62 2000/09/18 20:14:23 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
static bool tleIsArrayAssign(TargetEntry *tle);
static char *quote_identifier(char *ident);
static char *get_relation_name(Oid relid);
-static char *get_attribute_name(Oid relid, int2 attnum);
+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 ")
* ----------
*/
appendStringInfo(&keybuf, "%s",
- quote_identifier(get_attribute_name(idxrec->indrelid,
+ quote_identifier(get_relid_attribute_name(idxrec->indrelid,
idxrec->indkey[keyno])));
/* ----------
quote_identifier(get_relation_name(ev_class)));
if (ev_attr > 0)
appendStringInfo(buf, ".%s",
- quote_identifier(get_attribute_name(ev_class,
- ev_attr)));
+ quote_identifier(get_relid_attribute_name(ev_class,
+ ev_attr)));
/* If the rule has an event qualification, add it */
if (ev_qual == NULL)
char *attname;
rte = get_rte_for_var(var, context);
- attname = get_attribute_name(rte->relid, var->varattno);
+ attname = get_rte_attribute_name(rte, var->varattno);
tell_as = (strcmp(attname, tle->resdom->resname) != 0);
}
quote_identifier(rte->eref->relname));
}
appendStringInfo(buf, "%s",
- quote_identifier(get_attribute_name(rte->relid,
+ quote_identifier(get_rte_attribute_name(rte,
var->varattno)));
}
break;
if (!OidIsValid(typrelid))
elog(ERROR, "Argument type %s of FieldSelect is not a tuple type",
NameStr(typeStruct->typname));
- fieldname = get_attribute_name(typrelid, fselect->fieldnum);
+ fieldname = get_relid_attribute_name(typrelid,
+ fselect->fieldnum);
appendStringInfo(buf, ".%s", quote_identifier(fieldname));
}
break;
/* ----------
- * get_attribute_name - Get an attribute name by its
- * relations Oid and its attnum
+ * get_relid_attribute_name
+ * Get an attribute name by its relations Oid and its attnum
+ *
+ * Same as underlying syscache routine get_attname(), except that error
+ * is handled by elog() instead of returning NULL.
* ----------
*/
static char *
-get_attribute_name(Oid relid, int2 attnum)
+get_relid_attribute_name(Oid relid, AttrNumber attnum)
{
- HeapTuple atttup;
- Form_pg_attribute attStruct;
+ char *attname;
- atttup = SearchSysCacheTuple(ATTNUM,
- ObjectIdGetDatum(relid), (Datum) attnum,
- 0, 0);
- if (!HeapTupleIsValid(atttup))
+ attname = get_attname(relid, attnum);
+ if (attname == NULL)
elog(ERROR, "cache lookup of attribute %d in relation %u failed",
attnum, relid);
+ return attname;
+}
- attStruct = (Form_pg_attribute) GETSTRUCT(atttup);
- return pstrdup(NameStr(attStruct->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);
}