@@ -2500,6 +2500,15 @@ heap_delete(Relation relation, ItemPointer tid,
2500
2500
2501
2501
LockBuffer (buffer ,BUFFER_LOCK_EXCLUSIVE );
2502
2502
2503
+ lp = PageGetItemId (page ,ItemPointerGetOffsetNumber (tid ));
2504
+ Assert (ItemIdIsNormal (lp ));
2505
+
2506
+ tp .t_tableOid = RelationGetRelid (relation );
2507
+ tp .t_data = (HeapTupleHeader )PageGetItem (page ,lp );
2508
+ tp .t_len = ItemIdGetLength (lp );
2509
+ tp .t_self = * tid ;
2510
+
2511
+ l1 :
2503
2512
/*
2504
2513
* If we didn't pin the visibility map page and the page has become all
2505
2514
* visible while we were busy locking the buffer, we'll have to unlock and
@@ -2513,15 +2522,6 @@ heap_delete(Relation relation, ItemPointer tid,
2513
2522
LockBuffer (buffer ,BUFFER_LOCK_EXCLUSIVE );
2514
2523
}
2515
2524
2516
- lp = PageGetItemId (page ,ItemPointerGetOffsetNumber (tid ));
2517
- Assert (ItemIdIsNormal (lp ));
2518
-
2519
- tp .t_tableOid = RelationGetRelid (relation );
2520
- tp .t_data = (HeapTupleHeader )PageGetItem (page ,lp );
2521
- tp .t_len = ItemIdGetLength (lp );
2522
- tp .t_self = * tid ;
2523
-
2524
- l1 :
2525
2525
result = HeapTupleSatisfiesUpdate (& tp ,cid ,buffer );
2526
2526
2527
2527
if (result == TM_Invisible )
@@ -2580,8 +2580,12 @@ heap_delete(Relation relation, ItemPointer tid,
2580
2580
* If xwait had just locked the tuple then some other xact
2581
2581
* could update this tuple before we get to this point. Check
2582
2582
* for xmax change, and start over if so.
2583
+ *
2584
+ * We also must start over if we didn't pin the VM page, and
2585
+ * the page has become all visible.
2583
2586
*/
2584
- if (xmax_infomask_changed (tp .t_data -> t_infomask ,infomask )||
2587
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page ))||
2588
+ xmax_infomask_changed (tp .t_data -> t_infomask ,infomask )||
2585
2589
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2586
2590
xwait ))
2587
2591
gotol1 ;
@@ -2613,8 +2617,12 @@ heap_delete(Relation relation, ItemPointer tid,
2613
2617
* xwait is done, but if xwait had just locked the tuple then some
2614
2618
* other xact could update this tuple before we get to this point.
2615
2619
* Check for xmax change, and start over if so.
2620
+ *
2621
+ * We also must start over if we didn't pin the VM page, and the
2622
+ * page has become all visible.
2616
2623
*/
2617
- if (xmax_infomask_changed (tp .t_data -> t_infomask ,infomask )||
2624
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page ))||
2625
+ xmax_infomask_changed (tp .t_data -> t_infomask ,infomask )||
2618
2626
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2619
2627
xwait ))
2620
2628
gotol1 ;