summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-08-11 23:04:50 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-08-11 23:04:50 +0000
commit302f1a86dc1125f681b9a3b3509d1be7e33b0e4f (patch)
tree9d31b15b5e5dac59aee0ce26597306a491512c31 /src/backend/parser
parent730b3a150238578505638ab2331bf569c89d8f7b (diff)
Rewriter and planner should use only resno, not resname, to identify
target columns in INSERT and UPDATE targetlists. Don't rely on resname to be accurate in ruleutils, either. This fixes bug reported by Donald Fraser, in which renaming a column referenced in a rule did not work very well.
Diffstat (limited to 'src/backend/parser')
-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
3 files changed, 21 insertions, 21 deletions
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;
}