diff options
Diffstat (limited to 'src/backend/executor/nodeIndexonlyscan.c')
-rw-r--r-- | src/backend/executor/nodeIndexonlyscan.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c index 38078763f57..e72ebc8c3a8 100644 --- a/src/backend/executor/nodeIndexonlyscan.c +++ b/src/backend/executor/nodeIndexonlyscan.c @@ -30,6 +30,7 @@ #include "executor/nodeIndexonlyscan.h" #include "executor/nodeIndexscan.h" #include "storage/bufmgr.h" +#include "storage/predicate.h" #include "utils/memutils.h" #include "utils/rel.h" @@ -52,7 +53,6 @@ IndexOnlyNext(IndexOnlyScanState *node) ExprContext *econtext; ScanDirection direction; IndexScanDesc scandesc; - HeapTuple tuple; TupleTableSlot *slot; ItemPointer tid; @@ -78,6 +78,8 @@ IndexOnlyNext(IndexOnlyScanState *node) */ while ((tid = index_getnext_tid(scandesc, direction)) != NULL) { + HeapTuple tuple = NULL; + /* * We can skip the heap fetch if the TID references a heap page on * which all tuples are known visible to everybody. In any case, @@ -147,6 +149,18 @@ IndexOnlyNext(IndexOnlyScanState *node) } } + /* + * Predicate locks for index-only scans must be acquired at the page + * level when the heap is not accessed, since tuple-level predicate + * locks need the tuple's xmin value. If we had to visit the tuple + * anyway, then we already have the tuple-level lock and can skip the + * page lock. + */ + if (tuple == NULL) + PredicateLockPage(scandesc->heapRelation, + ItemPointerGetBlockNumber(tid), + estate->es_snapshot); + return slot; } |