mirror of
https://github.com/postgres/postgres.git
synced 2025-05-23 00:02:38 -04:00
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.
This commit is contained in:
parent
b560ec1b0d
commit
ffcf654547
@ -361,6 +361,10 @@ systable_getnext(SysScanDesc sysscan)
|
|||||||
/*
|
/*
|
||||||
* systable_recheck_tuple --- recheck visibility of most-recently-fetched tuple
|
* 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
|
* This is useful to test whether an object was deleted while we waited to
|
||||||
* acquire lock on it.
|
* acquire lock on it.
|
||||||
*
|
*
|
||||||
@ -370,30 +374,38 @@ systable_getnext(SysScanDesc sysscan)
|
|||||||
bool
|
bool
|
||||||
systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
|
systable_recheck_tuple(SysScanDesc sysscan, HeapTuple tup)
|
||||||
{
|
{
|
||||||
|
Snapshot freshsnap;
|
||||||
bool result;
|
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)
|
if (sysscan->irel)
|
||||||
{
|
{
|
||||||
IndexScanDesc scan = sysscan->iscan;
|
IndexScanDesc scan = sysscan->iscan;
|
||||||
|
|
||||||
|
Assert(IsMVCCSnapshot(scan->xs_snapshot));
|
||||||
Assert(tup == &scan->xs_ctup);
|
Assert(tup == &scan->xs_ctup);
|
||||||
Assert(BufferIsValid(scan->xs_cbuf));
|
Assert(BufferIsValid(scan->xs_cbuf));
|
||||||
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
|
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
|
||||||
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
|
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);
|
||||||
result = HeapTupleSatisfiesVisibility(tup, scan->xs_snapshot,
|
result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->xs_cbuf);
|
||||||
scan->xs_cbuf);
|
|
||||||
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
|
LockBuffer(scan->xs_cbuf, BUFFER_LOCK_UNLOCK);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
HeapScanDesc scan = sysscan->scan;
|
HeapScanDesc scan = sysscan->scan;
|
||||||
|
|
||||||
|
Assert(IsMVCCSnapshot(scan->rs_snapshot));
|
||||||
Assert(tup == &scan->rs_ctup);
|
Assert(tup == &scan->rs_ctup);
|
||||||
Assert(BufferIsValid(scan->rs_cbuf));
|
Assert(BufferIsValid(scan->rs_cbuf));
|
||||||
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
|
/* must hold a buffer lock to call HeapTupleSatisfiesVisibility */
|
||||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);
|
||||||
result = HeapTupleSatisfiesVisibility(tup, scan->rs_snapshot,
|
result = HeapTupleSatisfiesVisibility(tup, freshsnap, scan->rs_cbuf);
|
||||||
scan->rs_cbuf);
|
|
||||||
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
|
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user