@@ -2773,6 +2773,15 @@ heap_delete(Relation relation, ItemPointer tid,
2773
2773
2774
2774
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2775
2775
2776
+ lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2777
+ Assert (ItemIdIsNormal (lp ));
2778
+
2779
+ tp .t_tableOid = RelationGetRelid (relation );
2780
+ tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2781
+ tp .t_len = ItemIdGetLength (lp );
2782
+ tp .t_self = * tid ;
2783
+
2784
+ l1 :
2776
2785
/*
2777
2786
* If we didn't pin the visibility map page and the page has become all
2778
2787
* visible while we were busy locking the buffer, we'll have to unlock and
@@ -2786,15 +2795,6 @@ heap_delete(Relation relation, ItemPointer tid,
2786
2795
LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
2787
2796
}
2788
2797
2789
- lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2790
- Assert (ItemIdIsNormal (lp ));
2791
-
2792
- tp .t_tableOid = RelationGetRelid (relation );
2793
- tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2794
- tp .t_len = ItemIdGetLength (lp );
2795
- tp .t_self = * tid ;
2796
-
2797
- l1 :
2798
2798
result = HeapTupleSatisfiesUpdate (& tp , cid , buffer );
2799
2799
2800
2800
if (result == TM_Invisible )
@@ -2853,8 +2853,12 @@ heap_delete(Relation relation, ItemPointer tid,
2853
2853
* If xwait had just locked the tuple then some other xact
2854
2854
* could update this tuple before we get to this point. Check
2855
2855
* for xmax change, and start over if so.
2856
+ *
2857
+ * We also must start over if we didn't pin the VM page, and
2858
+ * the page has become all visible.
2856
2859
*/
2857
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2860
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2861
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2858
2862
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2859
2863
xwait ))
2860
2864
goto l1 ;
@@ -2886,8 +2890,12 @@ heap_delete(Relation relation, ItemPointer tid,
2886
2890
* xwait is done, but if xwait had just locked the tuple then some
2887
2891
* other xact could update this tuple before we get to this point.
2888
2892
* Check for xmax change, and start over if so.
2893
+ *
2894
+ * We also must start over if we didn't pin the VM page, and the
2895
+ * page has become all visible.
2889
2896
*/
2890
- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2897
+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2898
+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2891
2899
!TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
2892
2900
xwait ))
2893
2901
goto l1 ;
0 commit comments