From 02b2b4f06578bf649f7574314cb55744de7ddd63 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sun, 16 Feb 2020 20:25:13 -0600
Subject: [PATCH v20 2/2] add callback for truncation

---
 src/backend/access/heap/vacuumlazy.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index ce3efd7..518a8a0 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -2501,9 +2501,15 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
 	BlockNumber new_rel_pages;
 	PGRUsage	ru0;
 	int			lock_retry;
+	ErrorContextCallback errcallback;
+	vacuum_error_callback_arg errcbarg;
 
 	pg_rusage_init(&ru0);
 
+	/* Setup error traceback support for ereport() */
+	init_vacuum_error_callback(&errcallback, &errcbarg, onerel,
+			PROGRESS_VACUUM_PHASE_TRUNCATE);
+
 	/* Report that we are now truncating */
 	pgstat_progress_update_param(PROGRESS_VACUUM_PHASE,
 								 PROGRESS_VACUUM_PHASE_TRUNCATE);
@@ -2584,11 +2590,18 @@ lazy_truncate_heap(Relation onerel, LVRelStats *vacrelstats)
 			return;
 		}
 
+		/* Setup error traceback support for ereport() */
+		errcbarg.blkno = new_rel_pages;
+		error_context_stack = &errcallback;
+
 		/*
 		 * Okay to truncate.
 		 */
 		RelationTruncate(onerel, new_rel_pages);
 
+		/* Pop the error context stack */
+		error_context_stack = errcallback.previous;
+
 		/*
 		 * We can release the exclusive lock as soon as we have truncated.
 		 * Other backends can't safely access the relation until they have
@@ -2628,6 +2641,12 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
 	BlockNumber blkno;
 	BlockNumber prefetchedUntil;
 	instr_time	starttime;
+	ErrorContextCallback errcallback;
+	vacuum_error_callback_arg errcbarg;
+
+	/* Setup error traceback support for ereport() */
+	init_vacuum_error_callback(&errcallback, &errcbarg, onerel,
+			PROGRESS_VACUUM_PHASE_TRUNCATE);
 
 	/* Initialize the starttime if we check for conflicting lock requests */
 	INSTR_TIME_SET_CURRENT(starttime);
@@ -2691,6 +2710,10 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
 
 		blkno--;
 
+		/* Setup error traceback support for ereport() */
+		errcbarg.blkno = blkno;
+		error_context_stack = &errcallback;
+
 		/* If we haven't prefetched this lot yet, do so now. */
 		if (prefetchedUntil > blkno)
 		{
@@ -2709,6 +2732,9 @@ count_nondeletable_pages(Relation onerel, LVRelStats *vacrelstats)
 		buf = ReadBufferExtended(onerel, MAIN_FORKNUM, blkno,
 								 RBM_NORMAL, vac_strategy);
 
+		/* Pop the error context stack */
+		error_context_stack = errcallback.previous;
+
 		/* In this phase we only need shared access to the buffer */
 		LockBuffer(buf, BUFFER_LOCK_SHARE);
 
@@ -3468,6 +3494,11 @@ vacuum_error_callback(void *arg)
 			break;
 
 		case PROGRESS_VACUUM_PHASE_TRUNCATE:
+			if (BlockNumberIsValid(cbarg->blkno))
+				errcontext(_("while truncating relation \"%s.%s\" to %u blocks"),
+						cbarg->relnamespace, cbarg->relname, cbarg->blkno);
+			break;
+
 		case PROGRESS_VACUUM_PHASE_FINAL_CLEANUP:
 		default:
 			return; /* Shouldn't happen: do nothing */
@@ -3483,6 +3514,7 @@ init_vacuum_error_callback(ErrorContextCallback *errcallback,
 	{
 		case PROGRESS_VACUUM_PHASE_SCAN_HEAP:
 		case PROGRESS_VACUUM_PHASE_VACUUM_HEAP:
+		case PROGRESS_VACUUM_PHASE_TRUNCATE:
 			errcbarg->relname = RelationGetRelationName(rel);
 			errcbarg->indname = NULL; /* Not used for heap */
 			break;
-- 
2.7.4

