On Mon, Sep 14, 2026 at 12:32:18AM -0400, Tom Lane wrote:
> Kyotaro Horiguchi <[email protected]> writes:
> > Commit cb298616463 changed the following line:
> 
> > -   printf(_("Latest checkpoint's NextOID:          %u\n"),
> > +   printf(_("Latest checkpoint's NextOID:          " OID8_FORMAT "\n"),

Oops, sorry about that.  I can see the breakage with some update-po.

>> It appears that xgettext does not recognize PostgreSQL's OID8_FORMAT
>> macro and therefore extracts only the preceding string literal as the
>> msgid. In contrast, PRIu64, which is used in the same file, is
>> correctly extracted as %<PRIu64>. Therefore, shouldn't we use "%"
>> PRIu64 instead of OID8_FORMAT here as well?

Yes, it's not the first time that 64-bit values show this problem with
translatable strings.

> That would be fairly sad, because it means hard-wiring the fact that
> Oid8 is the same as uint64 in a bunch of non-obvious places.
> Admittedly, we've lived with formatting Oid as %u for a long time.
> But can we fix this some other way?

The proposed patch to use the Pri markers would work with gettext().
Just note that, I have.. cough.. also broken pg_resetwal in two
places.

The other places switched recently (amcheck, backend) only relate to
internal errors and places without po files, so they're out of the 
picture, fine with the OID8_FORMAT markers.

Anyway, I really want to keep this code greppable with the Oid8
markers, so I don't think that the proposed patch is what I would do.
The magic solution I can think of is to remove the markers from the
translatable strings, and replace them with a set of %s, as of the
attached patch, then use a pre-built string that itself uses
OID8_FORMAT.  I am pretty sure we have used this method in other
places of the tree, but I cannot pinpoint where, on top of my mind.

The idea of documenting this trick or equivalent in c.h is interesting
in the long term, for sure.  Any suggestions how to word this
requirement close to the OID8_FORMAT declaration?

Thoughts?
--
Michael
From 00a59f976130a1bb569dce94a9f2ab32692a9c76 Mon Sep 17 00:00:00 2001
From: Michael Paquier <[email protected]>
Date: Mon, 14 Sep 2026 14:47:48 +0900
Subject: [PATCH] Fix translation of pg_resetwal and pg_controldata's NextOID
 output

xgettext() drops OID8_FORMAT and therefore extracts an incomplete
message.  Let's use %s in these translatable strings, with a pre-built
buffer that relies on OID8_FORMAT.

Reported-by: Kyotaro Horiguchi <[email protected]>
---
 src/bin/pg_controldata/pg_controldata.c |  6 ++++--
 src/bin/pg_resetwal/pg_resetwal.c       | 13 +++++++++----
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/src/bin/pg_controldata/pg_controldata.c 
b/src/bin/pg_controldata/pg_controldata.c
index b785f7f40701..31dba74f5996 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -101,6 +101,7 @@ main(int argc, char *argv[])
        char            pgctime_str[128];
        char            ckpttime_str[128];
        char            mock_auth_nonce_str[MOCK_AUTH_NONCE_LEN * 2 + 1];
+       char            nextoid_str[32];
        const char *strftime_fmt = "%c";
        const char *progname;
        char            xlogfilename[MAXFNAMELEN];
@@ -269,8 +270,9 @@ main(int argc, char *argv[])
        printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
                   
EpochFromFullTransactionId(ControlFile->checkPointCopy.nextXid),
                   
XidFromFullTransactionId(ControlFile->checkPointCopy.nextXid));
-       printf(_("Latest checkpoint's NextOID:          " OID8_FORMAT "\n"),
-                  ControlFile->checkPointCopy.nextOid);
+       snprintf(nextoid_str, sizeof(nextoid_str), OID8_FORMAT,
+                        ControlFile->checkPointCopy.nextOid);
+       printf(_("Latest checkpoint's NextOID:          %s\n"), nextoid_str);
        printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
                   ControlFile->checkPointCopy.nextMulti);
        printf(_("Latest checkpoint's NextMultiOffset:  %" PRIu64 "\n"),
diff --git a/src/bin/pg_resetwal/pg_resetwal.c 
b/src/bin/pg_resetwal/pg_resetwal.c
index 63e4381e03f0..45146df30a56 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -757,6 +757,8 @@ GuessControlValues(void)
 static void
 PrintControlValues(bool guessed)
 {
+       char            nextoid_str[32];
+
        if (guessed)
                printf(_("Guessed pg_control values:\n\n"));
        else
@@ -775,8 +777,9 @@ PrintControlValues(bool guessed)
        printf(_("Latest checkpoint's NextXID:          %u:%u\n"),
                   
EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid),
                   
XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid));
-       printf(_("Latest checkpoint's NextOID:          " OID8_FORMAT "\n"),
-                  ControlFile.checkPointCopy.nextOid);
+       snprintf(nextoid_str, sizeof(nextoid_str), OID8_FORMAT,
+                        ControlFile.checkPointCopy.nextOid);
+       printf(_("Latest checkpoint's NextOID:          %s\n"), nextoid_str);
        printf(_("Latest checkpoint's NextMultiXactId:  %u\n"),
                   ControlFile.checkPointCopy.nextMulti);
        printf(_("Latest checkpoint's NextMultiOffset:  %" PRIu64 "\n"),
@@ -835,6 +838,7 @@ static void
 PrintNewControlValues(void)
 {
        char            fname[MAXFNAMELEN];
+       char            nextoid_str[32];
 
        /* This will be always printed in order to keep format same. */
        printf(_("\n\nValues to be changed:\n\n"));
@@ -861,8 +865,9 @@ PrintNewControlValues(void)
 
        if (next_oid_given)
        {
-               printf(_("NextOID:                              " OID8_FORMAT 
"\n"),
-                          ControlFile.checkPointCopy.nextOid);
+               snprintf(nextoid_str, sizeof(nextoid_str), OID8_FORMAT,
+                                ControlFile.checkPointCopy.nextOid);
+               printf(_("NextOID:                              %s\n"), 
nextoid_str);
        }
 
        if (next_xid_given)
-- 
2.55.0

Attachment: signature.asc
Description: PGP signature

Reply via email to