From dea5cc35c7ad2a86e86c28096b50f132d51bca57 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Thu, 3 Jul 2025 19:48:28 +0530
Subject: [PATCH v2] Fix referencing invalid pointer in logical decoding after
 error

When an error occurs while processing changes with conflicting
column lists in different publications, the entry->columns memory
which is allocated in entry private context is freed. However, the
RelationSyncCache still holds a pointer to this memory, leading to
a crash on subsequent access. Fix this by clearing the cached relation
info through MemoryContext reset callback.
---
 src/backend/replication/pgoutput/pgoutput.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/src/backend/replication/pgoutput/pgoutput.c b/src/backend/replication/pgoutput/pgoutput.c
index 082b4d9d327..1d00587b715 100644
--- a/src/backend/replication/pgoutput/pgoutput.c
+++ b/src/backend/replication/pgoutput/pgoutput.c
@@ -424,6 +424,19 @@ parse_output_parameters(List *options, PGOutputData *data)
 				errmsg("option \"%s\" missing", "publication_names"));
 }
 
+/*
+ * Memory context reset callback for clearing the cached relation info.
+ */
+static void
+cache_context_callback(void *arg)
+{
+	if (RelationSyncCache)
+	{
+		hash_destroy(RelationSyncCache);
+		RelationSyncCache = NULL;
+	}
+}
+
 /*
  * Initialize this plugin
  */
@@ -433,6 +446,7 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
 {
 	PGOutputData *data = palloc0(sizeof(PGOutputData));
 	static bool publication_callback_registered = false;
+	MemoryContextCallback *mcallback;
 
 	/* Create our memory context for private allocations. */
 	data->context = AllocSetContextCreate(ctx->context,
@@ -447,6 +461,10 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
 										 "logical replication publication list context",
 										 ALLOCSET_SMALL_SIZES);
 
+	mcallback = palloc0(sizeof(MemoryContextCallback));
+	mcallback->func = cache_context_callback;
+	MemoryContextRegisterResetCallback(data->cachectx, mcallback);
+
 	ctx->output_plugin_private = data;
 
 	/* This plugin uses binary protocol. */
-- 
2.43.0

