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.c87
1 files changed, 82 insertions, 5 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index c8436b709d1..9f81057d615 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.108 2001/01/15 05:29:19 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.109 2001/01/23 04:32:20 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -1423,6 +1423,9 @@ heap_insert(Relation relation, HeapTuple tup)
/*
* heap_delete - delete a tuple
+ *
+ * NB: do not call this directly unless you are prepared to deal with
+ * concurrent-update conditions. Use simple_heap_delete instead.
*/
int
heap_delete(Relation relation, ItemPointer tid, ItemPointer ctid)
@@ -1496,8 +1499,7 @@ l1:
if (result != HeapTupleMayBeUpdated)
{
Assert(result == HeapTupleSelfUpdated || result == HeapTupleUpdated);
- if (ctid != NULL)
- *ctid = tp.t_data->t_ctid;
+ *ctid = tp.t_data->t_ctid;
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer);
return result;
@@ -1561,7 +1563,47 @@ l1:
}
/*
+ * simple_heap_delete - delete a tuple
+ *
+ * This routine may be used to delete a tuple when concurrent updates of
+ * the target tuple are not expected (for example, because we have a lock
+ * on the relation associated with the tuple). Any failure is reported
+ * via elog().
+ */
+void
+simple_heap_delete(Relation relation, ItemPointer tid)
+{
+ ItemPointerData ctid;
+ int result;
+
+ result = heap_delete(relation, tid, &ctid);
+ switch (result)
+ {
+ case HeapTupleSelfUpdated:
+ /* Tuple was already updated in current command? */
+ elog(ERROR, "simple_heap_delete: tuple already updated by self");
+ break;
+
+ case HeapTupleMayBeUpdated:
+ /* done successfully */
+ break;
+
+ case HeapTupleUpdated:
+ elog(ERROR, "simple_heap_delete: tuple concurrently updated");
+ break;
+
+ default:
+ elog(ERROR, "Unknown status %u from heap_delete", result);
+ break;
+ }
+
+}
+
+/*
* heap_update - replace a tuple
+ *
+ * NB: do not call this directly unless you are prepared to deal with
+ * concurrent-update conditions. Use simple_heap_update instead.
*/
int
heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
@@ -1643,8 +1685,7 @@ l2:
if (result != HeapTupleMayBeUpdated)
{
Assert(result == HeapTupleSelfUpdated || result == HeapTupleUpdated);
- if (ctid != NULL)
- *ctid = oldtup.t_data->t_ctid;
+ *ctid = oldtup.t_data->t_ctid;
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer);
return result;
@@ -1784,6 +1825,42 @@ l2:
}
/*
+ * simple_heap_update - replace a tuple
+ *
+ * This routine may be used to update a tuple when concurrent updates of
+ * the target tuple are not expected (for example, because we have a lock
+ * on the relation associated with the tuple). Any failure is reported
+ * via elog().
+ */
+void
+simple_heap_update(Relation relation, ItemPointer otid, HeapTuple tup)
+{
+ ItemPointerData ctid;
+ int result;
+
+ result = heap_update(relation, otid, tup, &ctid);
+ switch (result)
+ {
+ case HeapTupleSelfUpdated:
+ /* Tuple was already updated in current command? */
+ elog(ERROR, "simple_heap_update: tuple already updated by self");
+ break;
+
+ case HeapTupleMayBeUpdated:
+ /* done successfully */
+ break;
+
+ case HeapTupleUpdated:
+ elog(ERROR, "simple_heap_update: tuple concurrently updated");
+ break;
+
+ default:
+ elog(ERROR, "Unknown status %u from heap_update", result);
+ break;
+ }
+}
+
+/*
* heap_mark4update - mark a tuple for update
*/
int