diff options
Diffstat (limited to 'src/backend/executor/execMain.c')
-rw-r--r-- | src/backend/executor/execMain.c | 57 |
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; } } |