From 815d21cc9ba385376622a9cbab7a9807c5e9c726 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:31:54 +0530
Subject: [PATCH v5 2/3] Add custom PQsetNoticeReceiver handlers for remote
 server connection in dblink

This patch introduces a custom notice receiver for remote
server connection in dblink.  The notice receiver captures
messages and routes them through ereport(), making them visible
in local logs with a prefix making it easy for diagnosis.
---
 contrib/dblink/dblink.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..a2d1e407137 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -137,6 +137,7 @@ static void appendSCRAMKeysInfo(StringInfo buf);
 static bool is_valid_dblink_fdw_option(const PQconninfoOption *options, const char *option,
 									   Oid context);
 static bool dblink_connstr_has_required_scram_options(const char *connstr);
+static void notice_receiver(void *arg, const PGresult *result);
 
 /* Global */
 static remoteConn *pconn = NULL;
@@ -240,6 +241,14 @@ dblink_get_conn(char *conname_or_str,
 					 errmsg("could not establish connection"),
 					 errdetail_internal("%s", msg)));
 		}
+
+		/*
+		 * Set a custom notice receiver so that NOTICEs, WARNINGs, and similar
+		 * messages from the remote server connection are reported via
+		 * ereport(), instead of being printed to stderr.
+		 */
+		PQsetNoticeReceiver(conn, notice_receiver, NULL);
+
 		dblink_security_check(conn, NULL, connstr);
 		if (PQclientEncoding(conn) != GetDatabaseEncoding())
 			PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +347,13 @@ dblink_connect(PG_FUNCTION_ARGS)
 				 errdetail_internal("%s", msg)));
 	}
 
+	/*
+	 * Set a custom notice receiver so that NOTICEs, WARNINGs, and similar
+	 * messages from the remote server connection are reported via ereport(),
+	 * instead of being printed to stderr.
+	 */
+	PQsetNoticeReceiver(conn, notice_receiver, NULL);
+
 	/* check password actually used if not superuser */
 	dblink_security_check(conn, connname, connstr);
 
@@ -2670,6 +2686,28 @@ dblink_connstr_has_required_scram_options(const char *connstr)
 	return (has_scram_keys && has_require_auth);
 }
 
+/*
+ * Custom notice receiver for remote server connection.
+ */
+static void
+notice_receiver(void *arg, const PGresult *result)
+{
+	char	   *message;
+	int			len;
+
+	/*
+	 * Trim the trailing newline from the message text passed to the notice
+	 * receiver, as it always includes one, to produce cleaner log output.
+	 */
+	message = PQresultErrorMessage(result);
+	len = strlen(message);
+	if (len > 0 && message[len - 1] == '\n')
+		len--;
+
+	ereport(LOG,
+			errmsg("received message from remote server: %.*s", len, message));
+}
+
 /*
  * We need to make sure that the connection made used credentials
  * which were provided by the user, so check what credentials were
-- 
2.43.0

