@@ -2531,6 +2531,15 @@ heap_delete(Relation relation, ItemPointer tid,
2531
2531
2532
2532
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2533
2533
2534
+ lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2535
+ Assert (ItemIdIsNormal (lp ));
2536
+
2537
+ tp .t_tableOid = RelationGetRelid (relation );
2538
+ tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2539
+ tp .t_len = ItemIdGetLength (lp );
2540
+ tp .t_self = * tid ;
2541
+
2542
+ l1 :
2534
2543
/*
2535
2544
* If we didn't pin the visibility map page and the page has become all
2536
2545
* visible while we were busy locking the buffer, we'll have to unlock and
@@ -2544,15 +2553,6 @@ heap_delete(Relation relation, ItemPointer tid,
2544
2553
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2545
2554
}
2546
2555
2547
- lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2548
- Assert (ItemIdIsNormal (lp ));
2549
-
2550
- tp .t_tableOid = RelationGetRelid (relation );
2551
- tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2552
- tp .t_len = ItemIdGetLength (lp );
2553
- tp .t_self = * tid ;
2554
-
2555
- l1 :
2556
2556
result = HeapTupleSatisfiesUpdate (& tp , cid , buffer );
2557
2557
2558
2558
if (result == TM_Invisible )
@@ -2611,8 +2611,12 @@ heap_delete(Relation relation, ItemPointer tid,
2611
2611
* If xwait had just locked the tuple then some other xact
2612
2612
* could update this tuple before we get to this point. Check
2613
2613
* for xmax change, and start over if so.
2614
+ *
2615
+ * We also must start over if we didn't pin the VM page, and
2616
+ * the page has become all visible.
2614
2617
*/
2615
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2618
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2619
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2616
2620
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2617
2621
xwait ))
2618
2622
goto l1 ;
@@ -2644,8 +2648,12 @@ heap_delete(Relation relation, ItemPointer tid,
2644
2648
* xwait is done, but if xwait had just locked the tuple then some
2645
2649
* other xact could update this tuple before we get to this point.
2646
2650
* Check for xmax change, and start over if so.
2651
+ *
2652
+ * We also must start over if we didn't pin the VM page, and the
2653
+ * page has become all visible.
2647
2654
*/
2648
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2655
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2656
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2649
2657
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2650
2658
xwait ))
2651
2659
goto l1 ;
0 commit comments