@@ -728,9 +728,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
728
728
erm -> prti = rc -> prti ;
729
729
erm -> markType = rc -> markType ;
<
67E6
tr class="diff-line-row">730
730
erm -> noWait = rc -> noWait ;
731
- erm -> ctidAttNo = rc -> ctidAttNo ;
732
- erm -> toidAttNo = rc -> toidAttNo ;
733
- erm -> wholeAttNo = rc -> wholeAttNo ;
734
731
ItemPointerSetInvalid (& (erm -> curCtid ));
735
732
estate -> es_rowMarks = lappend (estate -> es_rowMarks , erm );
736
733
}
@@ -1334,6 +1331,71 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
1334
1331
}
1335
1332
1336
1333
1334
+ /*
1335
+ * ExecFindRowMark -- find the ExecRowMark struct for given rangetable index
1336
+ */
1337
+ ExecRowMark *
1338
+ ExecFindRowMark (EState * estate , Index rti )
1339
+ {
1340
+ ListCell * lc ;
1341
+
1342
+ foreach (lc , estate -> es_rowMarks )
1343
+ {
1344
+ ExecRowMark * erm = (ExecRowMark * ) lfirst (lc );
1345
+
1346
+ if (erm -> rti == rti )
1347
+ return erm ;
1348
+ }
1349
+ elog (ERROR , "failed to find ExecRowMark for rangetable index %u" , rti );
1350
+ return NULL ; /* keep compiler quiet */
1351
+ }
1352
+
1353
+ /*
1354
+ * ExecBuildAuxRowMark -- create an ExecAuxRowMark struct
1355
+ *
1356
+ * Inputs are the underlying ExecRowMark struct and the targetlist of the
1357
+ * input plan node (not planstate node!). We need the latter to find out
1358
+ * the column numbers of the resjunk columns.
1359
+ */
1360
+ ExecAuxRowMark *
1361
+ ExecBuildAuxRowMark (ExecRowMark * erm , List * targetlist )
1362
+ {
1363
+ ExecAuxRowMark * aerm = (ExecAuxRowMark * ) palloc0 (sizeof (ExecAuxRowMark ));
1364
+ char resname [32 ];
1365
+
1366
+ aerm -> rowmark = erm ;
1367
+
1368
+ /* Look up the resjunk columns associated w
F438
ith this rowmark */
1369
+ if (erm -> relation )
1370
+ {
1371
+ Assert (erm -> markType != ROW_MARK_COPY );
1372
+
1373
+ /* if child rel, need tableoid */
1374
+ if (erm -> rti != erm -> prti )
1375
+ {
1376
+ snprintf (resname , sizeof (resname ), "tableoid%u" , erm -> prti );
1377
+ aerm -> toidAttNo = ExecFindJunkAttributeInTlist (targetlist ,
1378
+ resname );
1379
+ }
1380
+
1381
+ /* always need ctid for real relations */
1382
+ snprintf (resname , sizeof (resname ), "ctid%u" , erm -> prti );
1383
+ aerm -> ctidAttNo = ExecFindJunkAttributeInTlist (targetlist ,
1384
+ resname );
1385
+ }
1386
+ else
1387
+ {
1388
+ Assert (erm -> markType == ROW_MARK_COPY );
1389
+
1390
+ snprintf (resname , sizeof (resname ), "wholerow%u" , erm -> prti );
1391
+ aerm -> wholeAttNo = ExecFindJunkAttributeInTlist (targetlist ,
1392
+ resname );
1393
+ }
1394
+
1395
+ return aerm ;
1396
+ }
1397
+
1398
+
1337
1399
/*
1338
1400
* EvalPlanQual logic --- recheck modified tuple(s) to see if we want to
1339
1401
* process the updated version under READ COMMITTED rules.
@@ -1624,19 +1686,21 @@ EvalPlanQualFetch(EState *estate, Relation relation, int lockmode,
1624
1686
/*
1625
1687
* EvalPlanQualInit -- initialize during creation of a plan state node
1626
1688
* that might need to invoke EPQ processing.
1627
- * Note: subplan can be NULL if it will be set later with EvalPlanQualSetPlan.
1689
+ *
1690
+ * Note: subplan/auxrowmarks can be NULL/NIL if they will be set later
1691
+ * with EvalPlanQualSetPlan.
1628
1692
*/
1629
1693
void
1630
1694
EvalPlanQualInit (EPQState * epqstate , EState * estate ,
1631
- Plan * subplan , int epqParam )
1695
+ Plan * subplan , List * auxrowmarks , int epqParam )
1632
1696
{
1633
1697
/* Mark the EPQ state inactive */
1634
1698
epqstate -> estate = NULL ;
1635
1699
epqstate -> planstate = NULL ;
1636
1700
epqstate -> origslot = NULL ;
1637
1701
/* ... and remember data that EvalPlanQualBegin will need */
1638
1702
epqstate -> plan = subplan ;
1639
- epqstate -> rowMarks = NIL ;
1703
+ epqstate -> arowMarks = auxrowmarks ;
1640
1704
epqstate -> epqParam = epqParam ;
1641
1705
}
1642
1706
@@ -1646,25 +1710,14 @@ EvalPlanQualInit(EPQState *epqstate, EState *estate,
1646
1710
* We need this so that ModifyTuple can deal with multiple subplans.
1647
1711
*/
1648
1712
void
1649
- EvalPlanQualSetPlan (EPQState * epqstate , Plan * subplan )
1713
+ EvalPlanQualSetPlan (EPQState * epqstate , Plan * subplan , List * auxrowmarks )
1650
1714
{
1651
1715
/* If we have a live EPQ query, shut it down */
1652
1716
EvalPlanQualEnd (epqstate );
1653
1717
/* And set/change the plan pointer */
1654
1718
epqstate -> plan = subplan ;
1655
- }
1656
-
1657
- /*
1658
- * EvalPlanQualAddRowMark -- add an ExecRowMark that EPQ needs to handle.
1659
- *
1660
- * Currently, only non-locking RowMarks are supported.
1661
- */
1662
- void
1663
- EvalPlanQualAddRowMark (EPQState * epqstate , ExecRowMark * erm )
1664
- {
1665
- if (RowMarkRequiresRowShareLock (erm -> markType ))
1666
- elog (ERROR , "EvalPlanQual doesn't support locking rowmarks" );
1667
- epqstate -> rowMarks = lappend (epqstate -> rowMarks , erm );
1719
+ /* The rowmarks depend on the plan, too */
1720
+ epqstate -> arowMarks = auxrowmarks ;
1668
1721
}
1669
1722
1670
1723
/*
@@ -1714,13 +1767,17 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
1714
1767
1715
1768
Assert (epqstate -> origslot != NULL );
1716
1769
1717
- foreach (l , epqstate -> rowMarks )
1770
+ foreach (l , epqstate -> arowMarks )
1718
1771
{
1719
- ExecRowMark * erm = (ExecRowMark * ) lfirst (l );
1772
+ ExecAuxRowMark * aerm = (ExecAuxRowMark * ) lfirst (l );
1773
+ ExecRowMark * erm = aerm -> rowmark ;
1720
1774
Datum datum ;
1721
1775
bool isNull ;
1722
1776
HeapTupleData tuple ;
1723
1777
1778
+ if (RowMarkRequiresRowShareLock (erm -> markType ))
1779
+ elog (ERROR , "EvalPlanQual doesn't support locking rowmarks" );
1780
+
1724
1781
/* clear any leftover test tuple for this rel */
1725
1782
EvalPlanQualSetTuple (epqstate , erm -> rti , NULL );
1726
1783
@@ -1736,7 +1793,7 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
1736
1793
Oid tableoid ;
1737
1794
1738
1795
datum = ExecGetJunkAttribute (epqstate -> origslot ,
1739
- erm -> toidAttNo ,
1796
+ aerm -> toidAttNo ,
1740
1797
& isNull );
1741
1798
/* non-locked rels could be on the inside of outer joins */
1742
1799
if (isNull )
@@ -1752,7 +1809,7 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
1752
1809
1753
1810
/* fetch the tuple's ctid */
1754
1811
datum = ExecGetJunkAttribute (epqstate -> origslot ,
1755
- erm -> ctidAttNo ,
1812
+ aerm -> ctidAttNo ,
1756
1813
& isNull );
1757
1814
/* non-locked rels could be on the inside of outer joins */
1758
1815
if (isNull )
@@ -1777,7 +1834,7 @@ EvalPlanQualFetchRowMarks(EPQState *epqstate)
1777
1834
1778
1835
/* fetch the whole-row Var for the relation */
1779
1836
datum = ExecGetJunkAttribute (epqstate -> origslot ,
1780
- erm -> wholeAttNo ,
1837
+ aerm-> wholeAttNo ,
1781
1838
& isNull );
1782
1839
/* non-locked rels could be on the inside of outer joins */
1783
1840
if (isNull )
0 commit comments