From f9cdde59dfa05413ad4213c5438c06fc552d8f40 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 31 Jul 2020 21:24:49 -0500
Subject: [PATCH 2/2] fix

---
 src/backend/access/heap/vacuumlazy.c | 29 +++++++++++++++-------------
 1 file changed, 16 insertions(+), 13 deletions(-)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 78d1db9ae2..b6015c9297 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1860,7 +1860,6 @@ lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats)
 
 		tblk = ItemPointerGetBlockNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		vacrelstats->blkno = tblk;
-		vacrelstats->offnum = ItemPointerGetOffsetNumber(&vacrelstats->dead_tuples->itemptrs[tupindex]);
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, tblk, RBM_NORMAL,
 								 vac_strategy);
 		if (!ConditionalLockBufferForCleanup(buf))
@@ -1937,7 +1936,6 @@ lazy_vacuum_page(Relation onerel, BlockNumber blkno, Buffer buffer,
 		if (tblk != blkno)
 			break;				/* past end of tuples for this block */
 		toff = ItemPointerGetOffsetNumber(&dead_tuples->itemptrs[tupindex]);
-		vacrelstats->offnum = toff;
 		itemid = PageGetItemId(page, toff);
 		ItemIdSetUnused(itemid);
 		unused[uncnt++] = toff;
@@ -2022,6 +2020,7 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	OffsetNumber offnum,
 				maxoff;
 	HeapTupleHeader tupleheader;
+	LVSavedErrInfo saved_err_info;
 
 	*hastup = false;
 
@@ -2034,6 +2033,11 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 	if (PageIsNew(page) || PageIsEmpty(page))
 		return false;
 
+	/* Update error traceback information */
+	update_vacuum_error_info(vacrelstats, &saved_err_info,
+			VACUUM_ERRCB_PHASE_SCAN_HEAP, vacrelstats->blkno,
+			InvalidOffsetNumber);
+
 	maxoff = PageGetMaxOffsetNumber(page);
 	for (offnum = FirstOffsetNumber;
 		 offnum <= maxoff;
@@ -2056,10 +2060,13 @@ lazy_check_needs_freeze(Buffer buf, bool *hastup, LVRelStats *vacrelstats)
 
 		if (heap_tuple_needs_freeze(tupleheader, FreezeLimit,
 									MultiXactCutoff, buf))
-			return true;
+			break;
 	}							/* scan along page */
 
-	return false;
+	/* Revert to the previous phase information for error traceback */
+	restore_vacuum_error_info(vacrelstats, &saved_err_info);
+
+	return offnum <= maxoff ? true : false;
 }
 
 /*
@@ -2501,7 +2508,7 @@ lazy_cleanup_index(Relation indrel,
 
 	*stats = index_vacuum_cleanup(&ivinfo, *stats);
 
-	/* Revert back to the old phase information for error traceback */
+	/* Revert to the old phase information for error traceback */
 	restore_vacuum_error_info(vacrelstats, &saved_err_info);
 	pfree(vacrelstats->indname);
 	vacrelstats->indname = NULL;
@@ -3590,8 +3597,8 @@ vacuum_error_callback(void *arg)
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
 				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while scanning block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
+					errcontext("while scanning block %u of relation \"%s.%s\", item offset %u",
+							   errinfo->blkno, errinfo->relnamespace, errinfo->relname, errinfo->offnum);
 				else
 					errcontext("while scanning block %u of relation \"%s.%s\"",
 							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
@@ -3601,12 +3608,8 @@ vacuum_error_callback(void *arg)
 		case VACUUM_ERRCB_PHASE_VACUUM_HEAP:
 			if (BlockNumberIsValid(errinfo->blkno))
 			{
-				if (OffsetNumberIsValid(errinfo->offnum))
-					errcontext("while vacuuming block %u and offset %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->offnum, errinfo->relnamespace, errinfo->relname);
-				else
-					errcontext("while vacuuming block %u of relation \"%s.%s\"",
-							   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
+				errcontext("while vacuuming block %u of relation \"%s.%s\"",
+						   errinfo->blkno, errinfo->relnamespace, errinfo->relname);
 			}
 			break;
 
-- 
2.17.0

