@@ -2711,6 +2711,15 @@ heap_delete(Relation relation, ItemPointer tid,
27112711
27122712 LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
27132713
2714+ lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2715+ Assert (ItemIdIsNormal (lp ));
2716+
2717+ tp .t_tableOid = RelationGetRelid (relation );
2718+ tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2719+ tp .t_len = ItemIdGetLength (lp );
2720+ tp .t_self = * tid ;
2721+
2722+ l1 :
27142723 /*
27152724 * If we didn't pin the visibility map page and the page has become all
27162725 * visible while we were busy locking the buffer, we'll have to unlock and
@@ -2724,15 +2733,6 @@ heap_delete(Relation relation, ItemPointer tid,
27242733 LockBuffer (buffer , BUFFER_LOCK_EXCLUSIVE );
27252734 }
27262735
2727- lp = PageGetItemId (page , ItemPointerGetOffsetNumber (tid ));
2728- Assert (ItemIdIsNormal (lp ));
2729-
2730- tp .t_tableOid = RelationGetRelid (relation );
2731- tp .t_data = (HeapTupleHeader ) PageGetItem (page , lp );
2732- tp .t_len = ItemIdGetLength (lp );
2733- tp .t_self = * tid ;
2734-
2735- l1 :
27362736 result = HeapTupleSatisfiesUpdate (& tp , cid , buffer );
27372737
27382738 if (result == TM_Invisible )
@@ -2791,8 +2791,12 @@ heap_delete(Relation relation, ItemPointer tid,
27912791 * If xwait had just locked the tuple then some other xact
27922792 * could update this tuple before we get to this point. Check
27932793 * for xmax change, and start over if so.
2794+ *
2795+ * We also must start over if we didn't pin the VM page, and
2796+ * the page has become all visible.
27942797 */
2795- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2798+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2799+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
27962800 !TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
27972801 xwait ))
27982802 goto l1 ;
@@ -2824,8 +2828,12 @@ heap_delete(Relation relation, ItemPointer tid,
28242828 * xwait is done, but if xwait had just locked the tuple then some
28252829 * other xact could update this tuple before we get to this point.
28262830 * Check for xmax change, and start over if so.
2831+ *
2832+ * We also must start over if we didn't pin the VM page, and the
2833+ * page has become all visible.
28272834 */
2828- if (xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
2835+ if ((vmbuffer == InvalidBuffer && PageIsAllVisible (page )) ||
2836+ xmax_infomask_changed (tp .t_data -> t_infomask , infomask ) ||
28292837 !TransactionIdEquals (HeapTupleHeaderGetRawXmax (tp .t_data ),
28302838 xwait ))
28312839 goto l1 ;
0 commit comments