aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/execMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r--src/backend/executor/execMain.c64
1 files changed, 44 insertions, 20 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 5e5ca085ba4..6db354cd4f9 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -26,7 +26,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.280 2006/10/04 00:29:52 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.281 2006/12/04 02:06:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -567,7 +567,9 @@ InitPlan(QueryDesc *queryDesc, int eflags)
}
/*
- * Have to lock relations selected FOR UPDATE/FOR SHARE
+ * Have to lock relations selected FOR UPDATE/FOR SHARE before we
+ * initialize the plan tree, else we'd be doing a lock upgrade.
+ * While we are at it, build the ExecRowMark list.
*/
estate->es_rowMarks = NIL;
foreach(l, parseTree->rowMarks)
@@ -583,7 +585,8 @@ InitPlan(QueryDesc *queryDesc, int eflags)
erm->rti = rc->rti;
erm->forUpdate = rc->forUpdate;
erm->noWait = rc->noWait;
- snprintf(erm->resname, sizeof(erm->resname), "ctid%u", rc->rti);
+ /* We'll set up ctidAttno below */
+ erm->ctidAttNo = InvalidAttrNumber;
estate->es_rowMarks = lappend(estate->es_rowMarks, erm);
}
@@ -703,6 +706,16 @@ InitPlan(QueryDesc *queryDesc, int eflags)
j = ExecInitJunkFilter(subplan->plan->targetlist,
resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
ExecAllocTableSlot(estate->es_tupleTable));
+ /*
+ * Since it must be UPDATE/DELETE, there had better be
+ * a "ctid" junk attribute in the tlist ... but ctid could
+ * be at a different resno for each result relation.
+ * We look up the ctid resnos now and save them in the
+ * junkfilters.
+ */
+ j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
+ if (!AttributeNumberIsValid(j->jf_junkAttNo))
+ elog(ERROR, "could not find junk ctid column");
resultRelInfo->ri_junkFilter = j;
resultRelInfo++;
}
@@ -726,9 +739,30 @@ InitPlan(QueryDesc *queryDesc, int eflags)
if (estate->es_result_relation_info)
estate->es_result_relation_info->ri_junkFilter = j;
- /* For SELECT, want to return the cleaned tuple type */
if (operation == CMD_SELECT)
+ {
+ /* For SELECT, want to return the cleaned tuple type */
tupType = j->jf_cleanTupType;
+ /* For SELECT FOR UPDATE/SHARE, find the ctid attrs now */
+ foreach(l, estate->es_rowMarks)
+ {
+ ExecRowMark *erm = (ExecRowMark *) lfirst(l);
+ char resname[32];
+
+ snprintf(resname, sizeof(resname), "ctid%u", erm->rti);
+ erm->ctidAttNo = ExecFindJunkAttribute(j, resname);
+ if (!AttributeNumberIsValid(erm->ctidAttNo))
+ elog(ERROR, "could not find junk \"%s\" column",
+ resname);
+ }
+ }
+ else if (operation == CMD_UPDATE || operation == CMD_DELETE)
+ {
+ /* For UPDATE/DELETE, find the ctid junk attr now */
+ j->jf_junkAttNo = ExecFindJunkAttribute(j, "ctid");
+ if (!AttributeNumberIsValid(j->jf_junkAttNo))
+ elog(ERROR, "could not find junk ctid column");
+ }
}
}
else
@@ -1111,13 +1145,8 @@ lnext: ;
*/
if (operation == CMD_UPDATE || operation == CMD_DELETE)
{
- if (!ExecGetJunkAttribute(junkfilter,
- slot,
- "ctid",
- &datum,
- &isNull))
- elog(ERROR, "could not find junk ctid column");
-
+ datum = ExecGetJunkAttribute(slot, junkfilter->jf_junkAttNo,
+ &isNull);
/* shouldn't ever get a null result... */
if (isNull)
elog(ERROR, "ctid is NULL");
@@ -1146,17 +1175,12 @@ lnext: ;
LockTupleMode lockmode;
HTSU_Result test;
- if (!ExecGetJunkAttribute(junkfilter,
- slot,
- erm->resname,
- &datum,
- &isNull))
- elog(ERROR, "could not find junk \"%s\" column",
- erm->resname);
-
+ datum = ExecGetJunkAttribute(slot,
+ erm->ctidAttNo,
+ &isNull);
/* shouldn't ever get a null result... */
if (isNull)
- elog(ERROR, "\"%s\" is NULL", erm->resname);
+ elog(ERROR, "ctid is NULL");
tuple.t_self = *((ItemPointer) DatumGetPointer(datum));