46
46
#include "utils/builtins.h"
47
47
#include "utils/rel.h"
48
48
49
- static TM_Result heapam_tuple_lock (Relation relation , ItemPointer tid ,
50
- Snapshot snapshot , TupleTableSlot * slot ,
51
- CommandId cid , LockTupleMode mode ,
52
- LockWaitPolicy wait_policy , uint8 flags ,
53
- TM_FailureData * tmfd );
54
49
static void reform_and_rewrite_tuple (HeapTuple tuple ,
55
50
Relation OldHeap , Relation NewHeap ,
56
51
Datum * values , bool * isnull , RewriteState rwstate );
@@ -306,55 +301,23 @@ heapam_tuple_complete_speculative(Relation relation, TupleTableSlot *slot,
306
301
307
302
static TM_Result
308
303
heapam_tuple_delete (Relation relation , ItemPointer tid , CommandId cid ,
309
- Snapshot snapshot , Snapshot crosscheck , int options ,
310
- TM_FailureData * tmfd , bool changingPart ,
311
- TupleTableSlot * oldSlot )
304
+ Snapshot snapshot , Snapshot crosscheck , bool wait ,
305
+ TM_FailureData * tmfd , bool changingPart )
312
306
{
313
- TM_Result result ;
314
-
315
307
/*
316
308
* Currently Deleting of index tuples are handled at vacuum, in case if
317
309
* the storage itself is cleaning the dead tuples by itself, it is the
318
310
* time to call the index tuple deletion also.
319
311
*/
320
- result = heap_delete (relation , tid , cid , crosscheck , options ,
321
- tmfd , changingPart , oldSlot );
322
-
323
- /*
324
- * If the tuple has been concurrently updated, then get the lock on it.
325
- * (Do only if caller asked for this by setting the
326
- * TABLE_MODIFY_LOCK_UPDATED option) With the lock held retry of the
327
- * delete should succeed even if there are more concurrent update
328
- * attempts.
329
- */
330
- if (result == TM_Updated && (options & TABLE_MODIFY_LOCK_UPDATED ))
331
- {
332
- /*
333
- * heapam_tuple_lock() will take advantage of tuple loaded into
334
- * oldSlot by heap_delete().
335
- */
336
- result = heapam_tuple_lock (relation , tid , snapshot ,
337
- oldSlot , cid , LockTupleExclusive ,
338
- (options & TABLE_MODIFY_WAIT ) ?
339
- LockWaitBlock :
340
- LockWaitSkip ,
341
- TUPLE_LOCK_FLAG_FIND_LAST_VERSION ,
342
- tmfd );
343
-
344
- if (result == TM_Ok )
345
- return TM_Updated ;
346
- }
347
-
348
- return result ;
312
+ return heap_delete (relation , tid , cid , crosscheck , wait , tmfd , changingPart );
349
313
}
350
314
351
315
352
316
static TM_Result
353
317
heapam_tuple_update (Relation relation , ItemPointer otid , TupleTableSlot * slot ,
354
318
CommandId cid , Snapshot snapshot , Snapshot crosscheck ,
355
- int options , TM_FailureData * tmfd ,
356
- LockTupleMode * lockmode , TU_UpdateIndexes * update_indexes ,
357
- TupleTableSlot * oldSlot )
319
+ bool wait , TM_FailureData * tmfd ,
320
+ LockTupleMode * lockmode , TU_UpdateIndexes * update_indexes )
358
321
{
359
322
bool shouldFree = true;
360
323
HeapTuple tuple = ExecFetchSlotHeapTuple (slot , true, & shouldFree );
@@ -364,8 +327,8 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
364
327
slot -> tts_tableOid = RelationGetRelid (relation );
365
328
tuple -> t_tableOid = slot -> tts_tableOid ;
366
329
367
- result = heap_update (relation , otid , tuple , cid , crosscheck , options ,
368
- tmfd , lockmode , update_indexes , oldSlot );
330
+ result = heap_update (relation , otid , tuple , cid , crosscheck , wait ,
331
+ tmfd , lockmode , update_indexes );
369
332
ItemPointerCopy (& tuple -> t_self , & slot -> tts_tid );
370
333
371
334
/*
@@ -392,31 +355,6 @@ heapam_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot,
392
355
if (shouldFree )
393
356
pfree (tuple );
394
357
395
- /*
396
- * If the tuple has been concurrently updated, then get the lock on it.
397
- * (Do only if caller asked for this by setting the
398
- * TABLE_MODIFY_LOCK_UPDATED option) With the lock held retry of the
399
- * update should succeed even if there are more concurrent update
400
- * attempts.
401
- */
402
- if (result == TM_Updated && (options & TABLE_MODIFY_LOCK_UPDATED ))
403
- {
404
- /*
405
- * heapam_tuple_lock() will take advantage of tuple loaded into
406
- * oldSlot by heap_update().
407
- */
408
- result = heapam_tuple_lock (relation , otid , snapshot ,
409
- oldSlot , cid , * lockmode ,
410
- (options & TABLE_MODIFY_WAIT ) ?
411
- LockWaitBlock :
412
- LockWaitSkip ,
413
- TUPLE_LOCK_FLAG_FIND_LAST_VERSION ,
414
- tmfd );
415
-
416
- if (result == TM_Ok )
417
- return TM_Updated ;
418
- }
419
-
420
358
return result ;
421
359
}
422
360
@@ -428,6 +366,7 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
428
366
{
429
367
BufferHeapTupleTableSlot * bslot = (BufferHeapTupleTableSlot * ) slot ;
430
368
TM_Result result ;
369
+ Buffer buffer ;
431
370
HeapTuple tuple = & bslot -> base .tupdata ;
432
371
bool follow_updates ;
433
372
@@ -437,15 +376,18 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
437
376
Assert (TTS_IS_BUFFERTUPLE (slot ));
438
377
439
378
tuple_lock_retry :
440
- result = heap_lock_tuple (relation , tid , slot , cid , mode , wait_policy ,
441
- follow_updates , tmfd );
379
+ tuple -> t_self = * tid ;
380
+ result = heap_lock_tuple (relation , tuple , cid , mode , wait_policy ,
381
+ follow_updates , & buffer , tmfd );
442
382
443
383
if (result == TM_Updated &&
444
384
(flags & TUPLE_LOCK_FLAG_FIND_LAST_VERSION ))
445
385
{
446
386
/* Should not encounter speculative tuple on recheck */
447
387
Assert (!HeapTupleHeaderIsSpeculative (tuple -> t_data ));
448
388
389
+ ReleaseBuffer (buffer );
390
+
449
391
if (!ItemPointerEquals (& tmfd -> ctid , & tuple -> t_self ))
450
392
{
451
393
SnapshotData SnapshotDirty ;
@@ -467,8 +409,6 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
467
409
InitDirtySnapshot (SnapshotDirty );
468
410
for (;;)
469
411
{
470
- Buffer buffer = InvalidBuffer ;
471
-
472
412
if (ItemPointerIndicatesMovedPartitions (tid ))
473
413
ereport (ERROR ,
474
414
(errcode (ERRCODE_T_R_SERIALIZATION_FAILURE ),
@@ -563,7 +503,7 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
563
503
/*
564
504
* This is a live tuple, so try to lock it again.
565
505
*/
566
- ExecStorePinnedBufferHeapTuple ( tuple , slot , buffer );
506
+ ReleaseBuffer ( buffer );
567
507
goto tuple_lock_retry ;
568
508
}
569
509
@@ -574,7 +514,7 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
574
514
*/
575
515
if (tuple -> t_data == NULL )
576
516
{
577
- ReleaseBuffer ( buffer );
517
+ Assert (! BufferIsValid ( buffer ) );
578
518
return TM_Deleted ;
579
519
}
580
520
@@ -627,6 +567,9 @@ heapam_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot,
627
567
slot -> tts_tableOid = RelationGetRelid (relation );
628
568
tuple -> t_tableOid = slot -> tts_tableOid ;
629
569
570
+ /* store in slot, transferring existing pin */
571
+ ExecStorePinnedBufferHeapTuple (tuple , slot , buffer );
572
+
630
573
return result ;
631
574
}
632
575
0 commit comments