Log prefix missing for subscriber log messages received from publisher
Hi,
Currently, when a warning is emitted by the publisher, the
corresponding log message does not include the log prefix. This makes
it harder to correlate such messages with other log entries. For
example, in a simulated error scenario where directory removal fails,
the notice message lacks the standard log prefix, as shown below:
2025-03-18 16:44:36.071 IST [196901] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finished
WARNING: could not remove directory
"pg_replslot/pg_16398_sync_16387_7483106341004194035.tmp"
In this case, the WARNING line does not include the usual timestamp
information, making it harder to trace.
To address this, we can have a custom notice processor for WAL
receiver connections—similar to what's done in the attached patch.
This ensures that notices received during both streaming and logical
replication include the appropriate log prefix. Since this issue is
present in both replication modes, the patch sets the notice processor
for all WAL receiver connections.
Regards,
Vignesh
Attachments:
register_notice_process.patchapplication/octet-stream; name=register_notice_process.patchDownload
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index c650935ef5d..636bf836e32 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -125,6 +125,12 @@ _PG_init(void)
WalReceiverFunctions = &PQWalReceiverFunctions;
}
+static void
+notice_processor(void *arg, const char *message)
+{
+ elog(LOG, "%s", message);
+}
+
/*
* Establish the connection to the primary server.
*
@@ -290,6 +296,8 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical,
PQclear(res);
}
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
+
conn->logical = logical;
return conn;
On 2025/04/15 13:37, vignesh C wrote:
Hi,
Currently, when a warning is emitted by the publisher, the
corresponding log message does not include the log prefix. This makes
it harder to correlate such messages with other log entries. For
example, in a simulated error scenario where directory removal fails,
the notice message lacks the standard log prefix, as shown below:
2025-03-18 16:44:36.071 IST [196901] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finished
WARNING: could not remove directory
"pg_replslot/pg_16398_sync_16387_7483106341004194035.tmp"In this case, the WARNING line does not include the usual timestamp
information, making it harder to trace.To address this, we can have a custom notice processor for WAL
receiver connections—similar to what's done in the attached patch.
I like this idea.
If this issue also exists other features like dblink or postgres_fdw
connecting to remote PostgreSQL servers, it might be worth applying
a similar improvement there as well.
+notice_processor(void *arg, const char *message)
+{
+ elog(LOG, "%s", message);
Should ereport() be used here instead?
Also, would it be better to add some context before %s, for example,
something like "received message from the primary:"? Without that,
users might mistakenly think the message originated from the local server.
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
On Mon, 14 Jul 2025 at 21:36, Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2025/04/15 13:37, vignesh C wrote:
Hi,
Currently, when a warning is emitted by the publisher, the
corresponding log message does not include the log prefix. This makes
it harder to correlate such messages with other log entries. For
example, in a simulated error scenario where directory removal fails,
the notice message lacks the standard log prefix, as shown below:
2025-03-18 16:44:36.071 IST [196901] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finished
WARNING: could not remove directory
"pg_replslot/pg_16398_sync_16387_7483106341004194035.tmp"In this case, the WARNING line does not include the usual timestamp
information, making it harder to trace.To address this, we can have a custom notice processor for WAL
receiver connections—similar to what's done in the attached patch.I like this idea.
If this issue also exists other features like dblink or postgres_fdw
connecting to remote PostgreSQL servers, it might be worth applying
a similar improvement there as well.
Included it for dblink and fdw
+notice_processor(void *arg, const char *message) +{ + elog(LOG, "%s", message);Should ereport() be used here instead?
Yes, that is better. Modified it to ereport
Also, would it be better to add some context before %s, for example,
something like "received message from the primary:"? Without that,
users might mistakenly think the message originated from the local server.
Yes, that makes sense. Updated accordingly.
For dblink and postgres_fdw, create the dblink and postgres_fdw setup
and create the below object to raise a notice:
CREATE OR REPLACE FUNCTION emit_notice(msg text) RETURNS int AS $$
BEGIN
RAISE NOTICE '%', msg;
RETURN 1;
END;
$$ LANGUAGE plpgsql;
CREATE VIEW my_notice_view AS SELECT 1 AS value;
CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO my_notice_view
DO INSTEAD
SELECT 1 AS value
FROM (SELECT emit_notice('NOTICE from _RETURN rule') AS dummy) s;
-- Scenario to see the notice raised by remote server using dblink
SELECT * FROM dblink('dbname=remotedb user=remoteuser', 'SELECT *
FROM my_notice_view') AS t(value int);
-- Scenario to see the notice raised by remote server using postgres_fdw
IMPORT FOREIGN SCHEMA public LIMIT TO (my_notice_view) FROM SERVER
foreign_server INTO public;
The attached v2 version patch has the changes for the same.
Regards,
Vignesh
Attachments:
v2-0001-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchapplication/octet-stream; name=v2-0001-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchDownload
From bc3880ad2ef1a76448c10cf9c6dc9a1b00cd659d Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Tue, 15 Jul 2025 22:38:25 +0530
Subject: [PATCH v2] Add custom PQsetNoticeProcessor handlers for dblink,
postgres_fdw, and subscribers
This patch introduces a custom notice processor for libpq-based connections in
dblink, postgres_fdw, and logical replication subscribers. The notice processor
captures messages from remote PostgreSQL servers and routes them through
ereport(), making them visible in local logs with a prefix making it
easy for diagnosis.
---
contrib/dblink/dblink.c | 29 +++++++++++++++++++
contrib/postgres_fdw/connection.c | 26 +++++++++++++++++
.../libpqwalreceiver/libpqwalreceiver.c | 26 +++++++++++++++++
3 files changed, 81 insertions(+)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..f80c5a196f2 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -177,6 +177,30 @@ xpstrdup(const char *in)
return pstrdup(in);
}
+/*
+ * notice_processor
+ *
+ * Custom notice processor for libpq connections used by dblink.
+ * This function captures NOTICE messages sent by the remote server and
+ * redirects them to PostgreSQL's logging facility using ereport().
+ *
+ * Strips trailing newline characters from messages for cleaner logs.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("Received message from remote server: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("Received message from remote server: %s", message));
+}
+
pg_noreturn static void
dblink_res_internalerror(PGconn *conn, PGresult *res, const char *p2)
{
@@ -240,6 +264,9 @@ dblink_get_conn(char *conname_or_str,
errmsg("could not establish connection"),
errdetail_internal("%s", msg)));
}
+
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
dblink_security_check(conn, NULL, connstr);
if (PQclientEncoding(conn) != GetDatabaseEncoding())
PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +365,8 @@ dblink_connect(PG_FUNCTION_ARGS)
errdetail_internal("%s", msg)));
}
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* check password actually used if not superuser */
dblink_security_check(conn, connname, connstr);
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..53df8fab394 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -472,6 +472,30 @@ pgfdw_security_check(const char **keywords, const char **values, UserMapping *us
errhint("Target server's authentication method must be changed or password_required=false set in the user mapping attributes.")));
}
+/*
+ * notice_processor
+ *
+ * Custom notice processor for libpq connections used by postgres_fdw.
+ * This function captures NOTICE messages sent by the remote server and
+ * redirects them to PostgreSQL's logging facility using ereport().
+ *
+ * Strips trailing newline characters from messages for cleaner logs.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("Received message from remote server: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("Received message from remote server: %s", message));
+}
+
/*
* Connect to remote server using specified server and user mapping properties.
*/
@@ -625,6 +649,8 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
server->servername),
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..40979287799 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -127,6 +127,30 @@ _PG_init(void)
WalReceiverFunctions = &PQWalReceiverFunctions;
}
+/*
+ * notice_processor
+ *
+ * Custom notice processor for libpq connections used by subscriber.
+ * This function captures NOTICE messages sent by the publisher and
+ * redirects them to logging facility using ereport().
+ *
+ * Strips trailing newline characters from messages for cleaner logs.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("Received message from publisher: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("Received message from publisher: %s", message));
+}
+
/*
* Establish the connection to the primary server.
*
@@ -232,6 +256,8 @@ 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.")));
}
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
+
/*
* Set always-secure search path for the cases where the connection is
* used to run SQL queries, so malicious users can't get control.
--
2.43.0
On Wed, Jul 16, 2025 at 2:24 AM vignesh C <vignesh21@gmail.com> wrote:
On Mon, 14 Jul 2025 at 21:36, Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2025/04/15 13:37, vignesh C wrote:
Hi,
Currently, when a warning is emitted by the publisher, the
corresponding log message does not include the log prefix. This makes
it harder to correlate such messages with other log entries. For
example, in a simulated error scenario where directory removal fails,
the notice message lacks the standard log prefix, as shown below:
2025-03-18 16:44:36.071 IST [196901] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finished
WARNING: could not remove directory
"pg_replslot/pg_16398_sync_16387_7483106341004194035.tmp"In this case, the WARNING line does not include the usual timestamp
information, making it harder to trace.To address this, we can have a custom notice processor for WAL
receiver connections—similar to what's done in the attached patch.I like this idea.
If this issue also exists other features like dblink or postgres_fdw
connecting to remote PostgreSQL servers, it might be worth applying
a similar improvement there as well.Included it for dblink and fdw
Thanks! It's better to submit each change for dblink and postgres_fdw
as separate patches, and first focus on the patch that sets the notice
processor for replication connections.
+notice_processor(void *arg, const char *message) +{ + elog(LOG, "%s", message);Should ereport() be used here instead?
Yes, that is better. Modified it to ereport
Also, would it be better to add some context before %s, for example,
something like "received message from the primary:"? Without that,
users might mistakenly think the message originated from the local server.Yes, that makes sense. Updated accordingly.
For dblink and postgres_fdw, create the dblink and postgres_fdw setup
and create the below object to raise a notice:
CREATE OR REPLACE FUNCTION emit_notice(msg text) RETURNS int AS $$
BEGIN
RAISE NOTICE '%', msg;
RETURN 1;
END;
$$ LANGUAGE plpgsql;CREATE VIEW my_notice_view AS SELECT 1 AS value;
CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO my_notice_view
DO INSTEAD
SELECT 1 AS value
FROM (SELECT emit_notice('NOTICE from _RETURN rule') AS dummy) s;-- Scenario to see the notice raised by remote server using dblink
SELECT * FROM dblink('dbname=remotedb user=remoteuser', 'SELECT *
FROM my_notice_view') AS t(value int);-- Scenario to see the notice raised by remote server using postgres_fdw
IMPORT FOREIGN SCHEMA public LIMIT TO (my_notice_view) FROM SERVER
foreign_server INTO public;The attached v2 version patch has the changes for the same.
Thanks for updating the patch!
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("Received message from publisher: %.*s",
+ (int) (len - 1), message));
Do we really need to trim the trailing newline? Are there actual
WARNING/NOTICE/INFO messages that include an unnecessary newline?
"Received" should be lowercase, i.e., "received" since the primary log message
should start with a lowercase letter, according to the Error Message
Style Guide [1]https://www.postgresql.org/docs/devel/error-style-guide.html.
The phrase "from publisher" could be misleading, since the sender might be
a primary in physical replication, not necessarily a logical publisher.
Maybe something like "received message via replication" would be clearer?
I'd like to hear others' thoughts on a better wording.
Regards,
[1]: https://www.postgresql.org/docs/devel/error-style-guide.html
--
Fujii Masao
On Wed, 16 Jul 2025 at 09:09, Fujii Masao <masao.fujii@gmail.com> wrote:
Included it for dblink and fdw
Thanks! It's better to submit each change for dblink and postgres_fdw
as separate patches, and first focus on the patch that sets the notice
processor for replication connections.
Modified
+notice_processor(void *arg, const char *message) +{ + elog(LOG, "%s", message);Should ereport() be used here instead?
Yes, that is better. Modified it to ereport
Also, would it be better to add some context before %s, for example,
something like "received message from the primary:"? Without that,
users might mistakenly think the message originated from the local server.Yes, that makes sense. Updated accordingly.
For dblink and postgres_fdw, create the dblink and postgres_fdw setup
and create the below object to raise a notice:
CREATE OR REPLACE FUNCTION emit_notice(msg text) RETURNS int AS $$
BEGIN
RAISE NOTICE '%', msg;
RETURN 1;
END;
$$ LANGUAGE plpgsql;CREATE VIEW my_notice_view AS SELECT 1 AS value;
CREATE OR REPLACE RULE "_RETURN" AS
ON SELECT TO my_notice_view
DO INSTEAD
SELECT 1 AS value
FROM (SELECT emit_notice('NOTICE from _RETURN rule') AS dummy) s;-- Scenario to see the notice raised by remote server using dblink
SELECT * FROM dblink('dbname=remotedb user=remoteuser', 'SELECT *
FROM my_notice_view') AS t(value int);-- Scenario to see the notice raised by remote server using postgres_fdw
IMPORT FOREIGN SCHEMA public LIMIT TO (my_notice_view) FROM SERVER
foreign_server INTO public;The attached v2 version patch has the changes for the same.
Thanks for updating the patch!
+ /* Trim trailing newline for cleaner logs */ + size_t len = strlen(message); + + if (len > 0 && message[len - 1] == '\n') + ereport(LOG, + errmsg("Received message from publisher: %.*s", + (int) (len - 1), message));Do we really need to trim the trailing newline? Are there actual
WARNING/NOTICE/INFO messages that include an unnecessary newline?
If we don't trim the trailing newline, an extra blank line will appear
after the message is printed, like this:
2025-07-16 12:44:20.076 IST [534376] LOG: logical replication table
synchronization worker for subscription "sub1", table "t2" has started
2025-07-16 12:44:20.294 IST [534374] LOG: received message via
replication: WARNING: could not remove directory
"pg_replslot/pg_16396_sync_16384_7527574647116269356.tmp"
2025-07-16 12:44:20.294 IST [534374] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finished
This occurs because a newline is appended to the message in
pqBuildErrorMessage3, which is called when the message is received in
pqGetErrorNotice3:
...
}
appendPQExpBufferChar(msg, '\n');
if (verbosity != PQERRORS_TERSE)
...
"Received" should be lowercase, i.e., "received" since the primary log message
should start with a lowercase letter, according to the Error Message
Style Guide [1].
Modified
The phrase "from publisher" could be misleading, since the sender might be
a primary in physical replication, not necessarily a logical publisher.
Maybe something like "received message via replication" would be clearer?
I'd like to hear others' thoughts on a better wording.
Modified the message to "received message via replication." Will
update it further if we get any better wording.
The attached v3 version patch has the changes for the same.
Regards,
Vignesh
Attachments:
v3-0003-Add-custom-PQsetNoticeProcessor-handlers-for-fdw-.patchapplication/octet-stream; name=v3-0003-Add-custom-PQsetNoticeProcessor-handlers-for-fdw-.patchDownload
From ef3a120e0ccf74c402f5bacec1c324b12d50356c Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:32:41 +0530
Subject: [PATCH v3 3/3] Add custom PQsetNoticeProcessor handlers for fdw
connection
This patch introduces a custom notice processor for libpq-based
connections in fdw connection. The notice processor captures
messages and routes them through ereport(), making them visible
in local logs with a prefix making it easy for diagnosis.
---
contrib/postgres_fdw/connection.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..e0f5fb595e3 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -472,6 +472,24 @@ pgfdw_security_check(const char **keywords, const char **values, UserMapping *us
errhint("Target server's authentication method must be changed or password_required=false set in the user mapping attributes.")));
}
+/*
+ * Custom notice processor for libpq connections used by postgres_fdw.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("received message from remote server: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("received message from remote server: %s", message));
+}
+
/*
* Connect to remote server using specified server and user mapping properties.
*/
@@ -625,6 +643,8 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
server->servername),
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
--
2.43.0
v3-0002-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchapplication/octet-stream; name=v3-0002-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchDownload
From aae0a76c609bb83972a4ec7625c567810e2d172e Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:31:54 +0530
Subject: [PATCH v3 2/3] Add custom PQsetNoticeProcessor handlers for dblink
connection
This patch introduces a custom notice processor for libpq-based
connections in dblink connection. The notice processor 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 | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..42b96c314db 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -177,6 +177,24 @@ xpstrdup(const char *in)
return pstrdup(in);
}
+/*
+ * Custom notice processor for libpq connections used by dblink.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("received message from remote server: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("received message from remote server: %s", message));
+}
+
pg_noreturn static void
dblink_res_internalerror(PGconn *conn, PGresult *res, const char *p2)
{
@@ -240,6 +258,9 @@ dblink_get_conn(char *conname_or_str,
errmsg("could not establish connection"),
errdetail_internal("%s", msg)));
}
+
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
dblink_security_check(conn, NULL, connstr);
if (PQclientEncoding(conn) != GetDatabaseEncoding())
PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +359,8 @@ dblink_connect(PG_FUNCTION_ARGS)
errdetail_internal("%s", msg)));
}
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* check password actually used if not superuser */
dblink_security_check(conn, connname, connstr);
--
2.43.0
v3-0001-Add-custom-PQsetNoticeProcessor-handlers-for-repl.patchapplication/octet-stream; name=v3-0001-Add-custom-PQsetNoticeProcessor-handlers-for-repl.patchDownload
From e5f553ad5787fb0a5f8783e18e3776740a08e8a0 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:26:12 +0530
Subject: [PATCH v3 1/3] Add custom PQsetNoticeProcessor handlers for
replication connection
This patch introduces a custom notice processor for libpq-based
connections in replication connection. The notice processor captures
messages and routes them through ereport(), making them visible in
local logs with a prefix making it easy for diagnosis.
---
.../libpqwalreceiver/libpqwalreceiver.c | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..93b71805df4 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -127,6 +127,24 @@ _PG_init(void)
WalReceiverFunctions = &PQWalReceiverFunctions;
}
+/*
+ * Custom notice processor for libpq connections used by replication.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("received message via replication: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("received message via replication: %s", message));
+}
+
/*
* Establish the connection to the primary server.
*
@@ -232,6 +250,8 @@ 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.")));
}
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
+
/*
* Set always-secure search path for the cases where the connection is
* used to run SQL queries, so malicious users can't get control.
--
2.43.0
On 2025/07/16 19:45, vignesh C wrote:
If we don't trim the trailing newline, an extra blank line will appear
after the message is printed, like this:
2025-07-16 12:44:20.076 IST [534376] LOG: logical replication table
synchronization worker for subscription "sub1", table "t2" has started
2025-07-16 12:44:20.294 IST [534374] LOG: received message via
replication: WARNING: could not remove directory
"pg_replslot/pg_16396_sync_16384_7527574647116269356.tmp"2025-07-16 12:44:20.294 IST [534374] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finishedThis occurs because a newline is appended to the message in
pqBuildErrorMessage3, which is called when the message is received in
pqGetErrorNotice3:
...
}
appendPQExpBufferChar(msg, '\n');
if (verbosity != PQERRORS_TERSE)
...
You're right, the message text passed to the notice processor includes
a trailing newline. I confirmed this is documented in the PQsetNoticeProcessor
docs [1]https://www.postgresql.org/docs/devel/libpq-notice-processing.html, so I agree it's reasonable to trim the newline for cleaner log output.
Regarding the current implementation:
+ /* Trim trailing newline for cleaner logs */
+ size_t len = strlen(message);
+
+ if (len > 0 && message[len - 1] == '\n')
+ ereport(LOG,
+ errmsg("received message via replication: %.*s",
+ (int) (len - 1), message));
+ else
+ ereport(LOG,
+ errmsg("received message via replication: %s", message));
To avoid repeating ereport(), how about refactoring it like this?
I think it's simpler and easier to read:
---------------------------------------
/*
* Custom notice processor for replication connection.
*/
static void
notice_processor(void *arg, const char *message)
{
int len;
/*
* Trim the trailing newline from the message text passed to the notice
* processor, as it always includes one, to produce cleaner log output.
*/
len = strlen(message);
if (len > 0 && message[len - 1] == '\n')
len--;
ereport(LOG,
errmsg("received message via replication: %.*s",
len, message));
}
---------------------------------------
Also, I suggest adding the prototype for notice_processor() in libpqwalreceiver.c:
---------------------------------------
/* Prototypes for private functions */
static void notice_processor(void *arg, const char *message);
static char *stringlist_to_identifierstr(PGconn *conn, List *strings);
---------------------------------------
Currently, notice_processor() is placed just before libpqrcv_connect(),
but I think it would be better to move it before stringlist_to_identifierstr(),
since the libpqwalreceiver.c seems to follow a structure where private
functions come after the libpqrcv_* functions.
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
It might be helpful to add a comment explaining the purpose, such as:
Set a custom notice processor so that notice, warning, and similar messages
received via the replication connection are logged in our preferred style,
instead of just being printed to stderr.
Thought?
The phrase "from publisher" could be misleading, since the sender might be
a primary in physical replication, not necessarily a logical publisher.
Maybe something like "received message via replication" would be clearer?
I'd like to hear others' thoughts on a better wording.Modified the message to "received message via replication." Will
update it further if we get any better wording.
+1
Regards,
[1]: https://www.postgresql.org/docs/devel/libpq-notice-processing.html
--
Fujii Masao
NTT DATA Japan Corporation
On Wed, 16 Jul 2025 at 21:30, Fujii Masao <masao.fujii@oss.nttdata.com> wrote:
On 2025/07/16 19:45, vignesh C wrote:
If we don't trim the trailing newline, an extra blank line will appear
after the message is printed, like this:
2025-07-16 12:44:20.076 IST [534376] LOG: logical replication table
synchronization worker for subscription "sub1", table "t2" has started
2025-07-16 12:44:20.294 IST [534374] LOG: received message via
replication: WARNING: could not remove directory
"pg_replslot/pg_16396_sync_16384_7527574647116269356.tmp"2025-07-16 12:44:20.294 IST [534374] LOG: logical replication table
synchronization worker for subscription "sub1", table "t1" has
finishedThis occurs because a newline is appended to the message in
pqBuildErrorMessage3, which is called when the message is received in
pqGetErrorNotice3:
...
}
appendPQExpBufferChar(msg, '\n');
if (verbosity != PQERRORS_TERSE)
...You're right, the message text passed to the notice processor includes
a trailing newline. I confirmed this is documented in the PQsetNoticeProcessor
docs [1], so I agree it's reasonable to trim the newline for cleaner log output.Regarding the current implementation: + /* Trim trailing newline for cleaner logs */ + size_t len = strlen(message); + + if (len > 0 && message[len - 1] == '\n') + ereport(LOG, + errmsg("received message via replication: %.*s", + (int) (len - 1), message)); + else + ereport(LOG, + errmsg("received message via replication: %s", message));To avoid repeating ereport(), how about refactoring it like this?
I think it's simpler and easier to read:---------------------------------------
/*
* Custom notice processor for replication connection.
*/
static void
notice_processor(void *arg, const char *message)
{
int len;/*
* Trim the trailing newline from the message text passed to the notice
* processor, as it always includes one, to produce cleaner log output.
*/
len = strlen(message);
if (len > 0 && message[len - 1] == '\n')
len--;ereport(LOG,
errmsg("received message via replication: %.*s",
len, message));
}
---------------------------------------
Looks good, modified
Also, I suggest adding the prototype for notice_processor() in libpqwalreceiver.c:
---------------------------------------
/* Prototypes for private functions */
static void notice_processor(void *arg, const char *message);
static char *stringlist_to_identifierstr(PGconn *conn, List *strings);
---------------------------------------Currently, notice_processor() is placed just before libpqrcv_connect(),
but I think it would be better to move it before stringlist_to_identifierstr(),
since the libpqwalreceiver.c seems to follow a structure where private
functions come after the libpqrcv_* functions.
Modified
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
It might be helpful to add a comment explaining the purpose, such as:
Set a custom notice processor so that notice, warning, and similar messages
received via the replication connection are logged in our preferred style,
instead of just being printed to stderr.
Modified
The attached v4 version patch has the changes for the same.
Regards,
Vignesh
Attachments:
v4-0001-Add-custom-PQsetNoticeProcessor-handlers-for-repl.patchtext/x-patch; charset=US-ASCII; name=v4-0001-Add-custom-PQsetNoticeProcessor-handlers-for-repl.patchDownload
From 2460fbd0a5c6a1be425cdaf92daa2800407e4fcb Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:26:12 +0530
Subject: [PATCH v4 1/3] Add custom PQsetNoticeProcessor handlers for
replication connection
This patch introduces a custom notice processor for libpq-based
connections in replication connection. The notice processor captures
messages and routes them through ereport(), making them visible in
local logs with a prefix making it easy for diagnosis.
---
.../libpqwalreceiver/libpqwalreceiver.c | 28 +++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..689333d7c52 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -114,6 +114,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = {
};
/* Prototypes for private functions */
+static void notice_processor(void *arg, const char *message);
static char *stringlist_to_identifierstr(PGconn *conn, List *strings);
/*
@@ -232,6 +233,13 @@ 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.")));
}
+ /*
+ * Set a custom notice processor so that NOTICEs, WARNINGs, and similar
+ * messages from the replication connection are reported via ereport(),
+ * instead of being printed to stderr.
+ */
+ PQsetNoticeProcessor(conn->streamConn, notice_processor, NULL);
+
/*
* Set always-secure search path for the cases where the connection is
* used to run SQL queries, so malicious users can't get control.
@@ -1195,6 +1203,26 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query,
return walres;
}
+/*
+ * Custom notice processor for replication connection.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ int len;
+
+ /*
+ * Trim the trailing newline from the message text passed to the notice
+ * processor, as it always includes one, to produce cleaner log output.
+ */
+ len = strlen(message);
+ if (len > 0 && message[len - 1] == '\n')
+ len--;
+
+ ereport(LOG,
+ errmsg("received message via replication: %.*s", len, message));
+}
+
/*
* Given a List of strings, return it as single comma separated
* string, quoting identifiers as needed.
--
2.43.0
v4-0002-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchtext/x-patch; charset=US-ASCII; name=v4-0002-Add-custom-PQsetNoticeProcessor-handlers-for-dbli.patchDownload
From 9a0c0ce671d3860f1611c4ca1ec7cf55ab43e6e4 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:31:54 +0530
Subject: [PATCH v4 2/3] Add custom PQsetNoticeProcessor handlers for dblink
connection
This patch introduces a custom notice processor for libpq-based
connections in dblink connection. The notice processor 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 | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..30509f9ff32 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_processor(void *arg, const char *message);
/* 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 processor so that NOTICEs, WARNINGs, and
+ * similar messages from the remote server connection are reported via
+ * ereport(), instead of being printed to stderr.
+ */
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
dblink_security_check(conn, NULL, connstr);
if (PQclientEncoding(conn) != GetDatabaseEncoding())
PQsetClientEncoding(conn, GetDatabaseEncodingName());
@@ -338,6 +347,8 @@ dblink_connect(PG_FUNCTION_ARGS)
errdetail_internal("%s", msg)));
}
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* check password actually used if not superuser */
dblink_security_check(conn, connname, connstr);
@@ -2670,6 +2681,26 @@ dblink_connstr_has_required_scram_options(const char *connstr)
return (has_scram_keys && has_require_auth);
}
+/*
+ * Custom notice processor for remote server connection.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ int len;
+
+ /*
+ * Trim the trailing newline from the message text passed to the notice
+ * processor, as it always includes one, to produce cleaner log output.
+ */
+ 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
v4-0003-Add-custom-PQsetNoticeProcessor-handlers-for-fdw-.patchtext/x-patch; charset=US-ASCII; name=v4-0003-Add-custom-PQsetNoticeProcessor-handlers-for-fdw-.patchDownload
From 880d19658fdc3f9d4e31b1e6f1be670e1cb3dd46 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:32:41 +0530
Subject: [PATCH v4 3/3] Add custom PQsetNoticeProcessor handlers for fdw
connection
This patch introduces a custom notice processor for libpq-based
connections in fdw connection. The notice processor captures
messages and routes them through ereport(), making them visible
in local logs with a prefix making it easy for diagnosis.
---
contrib/postgres_fdw/connection.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..53264ecbf93 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -472,6 +472,26 @@ pgfdw_security_check(const char **keywords, const char **values, UserMapping *us
errhint("Target server's authentication method must be changed or password_required=false set in the user mapping attributes.")));
}
+/*
+ * Custom notice processor for remote server connection.
+ */
+static void
+notice_processor(void *arg, const char *message)
+{
+ int len;
+
+ /*
+ * Trim the trailing newline from the message text passed to the notice
+ * processor, as it always includes one, to produce cleaner log output.
+ */
+ len = strlen(message);
+ if (len > 0 && message[len - 1] == '\n')
+ len--;
+
+ ereport(LOG,
+ errmsg("received message from remote server: %.*s", len, message));
+}
+
/*
* Connect to remote server using specified server and user mapping properties.
*/
@@ -625,6 +645,13 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
server->servername),
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
+ /*
+ * Set a custom notice processor so that NOTICEs, WARNINGs, and
+ * similar messages from the remote server connection are reported via
+ * ereport(), instead of being printed to stderr.
+ */
+ PQsetNoticeProcessor(conn, notice_processor, NULL);
+
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
--
2.43.0
Hi,
Shouldn't we be using a notice receiver rather than a notice processor?
--
Álvaro Herrera
On Thu, 17 Jul 2025 at 11:18, Álvaro Herrera <alvherre@kurilemu.de> wrote:
Hi,
Shouldn't we be using a notice receiver rather than a notice processor?
I saw the following comment in code regarding PQsetNoticeProcessor
should be deprecated:
/*
* The default notice message receiver just gets the standard notice text
* and sends it to the notice processor. This two-level setup exists
* mostly for backwards compatibility; perhaps we should deprecate use of
* PQsetNoticeProcessor?
*/
So I changed it to PQsetNoticeReceiver. The attached v5 version patch
has the changes for the same.
Regards,
Vignesh
Attachments:
v5-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchtext/x-patch; charset=US-ASCII; name=v5-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchDownload
From 8a0d5392f482572ebd57a6eae30c715c81b31963 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:26:12 +0530
Subject: [PATCH v5 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 | 30 +++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..7d1031139ac 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -114,6 +114,7 @@ static WalReceiverFunctionsType PQWalReceiverFunctions = {
};
/* Prototypes for private functions */
+static void notice_receiver(void *arg, const PGresult *result);
static char *stringlist_to_identifierstr(PGconn *conn, List *strings);
/*
@@ -232,6 +233,13 @@ 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.")));
}
+ /*
+ * Set a custom notice receiver so that NOTICEs, WARNINGs, and similar
+ * messages from the replication connection are reported via ereport(),
+ * instead of being printed to stderr.
+ */
+ PQsetNoticeReceiver(conn->streamConn, notice_receiver, NULL);
+
/*
* Set always-secure search path for the cases where the connection is
* used to run SQL queries, so malicious users can't get control.
@@ -1195,6 +1203,28 @@ libpqrcv_exec(WalReceiverConn *conn, const char *query,
return walres;
}
+/*
+ * Custom notice receiver for replication 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 via replication: %.*s", len, message));
+}
+
/*
* Given a List of strings, return it as single comma separated
* string, quoting identifiers as needed.
--
2.43.0
v5-0003-Add-custom-PQsetNoticeReceiver-handlers-for-remot.patchtext/x-patch; charset=US-ASCII; name=v5-0003-Add-custom-PQsetNoticeReceiver-handlers-for-remot.patchDownload
From c4f76b90d6be701e50bd3fff271f77565cd8d212 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:32:41 +0530
Subject: [PATCH v5 3/3] Add custom PQsetNoticeReceiver handlers for remote
server connection in fdw
This patch introduces a custom notice receiver for remote
server connection in fdw. 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/postgres_fdw/connection.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..babd78914fb 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -472,6 +472,28 @@ pgfdw_security_check(const char **keywords, const char **values, UserMapping *us
errhint("Target server's authentication method must be changed or password_required=false set in the user mapping attributes.")));
}
+/*
+ * 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));
+}
+
/*
* Connect to remote server using specified server and user mapping properties.
*/
@@ -625,6 +647,13 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
server->servername),
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
+ /*
+ * 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);
+
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
--
2.43.0
v5-0002-Add-custom-PQsetNoticeReceiver-handlers-for-remot.patchtext/x-patch; charset=US-ASCII; name=v5-0002-Add-custom-PQsetNoticeReceiver-handlers-for-remot.patchDownload
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
On 2025/07/17 17:05, vignesh C wrote:
On Thu, 17 Jul 2025 at 11:18, Álvaro Herrera <alvherre@kurilemu.de> wrote:
Hi,
Shouldn't we be using a notice receiver rather than a notice processor?
I saw the following comment in code regarding PQsetNoticeProcessor
should be deprecated:
/*
* The default notice message receiver just gets the standard notice text
* and sends it to the notice processor. This two-level setup exists
* mostly for backwards compatibility; perhaps we should deprecate use of
* PQsetNoticeProcessor?
*/So I changed it to PQsetNoticeReceiver.
+1
As a side note, I'd like to clarify in the source comments or documentation
that PQsetNoticeProcessor() exists mainly for backward compatibility,
and PQsetNoticeReceiver() should be preferred. But that's a separate topic
from this patch.
The attached v5 version patch
has the changes for the same.
Thanks for updating the patches!
+static void notice_receiver(void *arg, const PGresult *result);
For consistency with the typedef for PQnoticeReceiver, it would be better
to name the argument "res" instead of "result".
+ * Set a custom notice receiver so that NOTICEs, WARNINGs, and similar
The "s" in "NOTICEs" and "WARNINGs" isn't needed.
+ * Trim the trailing newline from the message text passed to the notice
+ * receiver, as it always includes one, to produce cleaner log output.
"message text passed to the notice receiver" should be changed to
"message text returned by PQresultErrorMessage()"?
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
On 2025/07/17 23:34, Fujii Masao wrote:
The attached v5 version patch
has the changes for the same.Thanks for updating the patches!
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?
--------------------
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("received message %s: %.*s", prefix, len, message));
}
--------------------
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
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.
--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
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 likeereport(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!
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
On Fri, 18 Jul 2025 at 04:46, Fujii Masao <masao.fujii@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 likeereport(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
Attachments:
v6-0003-Use-libpqsrv_notice_receiver-for-remote-server-co.patchtext/x-patch; charset=US-ASCII; name=v6-0003-Use-libpqsrv_notice_receiver-for-remote-server-co.patchDownload
From 4d40ae938e97f5d1b4dc8ec99f6bc0adde57ed2e Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@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
v6-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchtext/x-patch; charset=US-ASCII; name=v6-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchDownload
From 65061ce7de2ba20386a3d28a81c6ae0db005e9da Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@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
v6-0002-Use-libpqsrv_notice_receiver-for-remote-server-co.patchtext/x-patch; charset=US-ASCII; name=v6-0002-Use-libpqsrv_notice_receiver-for-remote-server-co.patchDownload
From 9c837f55239b8ae09eb4702db7c06d6d38acbe8b Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@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
On 2025-Jul-18, vignesh C wrote:
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"); +
These need to be:
PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
gettext_noop("received message via remote connection"));
so that the strings are picked up by gettext.
Also, I don't see why there are three patches here instead of just one.
--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
On Sat, 19 Jul 2025 at 01:39, Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-18, vignesh C wrote:
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"); +These need to be:
PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
gettext_noop("received message via remote connection"));so that the strings are picked up by gettext.
Modified
Also, I don't see why there are three patches here instead of just one.
Earlier we thought to commit replication changes function firstlly and
then commit dblink and fdw changes, but now that we are using a common
notice receiver function. I feel it can be a single patch. Merged the
patches. The attached v7 version patch has the changes for the same.
Regards,
Vignesh
Attachments:
v7-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchtext/x-patch; charset=US-ASCII; name=v7-0001-Add-custom-PQsetNoticeReceiver-handlers-for-repli.patchDownload
From 5807449c0bca1f9a6a407aebd9958d6ac0c9c902 Mon Sep 17 00:00:00 2001
From: Vignesh C <vignesh21@gmail.com>
Date: Wed, 16 Jul 2025 15:26:12 +0530
Subject: [PATCH v7] Add custom PQsetNoticeReceiver handlers for
replication/fdw/dblink connection
This patch introduces a custom notice receiver for
replication/fdw/dblink 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.
---
contrib/dblink/dblink.c | 7 +++++
contrib/postgres_fdw/connection.c | 3 ++
.../libpqwalreceiver/libpqwalreceiver.c | 3 ++
src/include/libpq/libpq-be-fe-helpers.h | 31 +++++++++++++++++++
4 files changed, 44 insertions(+)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8a0b112a7ff..c459a842fa9 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,
+ gettext_noop("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,
+ gettext_noop("received message via remote connection"));
+
/* check password actually used if not superuser */
dblink_security_check(conn, connname, connstr);
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 304f3c20f83..e41d47c3bbd 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,
+ gettext_noop("received message via remote connection"));
+
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index f7b5d093681..0c75fe064d5 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,
+ gettext_noop("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
On 2025/07/19 15:45, vignesh C wrote:
Also, I don't see why there are three patches here instead of just one.
Earlier we thought to commit replication changes function firstlly and
then commit dblink and fdw changes, but now that we are using a common
notice receiver function. I feel it can be a single patch.
Yes, I initially suggested splitting the patches for that reason,
but I agree it's better to merge them into a single patch now that
we're using a shared custom notice receiver.
Merged the
patches. The attached v7 version patch has the changes for the same.
Thanks for updating the patch! It looks good to me, except for one minor point:
static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_notice_receiver(void *arg, const PGresult *res);
This prototype is only needed if the function is used earlier in libpq-be-fe-helpers.h,
but that's not the case here, so I don't think it's necessary.
Unless there are objections, I'll remove that prototype and commit the patch.
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
On 2025-Jul-21, Fujii Masao wrote:
Thanks for updating the patch! It looks good to me, except for one minor point:
static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_notice_receiver(void *arg, const PGresult *res);This prototype is only needed if the function is used earlier in libpq-be-fe-helpers.h,
but that's not the case here, so I don't think it's necessary.Unless there are objections, I'll remove that prototype and commit the patch.
LGTM.
--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Debido a que la velocidad de la luz es mucho mayor que la del sonido,
algunas personas nos parecen brillantes un minuto antes
de escuchar las pelotudeces que dicen." (Roberto Fontanarrosa)
On Mon, Jul 21, 2025 at 5:51 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-21, Fujii Masao wrote:
Thanks for updating the patch! It looks good to me, except for one minor point:
static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_notice_receiver(void *arg, const PGresult *res);This prototype is only needed if the function is used earlier in libpq-be-fe-helpers.h,
but that's not the case here, so I don't think it's necessary.Unless there are objections, I'll remove that prototype and commit the patch.
LGTM.
I've pushed the patch. Thanks!
Regards,
--
Fujii Masao
On 2025/07/22 14:29, Fujii Masao wrote:
On Mon, Jul 21, 2025 at 5:51 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-21, Fujii Masao wrote:
Thanks for updating the patch! It looks good to me, except for one minor point:
static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_notice_receiver(void *arg, const PGresult *res);This prototype is only needed if the function is used earlier in libpq-be-fe-helpers.h,
but that's not the case here, so I don't think it's necessary.Unless there are objections, I'll remove that prototype and commit the patch.
LGTM.
I've pushed the patch. Thanks!
The buildfarm member indri reported the following error, which seems related to
the recent changes in dblink. I'll investigate this later.
/Library/Developer/CommandLineTools/usr/bin/make -C intagg all
make[1]: Nothing to be done for `all'.
/opt/local/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv -fexcess-precision=standard -mno-outline-atomics -Wno-unused-command-line-argument -Wno-compound-token-split-by-macro -Wno-format-truncation -O2 -I. -I. -I../../src/include -I/opt/local/include -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX15.5.sdk -I/opt/local/include/libxml2 -I/opt/local/include -I/opt/local/include -I/opt/local/include -I/opt/local/include -flto=thin -emit-llvm -c -o fuzzystrmatch.bc fuzzystrmatch.c
Undefined symbols for architecture arm64:
"_libintl_gettext", referenced from:
_libpqsrv_notice_receiver in dblink.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [dblink.dylib] Error 1
make: *** [all-dblink-recurse] Error 2
make: *** Waiting for unfinished jobs....
Regards,
--
Fujii Masao
NTT DATA Japan Corporation
On 2025-07-22, Fujii Masao wrote:
The buildfarm member indri reported the following error, which seems related to
the recent changes in dblink. I'll investigate this later.
Ah yes — contrib doesn't have gettext support and macOS doesn't like that. Maybe removing the gettext_noop calls in contrib is the easiest solution. I think another option is to add -lintl to the link line but that's probably messier, and without advantage since we still won't have translation support.
--
Álvaro Herrera
On 2025-Jul-22, Álvaro Herrera wrote:
On 2025-07-22, Fujii Masao wrote:
The buildfarm member indri reported the following error, which seems related to
the recent changes in dblink. I'll investigate this later.Ah yes — contrib doesn't have gettext support and macOS doesn't like
that. Maybe removing the gettext_noop calls in contrib is the easiest
solution. I think another option is to add -lintl to the link line but
that's probably messier, and without advantage since we still won't
have translation support.
I wonder why doesn't contrib/basic_archive fail though.
--
Álvaro Herrera PostgreSQL Developer — https://www.EnterpriseDB.com/
"Saca el libro que tu religión considere como el indicado para encontrar la
oración que traiga paz a tu alma. Luego rebootea el computador
y ve si funciona" (Carlos Duclós)
On Tue, Jul 22, 2025 at 6:24 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-22, Álvaro Herrera wrote:
On 2025-07-22, Fujii Masao wrote:
The buildfarm member indri reported the following error, which seems related to
the recent changes in dblink. I'll investigate this later.Ah yes — contrib doesn't have gettext support and macOS doesn't like
that. Maybe removing the gettext_noop calls in contrib is the easiest
solution. I think another option is to add -lintl to the link line but
that's probably messier, and without advantage since we still won't
have translation support.I wonder why doesn't contrib/basic_archive fail though.
Is the issue caused by the use of _() in libpq-be-fe-helpers.h,
instead of using gettext_noop() in dblink.c? At least in my test
environment, the build error disappeared after applying
the following change:
- errmsg_internal("%s: %.*s", _(prefix), len, message));
+ errmsg_internal("%s: %.*s", prefix, len, message));
Regards,
--
Fujii Masao
On 2025-Jul-22, Fujii Masao wrote:
Is the issue caused by the use of _() in libpq-be-fe-helpers.h,
instead of using gettext_noop() in dblink.c? At least in my test
environment, the build error disappeared after applying
the following change:- errmsg_internal("%s: %.*s", _(prefix), len, message)); + errmsg_internal("%s: %.*s", prefix, len, message));
Oh yeah, I should have remembered this -- see commit 213c959a294d. Feel
free to do away with the whole translation thing ... doesn't seem worth
spending more time on it.
We should still remove all gettext_noop() markers in contrib :-)
--
Álvaro Herrera Breisgau, Deutschland — https://www.EnterpriseDB.com/
On Tue, Jul 22, 2025 at 8:47 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-22, Fujii Masao wrote:
Is the issue caused by the use of _() in libpq-be-fe-helpers.h,
instead of using gettext_noop() in dblink.c? At least in my test
environment, the build error disappeared after applying
the following change:- errmsg_internal("%s: %.*s", _(prefix), len, message)); + errmsg_internal("%s: %.*s", prefix, len, message));Oh yeah, I should have remembered this -- see commit 213c959a294d. Feel
free to do away with the whole translation thing ... doesn't seem worth
spending more time on it.
Yes! The attached patch removes the translation marker and the
gettext_noop() calls I recently added.
We should still remove all gettext_noop() markers in contrib :-)
You mean to remove gettext_noop() also from basic_archive.c?
Regards,
--
Fujii Masao
Attachments:
v1-0001-Remove-translation-marker-from-libpq-be-fe-helper.patchapplication/octet-stream; name=v1-0001-Remove-translation-marker-from-libpq-be-fe-helper.patchDownload
From f1d58b9fb39bb9b029147688c422d2d7c9a633b0 Mon Sep 17 00:00:00 2001
From: Fujii Masao <fujii@postgresql.org>
Date: Tue, 22 Jul 2025 21:01:57 +0900
Subject: [PATCH v1] Remove translation marker from libpq-be-fe-helpers.h.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit 112faf1378e introduced a translation marker in libpq-be-fe-helpers.h,
but this caused build failures on some platforms—such as the one reported
by buildfarm member indri—due to linker issues with dblink. This is the same
problem previously addressed in commit 213c959a294.
To fix the issue, this commit removes the translation marker from
libpq-be-fe-helpers.h, following the approach used in 213c959a294.
It also removes the associated gettext_noop() calls added in 112faf1378e,
as they are no longer needed.
Per buildfarm member indri.
Discussion: https://postgr.es/m/0e6299d9-608a-4ffa-aeb1-40cb8a99000b@oss.nttdata.com
---
contrib/dblink/dblink.c | 4 ++--
contrib/postgres_fdw/connection.c | 2 +-
src/backend/replication/libpqwalreceiver/libpqwalreceiver.c | 2 +-
src/include/libpq/libpq-be-fe-helpers.h | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c459a842fa9..de5bed282f3 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -242,7 +242,7 @@ dblink_get_conn(char *conname_or_str,
}
PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
- gettext_noop("received message via remote connection"));
+ "received message via remote connection");
dblink_security_check(conn, NULL, connstr);
if (PQclientEncoding(conn) != GetDatabaseEncoding())
@@ -343,7 +343,7 @@ dblink_connect(PG_FUNCTION_ARGS)
}
PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
- gettext_noop("received message via remote connection"));
+ "received message via remote connection");
/* check password actually used if not superuser */
dblink_security_check(conn, connname, connstr);
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index e41d47c3bbd..c1ce6f33436 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -626,7 +626,7 @@ connect_pg_server(ForeignServer *server, UserMapping *user)
errdetail_internal("%s", pchomp(PQerrorMessage(conn)))));
PQsetNoticeReceiver(conn, libpqsrv_notice_receiver,
- gettext_noop("received message via remote connection"));
+ "received message via remote connection");
/* Perform post-connection security checks. */
pgfdw_security_check(keywords, values, user, conn);
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 0c75fe064d5..886d99951dd 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -233,7 +233,7 @@ libpqrcv_connect(const char *conninfo, bool replication, bool logical,
}
PQsetNoticeReceiver(conn->streamConn, libpqsrv_notice_receiver,
- gettext_noop("received message via replication"));
+ "received message via replication");
/*
* Set always-secure search path for the cases where the connection is
diff --git a/src/include/libpq/libpq-be-fe-helpers.h b/src/include/libpq/libpq-be-fe-helpers.h
index 49137a0a570..af13bd6bf3d 100644
--- a/src/include/libpq/libpq-be-fe-helpers.h
+++ b/src/include/libpq/libpq-be-fe-helpers.h
@@ -481,7 +481,7 @@ libpqsrv_notice_receiver(void *arg, const PGresult *res)
len--;
ereport(LOG,
- errmsg_internal("%s: %.*s", _(prefix), len, message));
+ errmsg_internal("%s: %.*s", prefix, len, message));
}
#endif /* LIBPQ_BE_FE_HELPERS_H */
--
2.50.1
On 2025-Jul-22, Fujii Masao wrote:
On Tue, Jul 22, 2025 at 8:47 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
Oh yeah, I should have remembered this -- see commit 213c959a294d. Feel
free to do away with the whole translation thing ... doesn't seem worth
spending more time on it.Yes! The attached patch removes the translation marker and the
gettext_noop() calls I recently added.
LGTM.
We should still remove all gettext_noop() markers in contrib :-)
You mean to remove gettext_noop() also from basic_archive.c?
Yes, it's useless and misleading. Feel free to do it in the same commit ...
--
Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/
"The ability of users to misuse tools is, of course, legendary" (David Steele)
/messages/by-id/11b38a96-6ded-4668-b772-40f992132797@pgmasters.net
On 22/7/2025 14:49, Álvaro Herrera wrote:
On 2025-Jul-22, Fujii Masao wrote:
We should still remove all gettext_noop() markers in contrib :-)
You mean to remove gettext_noop() also from basic_archive.c?
Yes, it's useless and misleading. Feel free to do it in the same commit ...
Just for the record. This patch obviously resolves my issue [1]/messages/by-id/39ac724e-58c8-4661-9e88-cb4ee97cb00e@gmail.com too ...
[1]: /messages/by-id/39ac724e-58c8-4661-9e88-cb4ee97cb00e@gmail.com
/messages/by-id/39ac724e-58c8-4661-9e88-cb4ee97cb00e@gmail.com
--
regards, Andrei Lepikhov
On Tue, Jul 22, 2025 at 9:49 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-22, Fujii Masao wrote:
On Tue, Jul 22, 2025 at 8:47 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
Oh yeah, I should have remembered this -- see commit 213c959a294d. Feel
free to do away with the whole translation thing ... doesn't seem worth
spending more time on it.Yes! The attached patch removes the translation marker and the
gettext_noop() calls I recently added.LGTM.
Thanks for the review!
We should still remove all gettext_noop() markers in contrib :-)
You mean to remove gettext_noop() also from basic_archive.c?
Yes, it's useless and misleading. Feel free to do it in the same commit ...
I've included that change in the patch and pushed it. Thanks!
Regards,
--
Fujii Masao
On Tue, 22 Jul 2025 at 18:43, Fujii Masao <masao.fujii@gmail.com> wrote:
On Tue, Jul 22, 2025 at 9:49 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
On 2025-Jul-22, Fujii Masao wrote:
On Tue, Jul 22, 2025 at 8:47 PM Álvaro Herrera <alvherre@kurilemu.de> wrote:
Oh yeah, I should have remembered this -- see commit 213c959a294d. Feel
free to do away with the whole translation thing ... doesn't seem worth
spending more time on it.Yes! The attached patch removes the translation marker and the
gettext_noop() calls I recently added.LGTM.
Thanks for the review!
We should still remove all gettext_noop() markers in contrib :-)
You mean to remove gettext_noop() also from basic_archive.c?
Yes, it's useless and misleading. Feel free to do it in the same commit ...
I've included that change in the patch and pushed it. Thanks!
Thanks Fuji-san for handling and pushing this issue.
Regards,
Vignesh