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.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 350381ad4b5..634ca69b4d1 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.315 2008/11/06 20:51:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.316 2008/11/15 19:43:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -590,18 +590,25 @@ InitPlan(QueryDesc *queryDesc, int eflags)
foreach(l, plannedstmt->rowMarks)
{
RowMarkClause *rc = (RowMarkClause *) lfirst(l);
- Oid relid = getrelid(rc->rti, rangeTable);
+ Oid relid;
Relation relation;
ExecRowMark *erm;
+ /* ignore "parent" rowmarks; they are irrelevant at runtime */
+ if (rc->isParent)
+ continue;
+
+ relid = getrelid(rc->rti, rangeTable);
relation = heap_open(relid, RowShareLock);
erm = (ExecRowMark *) palloc(sizeof(ExecRowMark));
erm->relation = relation;
erm->rti = rc->rti;
+ erm->prti = rc->prti;
erm->forUpdate = rc->forUpdate;
erm->noWait = rc->noWait;
- /* We'll set up ctidAttno below */
+ /* We'll locate the junk attrs below */
erm->ctidAttNo = InvalidAttrNumber;
+ erm->toidAttNo = InvalidAttrNumber;
estate->es_rowMarks = lappend(estate->es_rowMarks, erm);
}
@@ -822,17 +829,29 @@ InitPlan(QueryDesc *queryDesc, int eflags)
elog(ERROR, "could not find junk ctid column");
}
- /* For SELECT FOR UPDATE/SHARE, find the ctid attrs now */
+ /* For SELECT FOR UPDATE/SHARE, find the junk attrs now */
foreach(l, estate->es_rowMarks)
{
ExecRowMark *erm = (ExecRowMark *) lfirst(l);
char resname[32];
- snprintf(resname, sizeof(resname), "ctid%u", erm->rti);
+ /* always need the ctid */
+ snprintf(resname, sizeof(resname), "ctid%u",
+ erm->prti);
erm->ctidAttNo = ExecFindJunkAttribute(j, resname);
if (!AttributeNumberIsValid(erm->ctidAttNo))
elog(ERROR, "could not find junk \"%s\" column",
resname);
+ /* if child relation, need tableoid too */
+ if (erm->rti != erm->prti)
+ {
+ snprintf(resname, sizeof(resname), "tableoid%u",
+ erm->prti);
+ erm->toidAttNo = ExecFindJunkAttribute(j, resname);
+ if (!AttributeNumberIsValid(erm->toidAttNo))
+ elog(ERROR, "could not find junk \"%s\" column",
+ resname);
+ }
}
}
}
@@ -1383,13 +1402,33 @@ lnext: ;
LockTupleMode lockmode;
HTSU_Result test;
+ /* if child rel, must check whether it produced this row */
+ if (erm->rti != erm->prti)
+ {
+ Oid tableoid;
+
+ datum = ExecGetJunkAttribute(slot,
+ erm->toidAttNo,
+ &isNull);
+ /* shouldn't ever get a null result... */
+ if (isNull)
+ elog(ERROR, "tableoid is NULL");
+ tableoid = DatumGetObjectId(datum);
+
+ if (tableoid != RelationGetRelid(erm->relation))
+ {
+ /* this child is inactive right now */
+ continue;
+ }
+ }
+
+ /* okay, fetch the tuple by ctid */
datum = ExecGetJunkAttribute(slot,
erm->ctidAttNo,
&isNull);
/* shouldn't ever get a null result... */
if (isNull)
elog(ERROR, "ctid is NULL");
-
tuple.t_self = *((ItemPointer) DatumGetPointer(datum));
if (erm->forUpdate)
@@ -2122,9 +2161,11 @@ EvalPlanQual(EState *estate, Index rti,
relation = NULL;
foreach(l, estate->es_rowMarks)
{
- if (((ExecRowMark *) lfirst(l))->rti == rti)
+ ExecRowMark *erm = lfirst(l);
+
+ if (erm->rti == rti)
{
- relation = ((ExecRowMark *) lfirst(l))->relation;
+ relation = erm->relation;
break;
}
}