From ff053bf2b2b0525ef203e0d18fbb4c4ab586f110 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Mon, 20 Jan 2020 14:44:06 -0600
Subject: [PATCH v13 4/5] errcontext for lazy_vacuum_index

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

diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 8b053a7..d2673c2 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -292,7 +292,7 @@ typedef struct LVRelStats
 	char		*relname;
 	char 		*relnamespace;
 	BlockNumber blkno;
-	int			stage;	/* 0: scan heap; 1: vacuum heap */
+	int			stage;	/* 0: scan heap; 1: vacuum heap; 2: vacuum index */
 } LVRelStats;
 
 /* A few variables that don't seem worth passing around as parameters */
@@ -2360,6 +2360,8 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	IndexVacuumInfo ivinfo;
 	const char *msg;
 	PGRUsage	ru0;
+	ErrorContextCallback errcallback;
+	LVRelStats	vacrelstats; /* Used for error callback, only */
 
 	pg_rusage_init(&ru0);
 
@@ -2371,10 +2373,23 @@ lazy_vacuum_index(Relation indrel, IndexBulkDeleteResult **stats,
 	ivinfo.num_heap_tuples = reltuples;
 	ivinfo.strategy = vac_strategy;
 
+	/* Setup error traceback support for ereport() */
+	vacrelstats.relnamespace = get_namespace_name(RelationGetNamespace(indrel));
+	vacrelstats.relname = RelationGetRelationName(indrel);
+	vacrelstats.stage = 2;
+
+	errcallback.callback = vacuum_error_callback;
+	errcallback.arg = (void *) &vacrelstats;
+	errcallback.previous = error_context_stack;
+	error_context_stack = &errcallback;
+
 	/* Do bulk deletion */
 	*stats = index_bulk_delete(&ivinfo, *stats,
 							   lazy_tid_reaped, (void *) dead_tuples);
 
+	/* Pop the error context stack */
+	error_context_stack = errcallback.previous;
+
 	if (IsParallelWorker())
 		msg = gettext_noop("scanned index \"%s\" to remove %d row versions by parallel vacuum worker");
 	else
@@ -3432,3 +3447,7 @@ vacuum_error_callback(void *arg)
 	else if (cbarg->stage == 1)
 		errcontext(_("while vacuuming block %u of relation \"%s.%s\""),
 				cbarg->blkno, cbarg->relnamespace, cbarg->relname);
+	else if (cbarg->stage == 2)
+		errcontext(_("while vacuuming index \"%s.%s\""),
+				cbarg->relnamespace, cbarg->relname);
+}
-- 
2.7.4

