summaryrefslogtreecommitdiff
path: root/src/backend/access/index/genam.c
diff options
context:
space:
mode:
authorNoah Misch <noah@leadboat.com>2013-07-16 20:16:32 -0400
committerNoah Misch <noah@leadboat.com>2013-07-16 20:16:32 -0400
commitffcf654547ef38555203e6d716f47b7065a0a87d (patch)
treec5eddd43fbc8ba7a216d031ec71cb248af3d1029 /src/backend/access/index/genam.c
parentb560ec1b0d7b910ce13edc51ffaafaca72136e3b (diff)
downloadpostgresql-ffcf654547ef38555203e6d716f47b7065a0a87d.tar.gz
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.
Diffstat (limited to 'src/backend/access/index/genam.c')
-rw-r--r--src/backend/access/index/genam.c20
1 files 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;