On Fri, 18 Jul 2025 at 04:46, Fujii Masao <masao.fu...@oss.nttdata.com> wrote:
>
>
>
> On 2025/07/18 1:15, Álvaro Herrera wrote:
> > On 2025-Jul-18, Fujii Masao wrote:
> >
> >> The current patches add nearly identical notice_receiver functions
> >> in multiple places such as libpqwalreceiver.c and elsewhere. To avoid
> >> duplicating the same logic, could we define a shared notice receiver
> >> function in a common file, like libpq-be-fe-helpers.h, and use it in
> >> all three locations?
> >
> > I like the idea of reducing duplication.  I don't like the "prefix"
> > as proposed though, because it's not going to work well for translation
> > (string building) -- I'd rather pass the entire phrase from caller, so
> > that the translator has one piece to translate which lives in the module
> > that emits it.  I think I'd do something like
> >
> >      ereport(LOG,
> >              errmsg_internal("%s: %.*s",
> >                           _(prefix), len, message));
> >
> > and see to it that each caller uses gettext_noop() around the string
> > they pass as "arg", for gettext to collect.
>
> Agreed. Thanks!

The attached v6 version patch has the changes for these comments.

Regards,
Vignesh
From 4d40ae938e97f5d1b4dc8ec99f6bc0adde57ed2e Mon Sep 17 00:00:00 2001
From: Vignesh C <vignes...@gmail.com>
Date: Fri, 18 Jul 2025 21:07:35 +0530
Subject: [PATCH v6 3/3] Use libpqsrv_notice_receiver for remote server
 connections in FDW

This patch applies the previously introduced libpqsrv_notice_receiver
as the custom PQsetNoticeReceiver handler for remote libpq connections
used by Foreign Data Wrappers. It captures server notices and logs them
via ereport(LOG).
---
 contrib/postgres_fdw/connection.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..c1ce6f33436 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -625,6 +625,9 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
 							server->servername),
 					 errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
 
+		PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+							"received message via remote connection");
+
 		/* Perform post-connection security checks. */
 		pgfdw_security_check(keywords, values, user, conn);
 
-- 
2.43.0

From 65061ce7de2ba20386a3d28a81c6ae0db005e9da Mon Sep 17 00:00:00 2001
From: Vignesh C <vignes...@gmail.com>
Date: Wed, 16 Jul 2025 15:26:12 +0530
Subject: [PATCH v6 1/3] Add custom PQsetNoticeReceiver handlers for
 replication connection

This patch introduces a custom notice receiver for replication
connections. The notice receiver captures messages and routes
them through ereport(), making them visible in local logs with
a prefix making it easy for diagnosis.
---
 .../libpqwalreceiver/libpqwalreceiver.c       |  3 ++
 src/include/libpq/libpq-be-fe-helpers.h       | 31 +++++++++++++++++++
 2 files changed, 34 insertions(+)

diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..886d99951dd 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -232,6 +232,9 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical,
 				 errhint("Target server's authentication method must be changed, or set password_required=false in the subscription parameters.")));
 	}
 
+	PQsetNoticeReceiver(conn->streamConn, libpqsrv_notice_receiver,
+						"received message via replication");
+
 	/*
 	 * Set always-secure search path for the cases where the connection is
 	 * used to run SQL queries, so malicious users can't get control.
diff --git a/src/include/libpq/libpq-be-fe-helpers.h b/src/include/libpq/libpq-be-fe-helpers.h
index 16205b824fa..a697d6a0f2c 100644
--- a/src/include/libpq/libpq-be-fe-helpers.h
+++ b/src/include/libpq/libpq-be-fe-helpers.h
@@ -52,6 +52,7 @@ static inline void libpqsrv_connect_prepare(void);
 static inline void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info);
 static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info);
 static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_notice_receiver(void *arg, const PGresult *res);
 
 
 /*
@@ -454,4 +455,34 @@ exit:	;
 	return error;
 }
 
+/*
+ * libpqsrv_notice_receiver
+ *
+ * Custom notice receiver for libpq connections.
+ *
+ * This function is intended to be set via PQsetNoticeReceiver() so that
+ * NOTICE, WARNING, and similar messages from the connection are reported via
+ * ereport(), instead of being printed to stderr.
+ */
+static inline void
+libpqsrv_notice_receiver(void *arg, const PGresult *res)
+{
+	char	   *message;
+	int			len;
+	char	   *prefix = (char *) arg;
+
+	/*
+	 * Trim the trailing newline from the message text returned from
+	 * PQresultErrorMessage(), as it always includes one, to produce cleaner
+	 * log output.
+	 */
+	message = PQresultErrorMessage(res);
+	len = strlen(message);
+	if (len > 0 && message[len - 1] == '\n')
+		len--;
+
+	ereport(LOG,
+			errmsg_internal("%s: %.*s", _(prefix), len, message));
+}
+
 #endif							/* LIBPQ_BE_FE_HELPERS_H */
-- 
2.43.0

From 9c837f55239b8ae09eb4702db7c06d6d38acbe8b Mon Sep 17 00:00:00 2001
From: Vignesh C <vignes...@gmail.com>
Date: Fri, 18 Jul 2025 21:05:50 +0530
Subject: [PATCH v6 2/3] Use libpqsrv_notice_receiver for remote server
 connections in dblink

This patch integrates the previously introduced libpqsrv_notice_receiver
as the custom PQsetNoticeReceiver handler for dblink's remote server
connections. It ensures that server notices are logged via ereport(LOG).
---
 contrib/dblink/dblink.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..de5bed282f3 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -240,6 +240,10 @@ dblink_get_conn(char *conname_or_str,
 					 errmsg("could not establish connection"),
 					 errdetail_internal("%s", msg)));
 		}
+
+		PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+							"received message via remote connection");
+
 		dblink_security_check(conn, NULL, connstr);
 		if (PQclientEncoding(conn) != GetDatabaseEncoding())
 			PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +342,9 @@ dblink_connect(PG_FUNCTION_ARGS)
 				 errdetail_internal("%s", msg)));
 	}
 
+	PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
+						"received message via remote connection");
+
 	/* check password actually used if not superuser */
 	dblink_security_check(conn, connname, connstr);
 
-- 
2.43.0

Reply via email to