From 8bc3bf3a915344e119c87b6fbd751e01edc708f4 Mon Sep 17 00:00:00 2001
From: Amit Kapila <akapila@postgresql.org>
Date: Tue, 18 Aug 2020 09:18:27 +0530
Subject: [PATCH v6 2/2] additinal error context information in
 heap_page_prune.

---
 src/backend/access/heap/pruneheap.c  | 19 +++++++++++++++++--
 src/backend/access/heap/vacuumlazy.c |  3 ++-
 src/include/access/heapam.h          |  3 ++-
 3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 3ad4222cb8..5ff3477c1b 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -188,7 +188,7 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
 			/* OK to prune */
 			(void) heap_page_prune(relation, buffer, vistest,
 								   limited_xmin, limited_ts,
-								   true, &ignore);
+								   true, &ignore, NULL);
 		}
 
 		/* And release buffer lock */
@@ -213,6 +213,9 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
  * send its own new total to pgstats, and we don't want this delta applied
  * on top of that.)
  *
+ * off_loc is the offset location required by the caller to use in error
+ * callback.
+ *
  * Returns the number of tuples deleted from the page and sets
  * latestRemovedXid.
  */
@@ -221,7 +224,8 @@ heap_page_prune(Relation relation, Buffer buffer,
 				GlobalVisState *vistest,
 				TransactionId old_snap_xmin,
 				TimestampTz old_snap_ts,
-				bool report_stats, TransactionId *latestRemovedXid)
+				bool report_stats, TransactionId *latestRemovedXid,
+				OffsetNumber *off_loc)
 {
 	int			ndeleted = 0;
 	Page		page = BufferGetPage(buffer);
@@ -262,6 +266,13 @@ heap_page_prune(Relation relation, Buffer buffer,
 		if (prstate.marked[offnum])
 			continue;
 
+		/*
+		 * Set the offset number so that we can display it along with any
+		 * error occurred while processing this tuple.
+		 */
+		if (off_loc)
+			*off_loc = offnum;
+
 		/* Nothing to do if slot is empty or already dead */
 		itemid = PageGetItemId(page, offnum);
 		if (!ItemIdIsUsed(itemid) || ItemIdIsDead(itemid))
@@ -271,6 +282,10 @@ heap_page_prune(Relation relation, Buffer buffer,
 		ndeleted += heap_prune_chain(buffer, offnum, &prstate);
 	}
 
+	/* Clear the offset information once we have processed the given page. */
+	if (off_loc)
+		*off_loc = InvalidOffsetNumber;
+
 	/* Any error while applying the changes is critical */
 	START_CRIT_SECTION();
 
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index ef034af4e4..f5cd6b8e01 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1250,7 +1250,8 @@ lazy_scan_heap(Relation onerel, VacuumParams *params, LVRelStats *vacrelstats,
 		 */
 		tups_vacuumed += heap_page_prune(onerel, buf, vistest, false,
 										 InvalidTransactionId, 0,
-										 &vacrelstats->latestRemovedXid);
+										 &vacrelstats->latestRemovedXid,
+										 &vacrelstats->offnum);
 
 		/*
 		 * Now scan the page to collect vacuumable items and check for tuples
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index ba77013f64..92b19dba32 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -178,7 +178,8 @@ extern int	heap_page_prune(Relation relation, Buffer buffer,
 							struct GlobalVisState *vistest,
 							TransactionId limited_oldest_xmin,
 							TimestampTz limited_oldest_ts,
-							bool report_stats, TransactionId *latestRemovedXid);
+							bool report_stats, TransactionId *latestRemovedXid,
+							OffsetNumber *off_loc);
 extern void heap_page_prune_execute(Buffer buffer,
 									OffsetNumber *redirected, int nredirected,
 									OffsetNumber *nowdead, int ndead,
-- 
2.28.0.windows.1

