aboutsummaryrefslogtreecommitdiff
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.c57
1 files changed, 47 insertions, 10 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 2ddab234b0a..1d1bd6f6371 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.156 2003/09/25 06:57:56 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.157 2003/10/01 21:30:52 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1207,14 +1207,23 @@ simple_heap_insert(Relation relation, HeapTuple tup)
* NB: do not call this directly unless you are prepared to deal with
* concurrent-update conditions. Use simple_heap_delete instead.
*
+ * relation - table to be modified
+ * tid - TID of tuple to be deleted
+ * ctid - output parameter, used only for failure case (see below)
+ * cid - delete command ID to use in verifying tuple visibility
+ * crosscheck - if not SnapshotAny, also check tuple against this
+ * wait - true if should wait for any conflicting update to commit/abort
+ *
* Normal, successful return value is HeapTupleMayBeUpdated, which
* actually means we did delete it. Failure return codes are
* HeapTupleSelfUpdated, HeapTupleUpdated, or HeapTupleBeingUpdated
- * (the last only possible if wait == false).
+ * (the last only possible if wait == false). On a failure return,
+ * *ctid is set to the ctid link of the target tuple (possibly a later
+ * version of the row).
*/
int
heap_delete(Relation relation, ItemPointer tid,
- ItemPointer ctid, CommandId cid, bool wait)
+ ItemPointer ctid, CommandId cid, Snapshot crosscheck, bool wait)
{
ItemId lp;
HeapTupleData tp;
@@ -1240,7 +1249,7 @@ heap_delete(Relation relation, ItemPointer tid,
tp.t_tableOid = relation->rd_id;
l1:
- result = HeapTupleSatisfiesUpdate(&tp, cid);
+ result = HeapTupleSatisfiesUpdate(tp.t_data, cid);
if (result == HeapTupleInvisible)
{
@@ -1278,6 +1287,14 @@ l1:
else
result = HeapTupleUpdated;
}
+
+ if (crosscheck != SnapshotAny && result == HeapTupleMayBeUpdated)
+ {
+ /* Perform additional check for serializable RI updates */
+ if (!HeapTupleSatisfiesSnapshot(tp.t_data, crosscheck))
+ result = HeapTupleUpdated;
+ }
+
if (result != HeapTupleMayBeUpdated)
{
Assert(result == HeapTupleSelfUpdated ||
@@ -1378,7 +1395,7 @@ simple_heap_delete(Relation relation, ItemPointer tid)
result = heap_delete(relation, tid,
&ctid,
- GetCurrentCommandId(),
+ GetCurrentCommandId(), SnapshotAny,
true /* wait for commit */);
switch (result)
{
@@ -1407,14 +1424,26 @@ simple_heap_delete(Relation relation, ItemPointer tid)
* NB: do not call this directly unless you are prepared to deal with
* concurrent-update conditions. Use simple_heap_update instead.
*
+ * relation - table to be modified
+ * otid - TID of old tuple to be replaced
+ * newtup - newly constructed tuple data to store
+ * ctid - output parameter, used only for failure case (see below)
+ * cid - update command ID to use in verifying old tuple visibility
+ * crosscheck - if not SnapshotAny, also check old tuple against this
+ * wait - true if should wait for any conflicting update to commit/abort
+ *
* Normal, successful return value is HeapTupleMayBeUpdated, which
* actually means we *did* update it. Failure return codes are
* HeapTupleSelfUpdated, HeapTupleUpdated, or HeapTupleBeingUpdated
- * (the last only possible if wait == false).
+ * (the last only possible if wait == false). On a failure return,
+ * *ctid is set to the ctid link of the old tuple (possibly a later
+ * version of the row).
+ * On success, newtup->t_self is set to the TID where the new tuple
+ * was inserted.
*/
int
heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
- ItemPointer ctid, CommandId cid, bool wait)
+ ItemPointer ctid, CommandId cid, Snapshot crosscheck, bool wait)
{
ItemId lp;
HeapTupleData oldtup;
@@ -1450,7 +1479,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
*/
l2:
- result = HeapTupleSatisfiesUpdate(&oldtup, cid);
+ result = HeapTupleSatisfiesUpdate(oldtup.t_data, cid);
if (result == HeapTupleInvisible)
{
@@ -1488,6 +1517,14 @@ l2:
else
result = HeapTupleUpdated;
}
+
+ if (crosscheck != SnapshotAny && result == HeapTupleMayBeUpdated)
+ {
+ /* Perform additional check for serializable RI updates */
+ if (!HeapTupleSatisfiesSnapshot(oldtup.t_data, crosscheck))
+ result = HeapTupleUpdated;
+ }
+
if (result != HeapTupleMayBeUpdated)
{
Assert(result == HeapTupleSelfUpdated ||
@@ -1718,7 +1755,7 @@ simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
result = heap_update(relation, otid, tup,
&ctid,
- GetCurrentCommandId(),
+ GetCurrentCommandId(), SnapshotAny,
true /* wait for commit */);
switch (result)
{
@@ -1767,7 +1804,7 @@ heap_mark4update(Relation relation, HeapTuple tuple, Buffer *buffer,
tuple->t_len = ItemIdGetLength(lp);
l3:
- result = HeapTupleSatisfiesUpdate(tuple, cid);
+ result = HeapTupleSatisfiesUpdate(tuple->t_data, cid);
if (result == HeapTupleInvisible)
{