aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/common/tupdesc.c16
-rw-r--r--src/backend/catalog/dependency.c6
-rw-r--r--src/backend/nodes/print.c5
-rw-r--r--src/backend/optimizer/prep/preptlist.c4
-rw-r--r--src/backend/optimizer/prep/prepunion.c21
-rw-r--r--src/backend/parser/analyze.c13
-rw-r--r--src/backend/parser/parse_relation.c12
-rw-r--r--src/backend/parser/parse_target.c17
-rw-r--r--src/backend/rewrite/rewriteHandler.c22
-rw-r--r--src/backend/utils/adt/ruleutils.c68
-rw-r--r--src/backend/utils/cache/lsyscache.c25
-rw-r--r--src/backend/utils/misc/guc.c6
-rw-r--r--src/include/access/tupdesc.h4
-rw-r--r--src/include/nodes/primnodes.h39
-rw-r--r--src/include/utils/lsyscache.h3
15 files changed, 145 insertions, 116 deletions
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index b76e03ed43f..9a40c08ca92 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.98 2003/08/04 02:39:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.99 2003/08/11 23:04:49 tgl Exp $
*
* NOTES
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -357,7 +357,7 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
void
TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber,
- char *attributeName,
+ const char *attributeName,
Oid oidtypeid,
int32 typmod,
int attdim,
@@ -373,13 +373,6 @@ TupleDescInitEntry(TupleDesc desc,
AssertArg(PointerIsValid(desc));
AssertArg(attributeNumber >= 1);
AssertArg(attributeNumber <= desc->natts);
-
- /*
- * attributeName's are sometimes NULL, from resdom's. I don't know
- * why that is, though -- Jolly
- */
-/* AssertArg(NameIsValid(attributeName));*/
-
AssertArg(!PointerIsValid(desc->attrs[attributeNumber - 1]));
/*
@@ -394,6 +387,11 @@ TupleDescInitEntry(TupleDesc desc,
*/
att->attrelid = 0; /* dummy value */
+ /*
+ * Note: attributeName can be NULL, because the planner doesn't always
+ * fill in valid resname values in targetlists, particularly for resjunk
+ * attributes.
+ */
if (attributeName != NULL)
namestrcpy(&(att->attname), attributeName);
else
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index 870a2320c2f..8155f4fff3f 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.30 2003/08/04 02:39:58 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.31 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1439,8 +1439,8 @@ getObjectDescription(const ObjectAddress *object)
getRelationDescription(&buffer, object->objectId);
if (object->objectSubId != 0)
appendStringInfo(&buffer, " column %s",
- get_attname(object->objectId,
- object->objectSubId));
+ get_relid_attribute_name(object->objectId,
+ object->objectSubId));
break;
case OCLASS_PROC:
diff --git a/src/backend/nodes/print.c b/src/backend/nodes/print.c
index c3d702316d2..c3417d8efa2 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.63 2003/08/04 02:39:59 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/print.c,v 1.64 2003/08/11 23:04:49 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -448,7 +448,8 @@ print_tl(List *tlist, List *rtable)
{
TargetEntry *tle = lfirst(tl);
- printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);
+ printf("\t%d %s\t", tle->resdom->resno,
+ tle->resdom->resname ? tle->resdom->resname : "<null>");
if (tle->resdom->ressortgroupref != 0)
printf("(%u):\t", tle->resdom->ressortgroupref);
else
diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c
index 5796870e767..f2368d06779 100644
--- a/src/backend/optimizer/prep/preptlist.c
+++ b/src/backend/optimizer/prep/preptlist.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.64 2003/08/04 02:40:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/preptlist.c,v 1.65 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -150,8 +150,6 @@ expand_targetlist(List *tlist, int command_type,
if (!resdom->resjunk && resdom->resno == attrno)
{
- Assert(strcmp(resdom->resname,
- NameStr(att_tup->attname)) == 0);
new_tle = old_tle;
tlist = lnext(tlist);
}
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index d023fd97a8f..281b15571d5 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -14,7 +14,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.103 2003/08/04 02:40:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.104 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -64,7 +64,7 @@ static bool tlist_same_datatypes(List *tlist, List *colTypes, bool junkOK);
static Node *adjust_inherited_attrs_mutator(Node *node,
adjust_inherited_attrs_context *context);
static Relids adjust_relid_set(Relids relids, Index oldrelid, Index newrelid);
-static List *adjust_inherited_tlist(List *tlist, Oid new_relid);
+static List *adjust_inherited_tlist(List *tlist, Oid old_relid, Oid new_relid);
/*
@@ -787,6 +787,7 @@ adjust_inherited_attrs(Node *node,
if (newnode->commandType == CMD_UPDATE)
newnode->targetList =
adjust_inherited_tlist(newnode->targetList,
+ old_relid,
new_relid);
}
return (Node *) newnode;
@@ -812,9 +813,10 @@ adjust_inherited_attrs_mutator(Node *node,
var->varnoold = context->new_rt_index;
if (var->varattno > 0)
{
- char *attname = get_attname(context->old_relid,
- var->varattno);
+ char *attname;
+ attname = get_relid_attribute_name(context->old_relid,
+ var->varattno);
var->varattno = get_attnum(context->new_relid, attname);
if (var->varattno == InvalidAttrNumber)
elog(ERROR, "attribute \"%s\" of relation \"%s\" does not exist",
@@ -976,7 +978,7 @@ adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
* Note that this is not needed for INSERT because INSERT isn't inheritable.
*/
static List *
-adjust_inherited_tlist(List *tlist, Oid new_relid)
+adjust_inherited_tlist(List *tlist, Oid old_relid, Oid new_relid)
{
bool changed_it = false;
List *tl;
@@ -989,21 +991,26 @@ adjust_inherited_tlist(List *tlist, Oid new_relid)
{
TargetEntry *tle = (TargetEntry *) lfirst(tl);
Resdom *resdom = tle->resdom;
+ char *attname;
if (resdom->resjunk)
continue; /* ignore junk items */
- attrno = get_attnum(new_relid, resdom->resname);
+ attname = get_relid_attribute_name(old_relid, resdom->resno);
+ attrno = get_attnum(new_relid, attname);
if (attrno == InvalidAttrNumber)
elog(ERROR, "attribute \"%s\" of relation \"%s\" does not exist",
- resdom->resname, get_rel_name(new_relid));
+ attname, get_rel_name(new_relid));
if (resdom->resno != attrno)
{
resdom = (Resdom *) copyObject((Node *) resdom);
resdom->resno = attrno;
+ resdom->resname = attname;
tle->resdom = resdom;
changed_it = true;
}
+ else
+ pfree(attname);
}
/*
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index ea9a1d80a8e..832c98a1c1c 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.286 2003/08/08 21:41:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.287 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2124,10 +2124,12 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
{
Oid colType = lfirsto(dtlist);
Resdom *leftResdom = ((TargetEntry *) lfirst(lefttl))->resdom;
- char *colName = pstrdup(leftResdom->resname);
+ char *colName;
Resdom *resdom;
Expr *expr;
+ Assert(!leftResdom->resjunk);
+ colName = pstrdup(leftResdom->resname);
resdom = makeResdom((AttrNumber) pstate->p_next_resno++,
colType,
-1,
@@ -2501,11 +2503,12 @@ transformUpdateStmt(ParseState *pstate, UpdateStmt *stmt)
{
/*
* Resjunk nodes need no additional processing, but be sure
- * they have names and resnos that do not match any target
- * columns; else rewriter or planner might get confused.
+ * they have resnos that do not match any target columns;
+ * else rewriter or planner might get confused. They don't
+ * need a resname either.
*/
- resnode->resname = "?resjunk?";
resnode->resno = (AttrNumber) pstate->p_next_resno++;
+ resnode->resname = NULL;
continue;
}
if (origTargetList == NIL)
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index b8c2d8c8e36..ba1eea0475b 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.88 2003/08/11 20:46:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_relation.c,v 1.89 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1516,8 +1516,6 @@ expandRelAttrs(ParseState *pstate, RangeTblEntry *rte)
char *
get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
{
- char *attname;
-
if (attnum == InvalidAttrNumber)
return "*";
@@ -1535,13 +1533,7 @@ get_rte_attribute_name(RangeTblEntry *rte, AttrNumber attnum)
* built (which can easily happen for rules).
*/
if (rte->rtekind == RTE_RELATION)
- {
- attname = get_attname(rte->relid, attnum);
- if (attname == NULL)
- elog(ERROR, "cache lookup failed for attribute %d of relation %u",
- attnum, rte->relid);
- return attname;
- }
+ return get_relid_attribute_name(rte->relid, attnum);
/*
* Otherwise use the column name from eref. There should always be
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index a525e8795f0..5d5ee56eb14 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.111 2003/08/11 20:46:46 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.112 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -71,7 +71,7 @@ transformTargetEntry(ParseState *pstate,
type_id = exprType(expr);
type_mod = exprTypmod(expr);
- if (colname == NULL)
+ if (colname == NULL && !resjunk)
{
/*
* Generate a suitable column name for a column without any
@@ -428,14 +428,19 @@ updateTargetListEntry(ParseState *pstate,
/*
* The result of the target expression should now match the
- * destination column's type. Also, reset the resname and resno to
- * identify the destination column --- rewriter and planner depend on
- * that!
+ * destination column's type.
*/
resnode->restype = attrtype;
resnode->restypmod = attrtypmod;
- resnode->resname = colname;
+ /*
+ * Set the resno to identify the target column --- the rewriter and
+ * planner depend on this. We also set the resname to identify the
+ * target column, but this is only for debugging purposes; it should
+ * not be relied on. (In particular, it might be out of date in a
+ * stored rule.)
+ */
resnode->resno = (AttrNumber) attrno;
+ resnode->resname = colname;
}
diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c
index e8f3c185d16..d0ca89ee6ab 100644
--- a/src/backend/rewrite/rewriteHandler.c
+++ b/src/backend/rewrite/rewriteHandler.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.128 2003/08/08 21:41:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.129 2003/08/11 23:04:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -48,7 +48,8 @@ static Query *rewriteRuleAction(Query *parsetree,
static List *adjustJoinTreeList(Query *parsetree, bool removert, int rt_index);
static void rewriteTargetList(Query *parsetree, Relation target_relation);
static TargetEntry *process_matched_tle(TargetEntry *src_tle,
- TargetEntry *prior_tle);
+ TargetEntry *prior_tle,
+ const char *attrName);
static void markQueryForUpdate(Query *qry, bool skipOldNew);
static List *matchLocks(CmdType event, RuleLock *rulelocks,
int varno, Query *parsetree);
@@ -312,8 +313,7 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
continue;
/*
- * Look for targetlist entries matching this attr. We match by
- * resno, but the resname should match too.
+ * Look for targetlist entries matching this attr.
*
* Junk attributes are not candidates to be matched.
*/
@@ -324,9 +324,8 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
if (!resdom->resjunk && resdom->resno == attrno)
{
- Assert(strcmp(resdom->resname,
- NameStr(att_tup->attname)) == 0);
- new_tle = process_matched_tle(old_tle, new_tle);
+ new_tle = process_matched_tle(old_tle, new_tle,
+ NameStr(att_tup->attname));
/* keep scanning to detect multiple assignments to attr */
}
}
@@ -424,11 +423,12 @@ rewriteTargetList(Query *parsetree, Relation target_relation)
* Convert a matched TLE from the original tlist into a correct new TLE.
*
* This routine detects and handles multiple assignments to the same target
- * attribute.
+ * attribute. (The attribute name is needed only for error messages.)
*/
static TargetEntry *
process_matched_tle(TargetEntry *src_tle,
- TargetEntry *prior_tle)
+ TargetEntry *prior_tle,
+ const char *attrName)
{
Resdom *resdom = src_tle->resdom;
Node *priorbottom;
@@ -456,7 +456,7 @@ process_matched_tle(TargetEntry *src_tle,
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple assignments to same attribute \"%s\"",
- resdom->resname)));
+ attrName)));
/*
* Prior TLE could be a nest of ArrayRefs if we do this more than
@@ -470,7 +470,7 @@ process_matched_tle(TargetEntry *src_tle,
ereport(ERROR,
(errcode(ERRCODE_SYNTAX_ERROR),
errmsg("multiple assignments to same attribute \"%s\"",
- resdom->resname)));
+ attrName)));
/*
* Looks OK to nest 'em.
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 49cc73f24e4..83989292d6a 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.150 2003/08/08 21:42:09 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.151 2003/08/11 23:04:49 tgl Exp $
*
* This software is copyrighted by Jan Wieck - Hamburg.
*
@@ -207,7 +207,6 @@ static char *generate_relation_name(Oid relid);
static char *generate_function_name(Oid funcid, int nargs, Oid *argtypes);
static char *generate_operator_name(Oid operid, Oid arg1, Oid arg2);
static void print_operator_name(StringInfo buf, List *opname);
-static char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
#define only_marker(rte) ((rte)->inh ? "" : "ONLY ")
@@ -1140,7 +1139,7 @@ decompile_column_index_array(Datum column_index_array, Oid relId,
{
char *colName;
- colName = get_attname(relId, DatumGetInt16(keys[j]));
+ colName = get_relid_attribute_name(relId, DatumGetInt16(keys[j]));
if (j == 0)
appendStringInfo(buf, "%s",
@@ -1901,7 +1900,6 @@ get_basic_select_query(Query *query, deparse_context *context,
foreach(l, query->targetList)
{
TargetEntry *tle = (TargetEntry *) lfirst(l);
- bool tell_as = false;
char *colname;
if (tle->resdom->resjunk)
@@ -1924,24 +1922,30 @@ get_basic_select_query(Query *query, deparse_context *context,
else
colname = tle->resdom->resname;
- /* Check if we must say AS ... */
- if (!IsA(tle->expr, Var))
- tell_as = (strcmp(colname, "?column?") != 0);
- else
+ if (colname) /* resname could be NULL */
{
- Var *var = (Var *) (tle->expr);
- char *schemaname;
- char *refname;
- char *attname;
+ /* Check if we must say AS ... */
+ bool tell_as;
- get_names_for_var(var, context, &schemaname, &refname, &attname);
- tell_as = (attname == NULL ||
- strcmp(attname, colname) != 0);
- }
+ if (!IsA(tle->expr, Var))
+ tell_as = (strcmp(colname, "?column?") != 0);
+ else
+ {
+ Var *var = (Var *) (tle->expr);
+ char *schemaname;
+ char *refname;
+ char *attname;
- /* and do if so */
- if (tell_as)
- appendStringInfo(buf, " AS %s", quote_identifier(colname));
+ get_names_for_var(var, context,
+ &schemaname, &refname, &attname);
+ tell_as = (attname == NULL ||
+ strcmp(attname, colname) != 0);
+ }
+
+ /* and do if so */
+ if (tell_as)
+ appendStringInfo(buf, " AS %s", quote_identifier(colname));
+ }
}
/* Add the FROM clause if needed */
@@ -2151,7 +2155,9 @@ get_insert_query_def(Query *query, deparse_context *context)
appendStringInfo(buf, sep);
sep = ", ";
- appendStringInfo(buf, "%s", quote_identifier(tle->resdom->resname));
+ appendStringInfo(buf, "%s",
+ quote_identifier(get_relid_attribute_name(rte->relid,
+ tle->resdom->resno)));
}
appendStringInfo(buf, ") ");
@@ -2225,7 +2231,8 @@ get_update_query_def(Query *query, deparse_context *context)
*/
if (!tleIsArrayAssign(tle))
appendStringInfo(buf, "%s = ",
- quote_identifier(tle->resdom->resname));
+ quote_identifier(get_relid_attribute_name(rte->relid,
+ tle->resdom->resno)));
get_rule_expr((Node *) tle->expr, context, false);
}
@@ -4351,22 +4358,3 @@ print_operator_name(StringInfo buf, List *opname)
appendStringInfo(buf, "%s)", strVal(lfirst(opname)));
}
}
-
-/*
- * 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_relid_attribute_name(Oid relid, AttrNumber attnum)
-{
- char *attname;
-
- attname = get_attname(relid, attnum);
- if (attname == NULL)
- elog(ERROR, "cache lookup failed for attribute %d of relation %u",
- attnum, relid);
- return attname;
-}
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 0dfa0eb7c79..0faa097f349 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.105 2003/08/04 02:40:06 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.106 2003/08/11 23:04:49 tgl Exp $
*
* NOTES
* Eventually, the index information should go through here, too.
@@ -180,11 +180,10 @@ get_op_hash_function(Oid opno)
/*
* get_attname
- *
* Given the relation id and the attribute number,
* return the "attname" field from the attribute relation.
*
- * Note: returns a palloc'd copy of the string, or NULL if no such operator.
+ * Note: returns a palloc'd copy of the string, or NULL if no such attribute.
*/
char *
get_attname(Oid relid, AttrNumber attnum)
@@ -209,6 +208,24 @@ get_attname(Oid relid, AttrNumber attnum)
}
/*
+ * get_relid_attribute_name
+ *
+ * Same as above routine get_attname(), except that error
+ * is handled by elog() instead of returning NULL.
+ */
+char *
+get_relid_attribute_name(Oid relid, AttrNumber attnum)
+{
+ char *attname;
+
+ attname = get_attname(relid, attnum);
+ if (attname == NULL)
+ elog(ERROR, "cache lookup failed for attribute %d of relation %u",
+ attnum, relid);
+ return attname;
+}
+
+/*
* get_attnum
*
* Given the relation id and the attribute name,
@@ -1443,7 +1460,7 @@ get_typtype(Oid typid)
* get_typname
* Returns the name of a given type.
*
- * Returns a palloc'd copy of the string, or NULL if no such relation.
+ * Returns a palloc'd copy of the string, or NULL if no such type.
*
* NOTE: since type name is not unique, be wary of code that uses this
* for anything except preparing error messages.
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index ddaee15de57..2ff904510ca 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.148 2003/08/04 23:59:39 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.149 2003/08/11 23:04:49 tgl Exp $
*
*--------------------------------------------------------------------
*/
@@ -3293,7 +3293,7 @@ GetPGVariableResultDesc(const char *name)
/* need a tuple descriptor representing a single TEXT column */
tupdesc = CreateTemplateTupleDesc(1, false);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, (char *) varname,
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
TEXTOID, -1, 0, false);
}
return tupdesc;
@@ -3333,7 +3333,7 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
/* need a tuple descriptor representing a single TEXT column */
tupdesc = CreateTemplateTupleDesc(1, false);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, (char *) varname,
+ TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
TEXTOID, -1, 0, false);
/* prepare for projection of tuples */
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index c955689663b..4ecb951a902 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: tupdesc.h,v 1.40 2003/08/04 02:40:10 momjian Exp $
+ * $Id: tupdesc.h,v 1.41 2003/08/11 23:04:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -70,7 +70,7 @@ extern bool equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2);
extern void TupleDescInitEntry(TupleDesc desc,
AttrNumber attributeNumber,
- char *attributeName,
+ const char *attributeName,
Oid oidtypeid,
int32 typmod,
int attdim,
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index 49d5f494676..f6e4436d950 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -10,7 +10,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: primnodes.h,v 1.90 2003/08/08 21:42:48 momjian Exp $
+ * $Id: primnodes.h,v 1.91 2003/08/11 23:04:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -31,13 +31,29 @@
*
* Notes:
*
- * resno will normally be equal to the item's position in a targetlist,
- * but the code generally tries to avoid relying on that (eg, we avoid
- * using "nth()" rather than a search to find an item by resno).
- *
- * resname will be null if no name can easily be assigned to the column.
- * But it should never be null for user-visible columns (i.e., non-junk
- * columns in a toplevel targetlist).
+ * In a SELECT's targetlist, resno should always be equal to the item's
+ * ordinal position (counting from 1). However, in an INSERT or UPDATE
+ * targetlist, resno represents the attribute number of the destination
+ * column for the item; so there may be missing or out-of-order resnos.
+ * In an UPDATE, it is even legal to have duplicated resnos; consider
+ * UPDATE table SET arraycol[1] = ..., arraycol[2] = ..., ...
+ * The two meanings come together in the executor, because the planner
+ * transforms INSERT/UPDATE tlists into a normalized form with exactly
+ * one entry for each column of the destination table. Before that's
+ * happened, however, it is risky to assume that resno == position.
+ * Generally get_tle_by_resno() should be used rather than nth() to fetch
+ * tlist entries by resno.
+ *
+ * resname is required to represent the correct column name in non-resjunk
+ * entries of top-level SELECT targetlists, since it will be used as the
+ * column title sent to the frontend. In most other contexts it is only
+ * a debugging aid, and may be wrong or even NULL. (In particular, it may
+ * be wrong in a tlist from a stored rule, if the referenced column has been
+ * renamed by ALTER TABLE since the rule was made. Also, the planner tends
+ * to store NULL rather than look up a valid name for tlist entries in
+ * non-toplevel plan nodes.) In resjunk entries, resname should be either
+ * a specific system-generated name (such as "ctid") or NULL; anything else
+ * risks confusing ExecGetJunkAttribute!
*
* ressortgroupref is used in the representation of ORDER BY and
* GROUP BY items. Targetlist entries with ressortgroupref=0 are not
@@ -53,13 +69,16 @@
* a simple reference, these fields are zeroes.
*
* If resjunk is true then the column is a working column (such as a sort key)
- * that should be removed from the final output of the query.
+ * that should be removed from the final output of the query. Resjunk columns
+ * must have resnos that cannot duplicate any regular column's resno. Also
+ * note that there are places that assume resjunk columns come after non-junk
+ * columns.
*--------------------
*/
typedef struct Resdom
{
NodeTag type;
- AttrNumber resno; /* attribute number (1..N) */
+ AttrNumber resno; /* attribute number (see notes above) */
Oid restype; /* type of the value */
int32 restypmod; /* type-specific modifier of the value */
char *resname; /* name of the column (could be NULL) */
diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h
index c94e78eb491..4c9c073adea 100644
--- a/src/include/utils/lsyscache.h
+++ b/src/include/utils/lsyscache.h
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: lsyscache.h,v 1.79 2003/08/08 21:42:55 momjian Exp $
+ * $Id: lsyscache.h,v 1.80 2003/08/11 23:04:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,7 @@ extern bool op_requires_recheck(Oid opno, Oid opclass);
extern Oid get_opclass_member(Oid opclass, int16 strategy);
extern Oid get_op_hash_function(Oid opno);
extern char *get_attname(Oid relid, AttrNumber attnum);
+extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
extern AttrNumber get_attnum(Oid relid, const char *attname);
extern Oid get_atttype(Oid relid, AttrNumber attnum);
extern int32 get_atttypmod(Oid relid, AttrNumber attnum);