From 8f693117772b9886ab6fb450f1262bf858fa20a4 Mon Sep 17 00:00:00 2001
From: Hayato Kuroda <kuroda.hayato@fujitsu.com>
Date: Wed, 7 Oct 2026 15:56:06 +0900
Subject: [PATCH v5 2/4] Avoid adding leader context to parallel apply worker
 errors

Errors reported by a parallel apply worker are propagated through the
leader apply worker.  Before reporting such an error, the leader replaces
error_context_stack with apply_error_context_stack to avoid invoking error
context callbacks for unrelated work being performed by the leader.

However, LogicalRepApplyLoop saved apply_error_context_stack after
installing apply_error_callback.  Consequently, reporting a parallel
worker error invoked that callback again.  If the leader was concurrently
applying another transaction, the error could acquire a misleading
CONTEXT line describing the relation being processed by the leader rather
than the transaction that failed in the parallel worker.

Save the error context stack before installing apply_error_callback, so
that errors propagated from parallel apply workers retain their own
context without being annotated with the leader's current apply context.
---
 src/backend/replication/logical/applyparallelworker.c | 4 ++--
 src/backend/replication/logical/worker.c              | 7 ++++++-
 2 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/backend/replication/logical/applyparallelworker.c b/src/backend/replication/logical/applyparallelworker.c
index 96bf499e49c..afc19ba16ac 100644
--- a/src/backend/replication/logical/applyparallelworker.c
+++ b/src/backend/replication/logical/applyparallelworker.c
@@ -1046,8 +1046,8 @@ ProcessParallelApplyMessage(StringInfo msg)
 					edata.context = pstrdup(_("logical replication parallel apply worker"));
 
 				/*
-				 * Context beyond that should use the error context callbacks
-				 * that were in effect in LogicalRepApplyLoop().
+				 * Use the callbacks saved before the leader's apply error
+				 * context callback was installed.
 				 */
 				error_context_stack = apply_error_context_stack;
 
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index 37b37500213..f12cc464be9 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -4081,6 +4081,12 @@ LogicalRepApplyLoop(XLogRecPtr last_received)
 	/* mark as idle, before starting to loop */
 	pgstat_report_activity(STATE_IDLE, NULL);
 
+	/*
+	 * Save the current callbacks so that an error propagated from a parallel
+	 * apply worker does not use this leader's unrelated apply error context.
+	 */
+	apply_error_context_stack = error_context_stack;
+
 	/*
 	 * Push apply error context callback. Fields will be filled while applying
 	 * a change.
@@ -4088,7 +4094,6 @@ LogicalRepApplyLoop(XLogRecPtr last_received)
 	errcallback.callback = apply_error_callback;
 	errcallback.previous = error_context_stack;
 	error_context_stack = &errcallback;
-	apply_error_context_stack = error_context_stack;
 
 	/* This outer loop iterates once per wait. */
 	for (;;)
-- 
2.52.0

