|
26 | 26 | *
|
27 | 27 | *
|
28 | 28 | * IDENTIFICATION
|
29 |
| - * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.315 2008/11/06 20:51:14 tgl Exp $ |
| 29 | + * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.316 2008/11/15 19:43:45 tgl Exp $ |
30 | 30 | *
|
31 | 31 | *-------------------------------------------------------------------------
|
32 | 32 | */
|
@@ -590,18 +590,25 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
590 | 590 | foreach(l,plannedstmt->rowMarks)
|
591 | 591 | {
|
592 | 592 | RowMarkClause*rc= (RowMarkClause*)lfirst(l);
|
593 |
| -Oidrelid=getrelid(rc->rti,rangeTable); |
| 593 | +Oidrelid; |
594 | 594 | Relationrelation;
|
595 | 595 | ExecRowMark*erm;
|
596 | 596 |
|
| 597 | +/* ignore "parent" rowmarks; they are irrelevant at runtime */ |
| 598 | +if (rc->isParent) |
| 599 | +continue; |
| 600 | + |
| 601 | +relid=getrelid(rc->rti,rangeTable); |
597 | 602 | relation=heap_open(relid,RowShareLock);
|
598 | 603 | erm= (ExecRowMark*)palloc(sizeof(ExecRowMark));
|
599 | 604 | erm->relation=relation;
|
600 | 605 | erm->rti=rc->rti;
|
| 606 | +erm->prti=rc->prti; |
601 | 607 | erm->forUpdate=rc->forUpdate;
|
602 | 608 | erm->noWait=rc->noWait;
|
603 |
| -/* We'llset up ctidAttno below */ |
| 609 | +/* We'lllocate the junk attrs below */ |
604 | 610 | erm->ctidAttNo=InvalidAttrNumber;
|
| 611 | +erm->toidAttNo=InvalidAttrNumber; |
605 | 612 | estate->es_rowMarks=lappend(estate->es_rowMarks,erm);
|
606 | 613 | }
|
607 | 614 |
|
@@ -822,17 +829,29 @@ InitPlan(QueryDesc *queryDesc, int eflags)
|
822 | 829 | elog(ERROR,"could not find junk ctid column");
|
823 | 830 | }
|
824 | 831 |
|
825 |
| -/* For SELECT FOR UPDATE/SHARE, find thectid attrs now */ |
| 832 | +/* For SELECT FOR UPDATE/SHARE, find thejunk attrs now */ |
826 | 833 | foreach(l,estate->es_rowMarks)
|
827 | 834 | {
|
828 | 835 | ExecRowMark*erm= (ExecRowMark*)lfirst(l);
|
829 | 836 | charresname[32];
|
830 | 837 |
|
831 |
| -snprintf(resname,sizeof(resname),"ctid%u",erm->rti); |
| 838 | +/* always need the ctid */ |
| 839 | +snprintf(resname,sizeof(resname),"ctid%u", |
| 840 | +erm->prti); |
832 | 841 | erm->ctidAttNo=ExecFindJunkAttribute(j,resname);
|
833 | 842 | if (!AttributeNumberIsValid(erm->ctidAttNo))
|
834 | 843 | elog(ERROR,"could not find junk \"%s\" column",
|
835 | 844 | resname);
|
| 845 | +/* if child relation, need tableoid too */ |
| 846 | +if (erm->rti!=erm->prti) |
| 847 | +{ |
| 848 | +snprintf(resname,sizeof(resname),"tableoid%u", |
| 849 | +erm->prti); |
| 850 | +erm->toidAttNo=ExecFindJunkAttribute(j,resname); |
| 851 | +if (!AttributeNumberIsValid(erm->toidAttNo)) |
| 852 | +elog(ERROR,"could not find junk \"%s\" column", |
| 853 | +resname); |
| 854 | +} |
836 | 855 | }
|
837 | 856 | }
|
838 | 857 | }
|
@@ -1383,13 +1402,33 @@ lnext:;
|
1383 | 1402 | LockTupleModelockmode;
|
1384 | 1403 | HTSU_Resulttest;
|
1385 | 1404 |
|
| 1405 | +/* if child rel, must check whether it produced this row */ |
| 1406 | +if (erm->rti!=erm->prti) |
| 1407 | +{ |
| 1408 | +Oidtableoid; |
| 1409 | + |
| 1410 | +datum=ExecGetJunkAttribute(slot, |
| 1411 | +erm->toidAttNo, |
| 1412 | +&isNull); |
| 1413 | +/* shouldn't ever get a null result... */ |
| 1414 | +if (isNull) |
| 1415 | +elog(ERROR,"tableoid is NULL"); |
| 1416 | +tableoid=DatumGetObjectId(datum); |
| 1417 | + |
| 1418 | +if (tableoid!=RelationGetRelid(erm->relation)) |
| 1419 | +{ |
| 1420 | +/* this child is inactive right now */ |
| 1421 | +continue; |
| 1422 | +} |
| 1423 | +} |
| 1424 | + |
| 1425 | +/* okay, fetch the tuple by ctid */ |
1386 | 1426 | datum=ExecGetJunkAttribute(slot,
|
1387 | 1427 | erm->ctidAttNo,
|
1388 | 1428 | &isNull);
|
1389 | 1429 | /* shouldn't ever get a null result... */
|
1390 | 1430 | if (isNull)
|
1391 | 1431 | elog(ERROR,"ctid is NULL");
|
1392 |
| - |
1393 | 1432 | tuple.t_self=*((ItemPointer)DatumGetPointer(datum));
|
1394 | 1433 |
|
1395 | 1434 | if (erm->forUpdate)
|
@@ -2122,9 +2161,11 @@ EvalPlanQual(EState *estate, Index rti,
|
2122 | 2161 | relation=NULL;
|
2123 | 2162 | foreach(l,estate->es_rowMarks)
|
2124 | 2163 | {
|
2125 |
| -if (((ExecRowMark*)lfirst(l))->rti==rti) |
| 2164 | +ExecRowMark*erm=lfirst(l); |
| 2165 | + |
| 2166 | +if (erm->rti==rti) |
2126 | 2167 | {
|
2127 |
| -relation=((ExecRowMark*)lfirst(l))->relation; |
| 2168 | +relation=erm->relation; |
2128 | 2169 | break;
|
2129 | 2170 | }
|
2130 | 2171 | }
|
|