summaryrefslogtreecommitdiff
path: root/src/backend/access/heap/heapam.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/heap/heapam.c')
-rw-r--r--src/backend/access/heap/heapam.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index b947c11f7d8..450bb15ff8d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -479,8 +479,6 @@ heapgettup(HeapScanDesc scan,
if (valid)
{
- if (!scan->rs_relpredicatelocked)
- PredicateLockTuple(scan->rs_rd, tuple, snapshot);
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_UNLOCK);
return;
}
@@ -748,16 +746,12 @@ heapgettup_pagemode(HeapScanDesc scan,
nkeys, key, valid);
if (valid)
{
- if (!scan->rs_relpredicatelocked)
- PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
scan->rs_cindex = lineindex;
return;
}
}
else
{
- if (!scan->rs_relpredicatelocked)
- PredicateLockTuple(scan->rs_rd, tuple, scan->rs_snapshot);
scan->rs_cindex = lineindex;
return;
}
@@ -1224,13 +1218,26 @@ heap_beginscan_internal(Relation relation, Snapshot snapshot,
scan->rs_strategy = NULL; /* set in initscan */
scan->rs_allow_strat = allow_strat;
scan->rs_allow_sync = allow_sync;
- scan->rs_relpredicatelocked = false;
/*
* we can use page-at-a-time mode if it's an MVCC-safe snapshot
*/
scan->rs_pageatatime = IsMVCCSnapshot(snapshot);
+ /*
+ * For a seqscan in a serializable transaction, acquire a predicate lock
+ * on the entire relation. This is required not only to lock all the
+ * matching tuples, but also to conflict with new insertions into the
+ * table. In an indexscan, we take page locks on the index pages covering
+ * the range specified in the scan qual, but in a heap scan there is
+ * nothing more fine-grained to lock. A bitmap scan is a different story,
+ * there we have already scanned the index and locked the index pages
+ * covering the predicate. But in that case we still have to lock any
+ * matching heap tuples.
+ */
+ if (!is_bitmapscan)
+ PredicateLockRelation(relation, snapshot);
+
/* we only need to set this up once */
scan->rs_ctup.t_tableOid = RelationGetRelid(relation);