Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vmCan-008j0W-1g for pgsql-hackers@arkaria.postgresql.org; Sat, 31 Jan 2026 15:08:57 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vmCak-008Pmm-0m for pgsql-hackers@arkaria.postgresql.org; Sat, 31 Jan 2026 15:08:55 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vmCaj-008Pma-1z for pgsql-hackers@lists.postgresql.org; Sat, 31 Jan 2026 15:08:54 +0000 Received: from fhigh-a5-smtp.messagingengine.com ([103.168.172.156]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1vmCah-00000000NQr-2Atb for pgsql-hackers@lists.postgresql.org; Sat, 31 Jan 2026 15:08:54 +0000 Received: from phl-compute-01.internal (phl-compute-01.internal [10.202.2.41]) by mailfhigh.phl.internal (Postfix) with ESMTP id 2254F1400054 for ; Sat, 31 Jan 2026 10:08:50 -0500 (EST) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-01.internal (MEProxy); Sat, 31 Jan 2026 10:08:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm1; t=1769872130; x= 1769958530; bh=3gID390QerTlWia4OiloHqnlJwTAvXpAq3QrSXCRvWg=; b=p +Tr/JTMwjM9tudJv1C6GMjfzanGJEnYwO32dBUV4lkh4w6UkYx+920HpE2BcH3ZY 8roC5DYdSrU87pPo9Z8zODM2/q60vIHEs34K+ZEPyfaxxP/dXuRUhBmkk92NYZf8 wdHML4kQcMOiE0JnXj/huLsFyOPE9fcyYy0GUKCCfkFoNrt94a0mT+ECtvkgITLI 9iGrBGvnqq5u2sM+xyfZuoRjhKyxA8fHmTT/X3sQi5RtqZe/YYs60Tva3OnIzftr 6+R7Qg44n6LnJ+PlmRlmlsne/J1Cs+UsQnDmT9EXPO8FZj2amrlRU/cHD2htDhwT mEhKeeNB2uT2EFiPCXzug== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:reply-to :subject:subject:to:to:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm3; t=1769872130; x=1769958530; bh=3gID390QerTlW ia4OiloHqnlJwTAvXpAq3QrSXCRvWg=; b=q65UgSqcmPwMMl+JsVs90ClYKKDy8 5Di5/KPbeMZMj1LsfHfrWYIXYzW8ZiAXfe39jpMx7GA0ukDewFMjf/F1raMF7nk+ O39LdcthJU2NKroydj2pbrX92Y9vHlYqMehStFVSwSkh4/m20558cz1ZSqpmNBAp n3hYgkS8AA7Yqq36Uarmb38Q0qRvqgBO0HmWA89Oxx3mjs8PRfyVwb699W4Pm7ql 7N4+Idv2wgesDZv9vJkF+TgyJT62PqA5Vh8w5oLmRGqp4NNJtx2ee8jd5hZUifCO PdiTeDJ4aYPAGyjRipe+u7OQmF6atMBzkUL2Oa+1p6vanFawL/JMQPnFg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefgedrtddtgddujedvvdegucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepfffhvffukfggtggugfgjsehmkeerredttdejnecuhfhrohhmpemllhhvrghrohcu jfgvrhhrvghrrgcuoegrlhhvhhgvrhhrvgeskhhurhhilhgvmhhurdguvgeqnecuggftrf grthhtvghrnhepgeetudfftddvhfekfeelvedvteelheekgfevgfeuueevkeegleduveej keeiteeunecuffhomhgrihhnpegvnhhtvghrphhrihhsvggusgdrtghomhdpghhnuhdroh hrghenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpegr lhhvhhgvrhhrvgeskhhurhhilhgvmhhurdguvgdpnhgspghrtghpthhtohepuddpmhhoug gvpehsmhhtphhouhhtpdhrtghpthhtohepphhgshhqlhdqhhgrtghkvghrsheslhhishht shdrphhoshhtghhrvghsqhhlrdhorhhg X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA for ; Sat, 31 Jan 2026 10:08:40 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1769872118; bh=O0SxzWuS1MCTrfdFIXYFyqnOeFvZ98tn+hWtJqZ0Z4Q=; h=Date:From:To:Subject:In-Reply-To:From; b=i5biQRBWpYd4i01uDRvm220mRnlBGY5PKQfWreEY4BC9bKIHYC/yLtKAaK3BBUyl0 +Wf3th32ncus/guD/beRODPYZNL10x7SZqd0I6PKZU93gy/UGsvGzzzdz5s+o7DnVG Qr77wnUrMcQvoOzNTEA6rUyBUxiURGJbInH+lpYd9zRVhN48CvCnQyIvLcDkfkymx7 hxT2HeFg6lEHLZXq7WX8XGr6c8Us2oFMPYP459nUvN4HTNCq15KB4ycALZxU9s9ON/ S3fo0rtIjQ69gmns7biJ8wvdSZK3Jo52GIVKMyRZgCTsgpHDdiD2PYJ90WANivimV/ ZNVmHGxn0iCTA== Received: by schmee.kurilemu.internal (Postfix, from userid 1000) id 6F02674; Sat, 31 Jan 2026 16:08:38 +0100 (CET) Date: Sat, 31 Jan 2026 16:08:38 +0100 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: Pg Hackers Subject: Re: splitting pg_resetwal output strings Message-ID: <202601311502.ohp4cx7hfms2@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="m4rixdodkhrlzpzv" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <202601310924.yoik5n3blgt4@alvherre.pgsql> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --m4rixdodkhrlzpzv Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2026-Jan-31, Álvaro Herrera wrote: > This is not complete. It modifies PrintControlValues(), which is easy > because I just print each item in the entries.h file in the same order > they appear there. But for PrintNewControlValues() I'll need to add a > symbolic identifier to each string, that the code can use to scan the > array and print just those elements. I'll do that if there are no > objections to this idea here. It looks more or less like this. Patch 0001 is the same as before, and 0002 adds the symbolic names, which is used to create an enum and then to search for the correct lines to print in PrintNewControlValues. I decided to reuse simple_oid_list to store the integers values, which is kinda icky, so getting to something committable I think would have me add simple_int_list. Also, there's a few blocks that are duplicate cases of the same line measuring and printing logic; I suppose I should have a routine to simplify. -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ "Most hackers will be perfectly comfortable conceptualizing users as entropy sources, so let's move on." (Nathaniel Smith) https://mail.gnu.org/archive/html/monotone-devel/2007-01/msg00080.html --m4rixdodkhrlzpzv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0001-Split-out-entry-names-in-pg_resetwal.patch" From 59403690ca6253835ce7577f3eee7d04893b6950 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Fri, 14 Nov 2025 16:25:46 +0100 Subject: [PATCH 1/2] Split out entry names in pg_resetwal --- src/bin/pg_resetwal/entries.h | 62 ++++++++++++++ src/bin/pg_resetwal/nls.mk | 4 +- src/bin/pg_resetwal/pg_resetwal.c | 132 ++++++++++++++++-------------- 3 files changed, 134 insertions(+), 64 deletions(-) create mode 100644 src/bin/pg_resetwal/entries.h diff --git a/src/bin/pg_resetwal/entries.h b/src/bin/pg_resetwal/entries.h new file mode 100644 index 00000000000..6b7686da83a --- /dev/null +++ b/src/bin/pg_resetwal/entries.h @@ -0,0 +1,62 @@ +CONTROLDATA_LINE("pg_control version number", + "%u", ControlFile.pg_control_version) +CONTROLDATA_LINE("Catalog version number", + "%u", ControlFile.catalog_version_no) +CONTROLDATA_LINE("Database system identifier", + "%" PRIu64, ControlFile.system_identifier) +CONTROLDATA_LINE("Latest checkpoint's TimeLineID", + "%u", ControlFile.checkPointCopy.ThisTimeLineID) +CONTROLDATA_LINE("Latest checkpoint's full_page_writes", + "%s", (ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"))) +CONTROLDATA_LINE("Latest checkpoint's NextXID", + "%u:%u", EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid), XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid)) +CONTROLDATA_LINE("Latest checkpoint's NextOID", + "%u", ControlFile.checkPointCopy.nextOid) +CONTROLDATA_LINE("Latest checkpoint's NextMultiXactId", + "%u", ControlFile.checkPointCopy.nextMulti) +CONTROLDATA_LINE("Latest checkpoint's NextMultiOffset", + "%" PRIu64, ControlFile.checkPointCopy.nextMultiOffset) +CONTROLDATA_LINE("Latest checkpoint's oldestXID", + "%u", ControlFile.checkPointCopy.oldestXid) +CONTROLDATA_LINE("Latest checkpoint's oldestXID's DB", + "%u", ControlFile.checkPointCopy.oldestXidDB) +CONTROLDATA_LINE("Latest checkpoint's oldestActiveXID", + "%u", ControlFile.checkPointCopy.oldestActiveXid) +CONTROLDATA_LINE("Latest checkpoint's oldestMultiXid", + "%u", ControlFile.checkPointCopy.oldestMulti) +CONTROLDATA_LINE("Latest checkpoint's oldestMulti's DB", + "%u", ControlFile.checkPointCopy.oldestMultiDB) +CONTROLDATA_LINE("Latest checkpoint's oldestCommitTsXid", + "%u", ControlFile.checkPointCopy.oldestCommitTsXid) +CONTROLDATA_LINE("Latest checkpoint's newestCommitTsXid", + "%u", ControlFile.checkPointCopy.newestCommitTsXid) +CONTROLDATA_LINE("Maximum data alignment", + "%u", ControlFile.maxAlign) +CONTROLDATA_LINE("Database block size", + "%u", ControlFile.blcksz) +CONTROLDATA_LINE("Blocks per segment of large relation", + "%u", ControlFile.relseg_size) +CONTROLDATA_LINE("Pages per SLRU segment", + "%u", ControlFile.slru_pages_per_segment) +CONTROLDATA_LINE("WAL block size", + "%u", ControlFile.xlog_blcksz) +CONTROLDATA_LINE("Bytes per WAL segment", + "%u", ControlFile.xlog_seg_size) +CONTROLDATA_LINE("Maximum length of identifiers", + "%u", ControlFile.nameDataLen) +CONTROLDATA_LINE("Maximum columns in an index", + "%u", ControlFile.indexMaxKeys) +CONTROLDATA_LINE("Maximum size of a TOAST chunk", + "%u", ControlFile.toast_max_chunk_size) +CONTROLDATA_LINE("Size of a large-object chunk", + "%u", ControlFile.loblksize) + +/* This is no longer configurable, but users may still expect to see it: */ +CONTROLDATA_LINE("Date/time type storage", + "%s", _("64-bit integers")) +CONTROLDATA_LINE("Float8 argument passing", + "%s", ControlFile.float8ByVal ? _("by value") : _("by reference")) +CONTROLDATA_LINE("Data page checksum version", + "%u", ControlFile.data_checksum_version) +CONTROLDATA_LINE("Default char data signedness", + "%s", ControlFile.default_char_signedness ? _("signed") : _("unsigned")) diff --git a/src/bin/pg_resetwal/nls.mk b/src/bin/pg_resetwal/nls.mk index 694d5420a29..8dabee72bef 100644 --- a/src/bin/pg_resetwal/nls.mk +++ b/src/bin/pg_resetwal/nls.mk @@ -2,10 +2,12 @@ CATALOG_NAME = pg_resetwal GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \ pg_resetwal.c \ + entries.h \ ../../common/controldata_utils.c \ ../../common/fe_memutils.c \ ../../common/file_utils.c \ ../../common/restricted_token.c \ ../../fe_utils/option_utils.c -GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) +GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) \ + CONTROLDATA_LINE:1 GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 431b83a67da..fb17b6f80e0 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -57,6 +57,7 @@ #include "fe_utils/option_utils.h" #include "fe_utils/version.h" #include "getopt_long.h" +#include "mb/pg_wchar.h" #include "pg_getopt.h" #include "storage/large_object.h" @@ -114,6 +115,7 @@ static void KillExistingArchiveStatus(void); static void KillExistingWALSummaries(void); static void WriteEmptyXLOG(void); static void usage(void); +static int internal_wcswidth(const char *pwcs, size_t len, int encoding); static uint32 strtouint32_strict(const char *restrict s, char **restrict endptr, int base); static uint64 strtouint64_strict(const char *restrict s, char **restrict endptr, int base); @@ -753,74 +755,48 @@ GuessControlValues(void) static void PrintControlValues(bool guessed) { + int encoding = pg_get_encoding_from_locale(NULL, true); + int maxlen = 0; + int thislen; + if (guessed) printf(_("Guessed pg_control values:\n\n")); else printf(_("Current pg_control values:\n\n")); - printf(_("pg_control version number: %u\n"), - ControlFile.pg_control_version); - printf(_("Catalog version number: %u\n"), - ControlFile.catalog_version_no); - printf(_("Database system identifier: %" PRIu64 "\n"), - ControlFile.system_identifier); - printf(_("Latest checkpoint's TimeLineID: %u\n"), - ControlFile.checkPointCopy.ThisTimeLineID); - printf(_("Latest checkpoint's full_page_writes: %s\n"), - ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off")); - printf(_("Latest checkpoint's NextXID: %u:%u\n"), - EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid), - XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid)); - printf(_("Latest checkpoint's NextOID: %u\n"), - ControlFile.checkPointCopy.nextOid); - printf(_("Latest checkpoint's NextMultiXactId: %u\n"), - ControlFile.checkPointCopy.nextMulti); - printf(_("Latest checkpoint's NextMultiOffset: %" PRIu64 "\n"), - ControlFile.checkPointCopy.nextMultiOffset); - printf(_("Latest checkpoint's oldestXID: %u\n"), - ControlFile.checkPointCopy.oldestXid); - printf(_("Latest checkpoint's oldestXID's DB: %u\n"), - ControlFile.checkPointCopy.oldestXidDB); - printf(_("Latest checkpoint's oldestActiveXID: %u\n"), - ControlFile.checkPointCopy.oldestActiveXid); - printf(_("Latest checkpoint's oldestMultiXid: %u\n"), - ControlFile.checkPointCopy.oldestMulti); - printf(_("Latest checkpoint's oldestMulti's DB: %u\n"), - ControlFile.checkPointCopy.oldestMultiDB); - printf(_("Latest checkpoint's oldestCommitTsXid:%u\n"), - ControlFile.checkPointCopy.oldestCommitTsXid); - printf(_("Latest checkpoint's newestCommitTsXid:%u\n"), - ControlFile.checkPointCopy.newestCommitTsXid); - printf(_("Maximum data alignment: %u\n"), - ControlFile.maxAlign); - /* we don't print floatFormat since can't say much useful about it */ - printf(_("Database block size: %u\n"), - ControlFile.blcksz); - printf(_("Blocks per segment of large relation: %u\n"), - ControlFile.relseg_size); - printf(_("Pages per SLRU segment: %u\n"), - ControlFile.slru_pages_per_segment); - printf(_("WAL block size: %u\n"), - ControlFile.xlog_blcksz); - printf(_("Bytes per WAL segment: %u\n"), - ControlFile.xlog_seg_size); - printf(_("Maximum length of identifiers: %u\n"), - ControlFile.nameDataLen); - printf(_("Maximum columns in an index: %u\n"), - ControlFile.indexMaxKeys); - printf(_("Maximum size of a TOAST chunk: %u\n"), - ControlFile.toast_max_chunk_size); - printf(_("Size of a large-object chunk: %u\n"), - ControlFile.loblksize); - /* This is no longer configurable, but users may still expect to see it: */ - printf(_("Date/time type storage: %s\n"), - _("64-bit integers")); - printf(_("Float8 argument passing: %s\n"), - (ControlFile.float8ByVal ? _("by value") : _("by reference"))); - printf(_("Data page checksum version: %u\n"), - ControlFile.data_checksum_version); - printf(_("Default char data signedness: %s\n"), - (ControlFile.default_char_signedness ? _("signed") : _("unsigned"))); + /* + * First, determine the maximum length of the description of all entries, + * some or all of which might be translated. + */ +#define CONTROLDATA_LINE(description, fmt, ...) \ + thislen = internal_wcswidth(_(description), \ + strlen(_(description)), \ + encoding); \ + if (thislen > maxlen) \ + maxlen = thislen; +#include "entries.h" +#undef CONTROLDATA_LINE + + /* + * Print each line: the possibly-translated description, then some padding + * spaces according to its display width, then the value. + */ +#define CONTROLDATA_LINE(description, fmt, ...) \ + { \ + int thisstrlen; \ + \ + thisstrlen = strlen(_(description)); \ + thislen = internal_wcswidth(_(description), \ + thisstrlen, \ + encoding); \ + printf("%s:%*s" fmt "\n", \ + _(description), \ + maxlen - thislen + 2, \ + " ", \ + __VA_ARGS__); \ + } +#include "entries.h" +#undef CONTROLDATA_LINE } @@ -1238,6 +1214,36 @@ usage(void) printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL); } +/* + * Measure the display length of a single-line string in the given encoding. + * + * Similar to pg_wcswidth, written without dependency on libpq. + */ +static int +internal_wcswidth(const char *pwcs, size_t len, int encoding) +{ + int width = 0; + + while (len > 0) + { + int chlen, + chwidth; + + chlen = pg_encoding_mblen(encoding, pwcs); + if (len < (size_t) chlen) + break; /* Invalid string */ + + chwidth = pg_encoding_dsplen(encoding, pwcs); + if (chwidth > 0) + width += chwidth; + + pwcs += chlen; + len -= chlen; + } + return width; +} + + /* * strtouint32_strict -- like strtoul(), but returns uint32 and doesn't accept * negative values -- 2.47.3 --m4rixdodkhrlzpzv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="0002-Apply-the-same-technique-to-PrintNewControlValues-to.patch" From 8e8427064a9680617d9ba55902d101880df683a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Herrera?= Date: Sat, 31 Jan 2026 16:01:56 +0100 Subject: [PATCH 2/2] Apply the same technique to PrintNewControlValues too --- src/bin/pg_resetwal/entries.h | 60 +++++++-------- src/bin/pg_resetwal/pg_resetwal.c | 121 ++++++++++++++++++++---------- 2 files changed, 110 insertions(+), 71 deletions(-) diff --git a/src/bin/pg_resetwal/entries.h b/src/bin/pg_resetwal/entries.h index 6b7686da83a..25f2c49b3a8 100644 --- a/src/bin/pg_resetwal/entries.h +++ b/src/bin/pg_resetwal/entries.h @@ -1,62 +1,62 @@ -CONTROLDATA_LINE("pg_control version number", +CONTROLDATA_LINE(CD_CONTROL_VERSION, "pg_control version number", "%u", ControlFile.pg_control_version) -CONTROLDATA_LINE("Catalog version number", +CONTROLDATA_LINE(CD_CATALOG_VERSION, "Catalog version number", "%u", ControlFile.catalog_version_no) -CONTROLDATA_LINE("Database system identifier", +CONTROLDATA_LINE(CD_SYSTEM_IDENTIFIER, "Database system identifier", "%" PRIu64, ControlFile.system_identifier) -CONTROLDATA_LINE("Latest checkpoint's TimeLineID", +CONTROLDATA_LINE(CD_CKPT_TIMELINE, "Latest checkpoint's TimeLineID", "%u", ControlFile.checkPointCopy.ThisTimeLineID) -CONTROLDATA_LINE("Latest checkpoint's full_page_writes", +CONTROLDATA_LINE(CD_CKPT_FPW, "Latest checkpoint's full_page_writes", "%s", (ControlFile.checkPointCopy.fullPageWrites ? _("on") : _("off"))) -CONTROLDATA_LINE("Latest checkpoint's NextXID", +CONTROLDATA_LINE(CD_CKPT_NEXTXID, "Latest checkpoint's NextXID", "%u:%u", EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid), XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid)) -CONTROLDATA_LINE("Latest checkpoint's NextOID", +CONTROLDATA_LINE(CD_CKPT_NEXTOID, "Latest checkpoint's NextOID", "%u", ControlFile.checkPointCopy.nextOid) -CONTROLDATA_LINE("Latest checkpoint's NextMultiXactId", +CONTROLDATA_LINE(CD_CKPT_NEXTMXID, "Latest checkpoint's NextMultiXactId", "%u", ControlFile.checkPointCopy.nextMulti) -CONTROLDATA_LINE("Latest checkpoint's NextMultiOffset", +CONTROLDATA_LINE(CD_CKPT_NEXTMXOFF, "Latest checkpoint's NextMultiOffset", "%" PRIu64, ControlFile.checkPointCopy.nextMultiOffset) -CONTROLDATA_LINE("Latest checkpoint's oldestXID", +CONTROLDATA_LINE(CD_CKPT_OLDESTXID, "Latest checkpoint's oldestXID", "%u", ControlFile.checkPointCopy.oldestXid) -CONTROLDATA_LINE("Latest checkpoint's oldestXID's DB", +CONTROLDATA_LINE(CD_CKPT_OLDESTXID_DB, "Latest checkpoint's oldestXID's DB", "%u", ControlFile.checkPointCopy.oldestXidDB) -CONTROLDATA_LINE("Latest checkpoint's oldestActiveXID", +CONTROLDATA_LINE(CD_CKPT_OLDEST_ACTIVEXID, "Latest checkpoint's oldestActiveXID", "%u", ControlFile.checkPointCopy.oldestActiveXid) -CONTROLDATA_LINE("Latest checkpoint's oldestMultiXid", +CONTROLDATA_LINE(CD_CKPT_OLDEST_MULTI, "Latest checkpoint's oldestMultiXid", "%u", ControlFile.checkPointCopy.oldestMulti) -CONTROLDATA_LINE("Latest checkpoint's oldestMulti's DB", +CONTROLDATA_LINE(CD_CKPT_OLDEST_MULTI_DB, "Latest checkpoint's oldestMulti's DB", "%u", ControlFile.checkPointCopy.oldestMultiDB) -CONTROLDATA_LINE("Latest checkpoint's oldestCommitTsXid", +CONTROLDATA_LINE(CD_CKPT_OLDEST_COMMITTS_XID, "Latest checkpoint's oldestCommitTsXid", "%u", ControlFile.checkPointCopy.oldestCommitTsXid) -CONTROLDATA_LINE("Latest checkpoint's newestCommitTsXid", +CONTROLDATA_LINE(CD_CKPT_NEWEST_COMMITTS_XID, "Latest checkpoint's newestCommitTsXid", "%u", ControlFile.checkPointCopy.newestCommitTsXid) -CONTROLDATA_LINE("Maximum data alignment", +CONTROLDATA_LINE(CD_MAXALIGN, "Maximum data alignment", "%u", ControlFile.maxAlign) -CONTROLDATA_LINE("Database block size", +CONTROLDATA_LINE(CD_BLCKSZ, "Database block size", "%u", ControlFile.blcksz) -CONTROLDATA_LINE("Blocks per segment of large relation", +CONTROLDATA_LINE(CD_RELSEG_SZ, "Blocks per segment of large relation", "%u", ControlFile.relseg_size) -CONTROLDATA_LINE("Pages per SLRU segment", +CONTROLDATA_LINE(CD_SLRU_PPS, "Pages per SLRU segment", "%u", ControlFile.slru_pages_per_segment) -CONTROLDATA_LINE("WAL block size", +CONTROLDATA_LINE(CD_WAL_BLCKSZ, "WAL block size", "%u", ControlFile.xlog_blcksz) -CONTROLDATA_LINE("Bytes per WAL segment", +CONTROLDATA_LINE(CD_WAL_SEGSIZE, "Bytes per WAL segment", "%u", ControlFile.xlog_seg_size) -CONTROLDATA_LINE("Maximum length of identifiers", +CONTROLDATA_LINE(CD_WAL_NAMEDATALEN, "Maximum length of identifiers", "%u", ControlFile.nameDataLen) -CONTROLDATA_LINE("Maximum columns in an index", +CONTROLDATA_LINE(CD_INDEX_MAX_KEYS, "Maximum columns in an index", "%u", ControlFile.indexMaxKeys) -CONTROLDATA_LINE("Maximum size of a TOAST chunk", +CONTROLDATA_LINE(CD_TOAST_MAXCHUNKSZ, "Maximum size of a TOAST chunk", "%u", ControlFile.toast_max_chunk_size) -CONTROLDATA_LINE("Size of a large-object chunk", +CONTROLDATA_LINE(CD_LO_BLKSZ, "Size of a large-object chunk", "%u", ControlFile.loblksize) /* This is no longer configurable, but users may still expect to see it: */ -CONTROLDATA_LINE("Date/time type storage", +CONTROLDATA_LINE(CD_DATETIME_INT64, "Date/time type storage", "%s", _("64-bit integers")) -CONTROLDATA_LINE("Float8 argument passing", +CONTROLDATA_LINE(CD_FLOAT8_ARGS, "Float8 argument passing", "%s", ControlFile.float8ByVal ? _("by value") : _("by reference")) -CONTROLDATA_LINE("Data page checksum version", +CONTROLDATA_LINE(CD_CHECKSUMS, "Data page checksum version", "%u", ControlFile.data_checksum_version) -CONTROLDATA_LINE("Default char data signedness", +CONTROLDATA_LINE(CD_CHAR_SIGNEDNESS, "Default char data signedness", "%s", ControlFile.default_char_signedness ? _("signed") : _("unsigned")) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index fb17b6f80e0..23bf1c62183 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -55,6 +55,7 @@ #include "common/restricted_token.h" #include "common/string.h" #include "fe_utils/option_utils.h" +#include "fe_utils/simple_list.h" #include "fe_utils/version.h" #include "getopt_long.h" #include "mb/pg_wchar.h" @@ -119,6 +120,14 @@ static int internal_wcswidth(const char *pwcs, size_t len, int encoding); static uint32 strtouint32_strict(const char *restrict s, char **restrict endptr, int base); static uint64 strtouint64_strict(const char *restrict s, char **restrict endptr, int base); +/* Define the string enums */ +#define CONTROLDATA_LINE(symbol, description, fmt, ...) \ + symbol, +enum ControldataStrings { +#include "entries.h" +}; +#undef CONTROLDATA_LINE + int main(int argc, char *argv[]) @@ -768,7 +777,7 @@ PrintControlValues(bool guessed) * First, determine the maximum length of the description of all entries, * some or all of which might be translated. */ -#define CONTROLDATA_LINE(description, fmt, ...) \ +#define CONTROLDATA_LINE(symbol, description, fmt, ...) \ thislen = internal_wcswidth(_(description), \ strlen(_(description)), \ encoding); \ @@ -781,7 +790,7 @@ PrintControlValues(bool guessed) * Print each line: the possibly-translated description, then some padding * spaces according to its display width, then the value. */ -#define CONTROLDATA_LINE(description, fmt, ...) \ +#define CONTROLDATA_LINE(symbol, description, fmt, ...) \ { \ int thisstrlen; \ \ @@ -807,69 +816,99 @@ static void PrintNewControlValues(void) { char fname[MAXFNAMELEN]; + int encoding = pg_get_encoding_from_locale(NULL, true); + SimpleOidList toprint = {NULL, NULL}; + int maxlen = 0; + int thislen; /* This will be always printed in order to keep format same. */ printf(_("\n\nValues to be changed:\n\n")); - XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, - newXlogSegNo, WalSegSz); - printf(_("First log segment after reset: %s\n"), fname); - if (mxids_given) { - printf(_("NextMultiXactId: %u\n"), - ControlFile.checkPointCopy.nextMulti); - printf(_("OldestMultiXid: %u\n"), - ControlFile.checkPointCopy.oldestMulti); - printf(_("OldestMulti's DB: %u\n"), - ControlFile.checkPointCopy.oldestMultiDB); + simple_oid_list_append(&toprint, CD_CKPT_NEXTMXID); + simple_oid_list_append(&toprint, CD_CKPT_OLDEST_MULTI); + simple_oid_list_append(&toprint, CD_CKPT_OLDEST_MULTI_DB); } if (next_mxoff_given) - { - printf(_("NextMultiOffset: %" PRIu64 "\n"), - ControlFile.checkPointCopy.nextMultiOffset); - } + simple_oid_list_append(&toprint, CD_CKPT_NEXTMXOFF); if (next_oid_given) - { - printf(_("NextOID: %u\n"), - ControlFile.checkPointCopy.nextOid); - } + simple_oid_list_append(&toprint, CD_CKPT_NEXTOID); if (next_xid_given) - { - printf(_("NextXID: %u\n"), - XidFromFullTransactionId(ControlFile.checkPointCopy.nextXid)); - } + simple_oid_list_append(&toprint, CD_CKPT_NEXTXID); if (oldest_xid_given) { - printf(_("OldestXID: %u\n"), - ControlFile.checkPointCopy.oldestXid); - printf(_("OldestXID's DB: %u\n"), - ControlFile.checkPointCopy.oldestXidDB); - } - - if (next_xid_epoch_given) - { - printf(_("NextXID epoch: %u\n"), - EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid)); + simple_oid_list_append(&toprint, CD_CKPT_OLDESTXID); + simple_oid_list_append(&toprint, CD_CKPT_OLDESTXID_DB); } if (commit_ts_xids_given) { - printf(_("oldestCommitTsXid: %u\n"), - ControlFile.checkPointCopy.oldestCommitTsXid); - printf(_("newestCommitTsXid: %u\n"), - ControlFile.checkPointCopy.newestCommitTsXid); + simple_oid_list_append(&toprint, CD_CKPT_OLDEST_COMMITTS_XID); + simple_oid_list_append(&toprint, CD_CKPT_NEWEST_COMMITTS_XID); } if (wal_segsize_given) - { - printf(_("Bytes per WAL segment: %u\n"), - ControlFile.xlog_seg_size); + simple_oid_list_append(&toprint, CD_WAL_SEGSIZE); + +#define CONTROLDATA_LINE(symbol, description, fmt, ...) \ + if (simple_oid_list_member(&toprint, symbol)) \ + { \ + thislen = internal_wcswidth(_(description), \ + strlen(_(description)), \ + encoding); \ + if (thislen > maxlen) \ + maxlen = thislen; \ } +#include "entries.h" +#undef CONTROLDATA_LINE + + + XLogFileName(fname, ControlFile.checkPointCopy.ThisTimeLineID, + newXlogSegNo, WalSegSz); + + /* We print this one inconditionally */ + { + char *str = "First log segment after reset"; + thislen = internal_wcswidth(_(str), strlen(_(str)), encoding); + if (thislen > maxlen) + maxlen = thislen; + printf("%s:%*s%s\n", _(str), maxlen - thislen + 2, " ", fname); + } + + /* We print the XID epoch in a degenerate case */ + if (next_xid_epoch_given) + { + char *str = "NextXID epoch"; + thislen = internal_wcswidth(_(str), strlen(_(str)), encoding); + if (thislen > maxlen) + maxlen = thislen; + printf("%s:%*s%u\n", _(str), maxlen - thislen + 2, " ", + EpochFromFullTransactionId(ControlFile.checkPointCopy.nextXid)); + + } + +#define CONTROLDATA_LINE(symbol, description, fmt, ...) \ + if (simple_oid_list_member(&toprint, symbol)) \ + { \ + int thisstrlen; \ + \ + thisstrlen = strlen(_(description)); \ + thislen = internal_wcswidth(_(description), \ + thisstrlen, \ + encoding); \ + printf("%s:%*s" fmt "\n", \ + _(description), \ + maxlen - thislen + 2, \ + " ", \ + __VA_ARGS__); \ + } +#include "entries.h" +#undef CONTROLDATA_LINE } -- 2.47.3 --m4rixdodkhrlzpzv--