From ffcf654547ef38555203e6d716f47b7065a0a87d Mon Sep 17 00:00:00 2001 From: Noah Misch Date: Tue, 16 Jul 2013 20:16:32 -0400 Subject: [PATCH] Fix systable_recheck_tuple() for MVCC scan snapshots. Since this function assumed non-MVCC snapshots, it broke when commit 568d4138c646cd7cd8a837ac244ef2caf27c6bb8 switched its one caller from SnapshotNow scans to MVCC-snapshot scans. Reviewed by Robert Haas, Tom Lane and Andres Freund. --- src/backend/access/index/genam.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c index 2bfe78a92a..60a2b4e438 100644 --- a/src/backend/access/index/genam.c +++ b/src/backend/access/index/genam.c @@ -361,6 +361,10 @@ systable_getnext(SysScanDesc sysscan) /* * systable_recheck_tuple --- recheck visibility of most-recently-fetched tuple * + * In particular, determine if this tuple would be visible to a catalog scan + * that started now. We don't handle the case of a non-MVCC scan snapshot, + * because no caller needs that yet. + * * This is useful to test whether an object was deleted while we waited to * acquire lock on it. * @@ -370,30 +374,38 @@ systable_getnext(SysScanDesc sysscan) bool systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup) { + Snapshot freshsnap; bool result; + /* + * Trust that LockBuffer() and HeapTupleSatisfiesMVCC() do not themselves + * acquire snapshots, so we need not register the snapshot. Those + * facilities are too low-level to have any business scanning tables. + */ + freshsnap = GetCatalogSnapshot(RelationGetRelid(sysscan->heap_rel)); + if (sysscan->irel) { IndexScanDesc scan = sysscan->iscan; + Assert(IsMVCCSnapshot(scan->xs_snapshot)); Assert(tup == &scan->xs_ctup); Assert(BufferIsValid(scan->xs_cbuf)); /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE); - result = HeapTupleSatisfiesVisibility(tup, scan->xs_snapshot, - scan->xs_cbuf); + result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->xs_cbuf); LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK); } else { HeapScanDesc scan = sysscan->scan; + Assert(IsMVCCSnapshot(scan->rs_snapshot)); Assert(tup == &scan->rs_ctup); Assert(BufferIsValid(scan->rs_cbuf)); /* must hold a buffer lock to call HeapTupleSatisfiesVisibility */ LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE); - result = HeapTupleSatisfiesVisibility(tup, scan->rs_snapshot, - scan->rs_cbuf); + result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->rs_cbuf); LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK); } return result; -- 2.40.0