agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH 3/5] Fix handling of NULLs in MCV items and constants 179+ messages / 4 participants [nested] [flat]
* [PATCH 3/5] Fix handling of NULLs in MCV items and constants @ 2019-07-15 00:00 Tomas Vondra <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Tomas Vondra @ 2019-07-15 00:00 UTC (permalink / raw) There were two issues in how the extended statistics handled NULL values in opclauses. Firstly, the code was oblivious to the possibility that Const may be NULL (constisnull=true) in which case the constvalue is undefined. We need to treat this as a mismatch, and not call the proc. Secondly, the MCV item itself may contain NULL values too - the code already did check that, and updated the match bitmap accordingly, but failed to ensure we won't call the operator procedure anyway. This fixes both issues by extending the existing check so that it looks at constisnull too, and making sure it skips calling the procedure. Discussion: https://postgr.es/m/8736jdhbhc.fsf%40ansel.ydns.eu --- src/backend/statistics/mcv.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/backend/statistics/mcv.c b/src/backend/statistics/mcv.c index 865981bbb4..77daa647e2 100644 --- a/src/backend/statistics/mcv.c +++ b/src/backend/statistics/mcv.c @@ -1593,12 +1593,18 @@ mcv_get_match_bitmap(PlannerInfo *root, List *clauses, MCVItem *item = &mcvlist->items[i]; /* - * For AND-lists, we can also mark NULL items as 'no - * match' (and then skip them). For OR-lists this is not - * possible. + * When the MCV item or the Const value is NULL we can treat + * this as a mismatch. We must not call the operator proc + * because of strictness. */ - if ((!is_or) && item->isnull[idx]) - matches[i] = false; + if (item->isnull[idx] || cst->constisnull) + { + /* we only care about AND, because OR can't change */ + if (!is_or) + matches[i] = false; + + continue; + } /* skip MCV items that were already ruled out */ if ((!is_or) && (matches[i] == false)) -- 2.20.1 --ztxiowpcs6gwvnvh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0004-Refactor-simplify-evaluation-of-MCV-bitmap.patch" ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH] Track DEALLOCATE statements in pg_stat_activity @ 2023-08-14 10:59 Dagfinn Ilmari Mannsåker <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Dagfinn Ilmari Mannsåker @ 2023-08-14 10:59 UTC (permalink / raw) Treat the statement name as a constant when jumbling. --- .../pg_stat_statements/expected/utility.out | 40 +++++++++++++++++++ .../pg_stat_statements/pg_stat_statements.c | 8 +--- contrib/pg_stat_statements/sql/utility.sql | 13 ++++++ src/backend/parser/gram.y | 4 ++ src/include/nodes/parsenodes.h | 6 ++- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/contrib/pg_stat_statements/expected/utility.out b/contrib/pg_stat_statements/expected/utility.out index 93735d5d85..3681374869 100644 --- a/contrib/pg_stat_statements/expected/utility.out +++ b/contrib/pg_stat_statements/expected/utility.out @@ -472,6 +472,46 @@ SELECT pg_stat_statements_reset(); (1 row) +-- Execution statements +SELECT 1 as a; + a +--- + 1 +(1 row) + +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (1); + a +--- + 1 +(1 row) + +DEALLOCATE stat_select; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (2); + a +--- + 2 +(1 row) + +DEALLOCATE PREPARE stat_select; +DEALLOCATE ALL; +DEALLOCATE PREPARE ALL; +SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + calls | rows | query +-------+------+--------------------------------------- + 4 | 0 | DEALLOCATE $1 + 2 | 2 | PREPARE stat_select AS SELECT $1 AS a + 1 | 1 | SELECT $1 as a + 1 | 1 | SELECT pg_stat_statements_reset() +(4 rows) + +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + -- SET statements. -- These use two different strings, still they count as one entry. SET work_mem = '1MB'; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 55b957d251..06b65aeef5 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -104,8 +104,7 @@ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; * ignores. */ #define PGSS_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \ - !IsA(n, PrepareStmt) && \ - !IsA(n, DeallocateStmt)) + !IsA(n, PrepareStmt)) /* * Extension version number, for supporting older extension versions' objects @@ -830,8 +829,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate) /* * Clear queryId for prepared statements related utility, as those will - * inherit from the underlying statement's one (except DEALLOCATE which is - * entirely untracked). + * inherit from the underlying statement's one. */ if (query->utilityStmt) { @@ -1116,8 +1114,6 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, * calculated from the query tree) would be used to accumulate costs of * ensuing EXECUTEs. This would be confusing, and inconsistent with other * cases where planning time is not included at all. - * - * Likewise, we don't track execution of DEALLOCATE. */ if (pgss_track_utility && pgss_enabled(exec_nested_level) && PGSS_HANDLED_UTILITY(parsetree)) diff --git a/contrib/pg_stat_statements/sql/utility.sql b/contrib/pg_stat_statements/sql/utility.sql index 87666d9135..5f7d4a467f 100644 --- a/contrib/pg_stat_statements/sql/utility.sql +++ b/contrib/pg_stat_statements/sql/utility.sql @@ -237,6 +237,19 @@ DROP DOMAIN domain_stats; SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; SELECT pg_stat_statements_reset(); +-- Execution statements +SELECT 1 as a; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (1); +DEALLOCATE stat_select; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (2); +DEALLOCATE PREPARE stat_select; +DEALLOCATE ALL; +DEALLOCATE PREPARE ALL; +SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; +SELECT pg_stat_statements_reset(); + -- SET statements. -- These use two different strings, still they count as one entry. SET work_mem = '1MB'; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index b3bdf947b6..680c7f3683 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11936,6 +11936,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = $2; + n->location = @2; $$ = (Node *) n; } | DEALLOCATE PREPARE name @@ -11943,6 +11944,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = $3; + n->location = @3; $$ = (Node *) n; } | DEALLOCATE ALL @@ -11950,6 +11952,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = NULL; + n->location = -1; $$ = (Node *) n; } | DEALLOCATE PREPARE ALL @@ -11957,6 +11960,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = NULL; + n->location = -1; $$ = (Node *) n; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 2565348303..b7aeebe3b4 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -3925,8 +3925,10 @@ typedef struct ExecuteStmt typedef struct DeallocateStmt { NodeTag type; - char *name; /* The name of the plan to remove */ - /* NULL means DEALLOCATE ALL */ + /* The name of the plan to remove. NULL means DEALLOCATE ALL. */ + char *name pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location pg_node_attr(query_jumble_location); } DeallocateStmt; /* -- 2.39.2 --=-=-=-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH] Track DEALLOCATE statements in pg_stat_activity @ 2023-08-14 10:59 Dagfinn Ilmari Mannsåker <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Dagfinn Ilmari Mannsåker @ 2023-08-14 10:59 UTC (permalink / raw) Treat the statement name as a constant when jumbling. --- .../pg_stat_statements/expected/utility.out | 40 +++++++++++++++++++ .../pg_stat_statements/pg_stat_statements.c | 8 +--- contrib/pg_stat_statements/sql/utility.sql | 13 ++++++ src/backend/parser/gram.y | 4 ++ src/include/nodes/parsenodes.h | 6 ++- 5 files changed, 63 insertions(+), 8 deletions(-) diff --git a/contrib/pg_stat_statements/expected/utility.out b/contrib/pg_stat_statements/expected/utility.out index 93735d5d85..3681374869 100644 --- a/contrib/pg_stat_statements/expected/utility.out +++ b/contrib/pg_stat_statements/expected/utility.out @@ -472,6 +472,46 @@ SELECT pg_stat_statements_reset(); (1 row) +-- Execution statements +SELECT 1 as a; + a +--- + 1 +(1 row) + +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (1); + a +--- + 1 +(1 row) + +DEALLOCATE stat_select; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (2); + a +--- + 2 +(1 row) + +DEALLOCATE PREPARE stat_select; +DEALLOCATE ALL; +DEALLOCATE PREPARE ALL; +SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; + calls | rows | query +-------+------+--------------------------------------- + 4 | 0 | DEALLOCATE $1 + 2 | 2 | PREPARE stat_select AS SELECT $1 AS a + 1 | 1 | SELECT $1 as a + 1 | 1 | SELECT pg_stat_statements_reset() +(4 rows) + +SELECT pg_stat_statements_reset(); + pg_stat_statements_reset +-------------------------- + +(1 row) + -- SET statements. -- These use two different strings, still they count as one entry. SET work_mem = '1MB'; diff --git a/contrib/pg_stat_statements/pg_stat_statements.c b/contrib/pg_stat_statements/pg_stat_statements.c index 55b957d251..06b65aeef5 100644 --- a/contrib/pg_stat_statements/pg_stat_statements.c +++ b/contrib/pg_stat_statements/pg_stat_statements.c @@ -104,8 +104,7 @@ static const uint32 PGSS_PG_MAJOR_VERSION = PG_VERSION_NUM / 100; * ignores. */ #define PGSS_HANDLED_UTILITY(n) (!IsA(n, ExecuteStmt) && \ - !IsA(n, PrepareStmt) && \ - !IsA(n, DeallocateStmt)) + !IsA(n, PrepareStmt)) /* * Extension version number, for supporting older extension versions' objects @@ -830,8 +829,7 @@ pgss_post_parse_analyze(ParseState *pstate, Query *query, JumbleState *jstate) /* * Clear queryId for prepared statements related utility, as those will - * inherit from the underlying statement's one (except DEALLOCATE which is - * entirely untracked). + * inherit from the underlying statement's one. */ if (query->utilityStmt) { @@ -1116,8 +1114,6 @@ pgss_ProcessUtility(PlannedStmt *pstmt, const char *queryString, * calculated from the query tree) would be used to accumulate costs of * ensuing EXECUTEs. This would be confusing, and inconsistent with other * cases where planning time is not included at all. - * - * Likewise, we don't track execution of DEALLOCATE. */ if (pgss_track_utility && pgss_enabled(exec_nested_level) && PGSS_HANDLED_UTILITY(parsetree)) diff --git a/contrib/pg_stat_statements/sql/utility.sql b/contrib/pg_stat_statements/sql/utility.sql index 87666d9135..5f7d4a467f 100644 --- a/contrib/pg_stat_statements/sql/utility.sql +++ b/contrib/pg_stat_statements/sql/utility.sql @@ -237,6 +237,19 @@ DROP DOMAIN domain_stats; SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; SELECT pg_stat_statements_reset(); +-- Execution statements +SELECT 1 as a; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (1); +DEALLOCATE stat_select; +PREPARE stat_select AS SELECT $1 AS a; +EXECUTE stat_select (2); +DEALLOCATE PREPARE stat_select; +DEALLOCATE ALL; +DEALLOCATE PREPARE ALL; +SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"; +SELECT pg_stat_statements_reset(); + -- SET statements. -- These use two different strings, still they count as one entry. SET work_mem = '1MB'; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index b3bdf947b6..680c7f3683 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11936,6 +11936,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = $2; + n->location = @2; $$ = (Node *) n; } | DEALLOCATE PREPARE name @@ -11943,6 +11944,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = $3; + n->location = @3; $$ = (Node *) n; } | DEALLOCATE ALL @@ -11950,6 +11952,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = NULL; + n->location = -1; $$ = (Node *) n; } | DEALLOCATE PREPARE ALL @@ -11957,6 +11960,7 @@ DeallocateStmt: DEALLOCATE name DeallocateStmt *n = makeNode(DeallocateStmt); n->name = NULL; + n->location = -1; $$ = (Node *) n; } ; diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 2565348303..b7aeebe3b4 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -3925,8 +3925,10 @@ typedef struct ExecuteStmt typedef struct DeallocateStmt { NodeTag type; - char *name; /* The name of the plan to remove */ - /* NULL means DEALLOCATE ALL */ + /* The name of the plan to remove. NULL means DEALLOCATE ALL. */ + char *name pg_node_attr(query_jumble_ignore); + /* token location, or -1 if unknown */ + int location pg_node_attr(query_jumble_location); } DeallocateStmt; /* -- 2.39.2 --=-=-=-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* [PATCH 2/2] Apply the same technique to PrintNewControlValues too @ 2026-01-31 15:01 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Álvaro Herrera @ 2026-01-31 15:01 UTC (permalink / raw) --- 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-- ^ permalink raw reply [nested|flat] 179+ messages in thread
* Add heap and index vacuum timings to pg_stat_progress_vacuum @ 2026-05-04 05:41 Bharath Rupireddy <[email protected]> 0 siblings, 0 replies; 179+ messages in thread From: Bharath Rupireddy @ 2026-05-04 05:41 UTC (permalink / raw) To: PostgreSQL Hackers <[email protected]> Hi, When vacuum is running for hours on a table with many indexes, we can see what phase it is in and how many index vacuum cycles have happened (index_vacuum_count), but not how much time each phase has taken. That makes it hard to tell what is actually slow. The attached patch adds three columns to pg_stat_progress_vacuum that report the total time spent in heap vacuuming, index vacuuming, and index cleanup. The values are accumulated across overflow cycles when the dead TID store fills up. These columns make it easy to see whether the bottleneck is heap scanning or index processing, analyze why vacuum is slow, and adjust maintenance_work_mem accordingly to reduce TID store overflow cycles. They also make it possible to estimate how long vacuum takes to finish - polling these timing columns along with scanned blocks gives a good estimated time. We could put this behind a track_vacuum_timing GUC similar to track_io_timing and track_wal_timing of the time capturing calls seem costly. I'd prefer not to add another GUC, but I'm open to thoughts on this. For example, I tested with a 3M-row table (3.9 GB), 4 btree indexes, and maintenance_work_mem=256kB (kept low to force TID-store overflows). About 34 minutes in, only 13% through the vacuum [1]. index_vacuum_time is 2006s vs heap_vacuum_time of 2.1s - index processing is where all the time goes. 13,188 overflow cycles × 4 indexes = 52,752 index scans so far. In production, tables with more indexes, these columns show exactly where vacuum time is going and whether raising maintenance_work_mem would help. With the help of the attached sql function, the estimated time to finish the vacuum is about 3.5 hours [2]. Thoughts? [1] SELECT * FROM pg_stat_progress_vacuum; pid | 18764 relid | 16384 phase | vacuuming indexes heap_blks_total | 500000 heap_blks_scanned | 66202 heap_blks_vacuumed | 66202 index_vacuum_count | 13188 max_dead_tuple_bytes | 262144 dead_tuple_bytes | 0 num_dead_item_ids | 0 indexes_total | 4 indexes_processed | 4 delay_time | 0 mode | manual started_by | user heap_vacuum_time | 2.098345 index_vacuum_time | 2005.931383 index_cleanup_time | 0 [2] SELECT * FROM estimate_vacuum_completion(); pid | 18764 relname | vac_timing_test pct_done | 13.24 time_remaining | 03:35:39 -- Bharath Rupireddy Amazon Web Services: https://aws.amazon.com Attachments: [application/x-patch] v1-0001-Add-heap-and-index-vacuum-timings-to-pg_stat_prog.patch (12.5K, ../../CALj2ACVD08XgDcQpTSegKDiyJHwJ6eK89X+1WksWqUJxT86A_A@mail.gmail.com/3-v1-0001-Add-heap-and-index-vacuum-timings-to-pg_stat_prog.patch) download | inline diff: From b266993a0d61c3f46da32730086b7d538150f4fb Mon Sep 17 00:00:00 2001 From: Bharath Rupireddy <[email protected]> Date: Sun, 19 Apr 2026 00:01:13 +0000 Subject: [PATCH v1] Add heap and index vacuum timings to pg_stat_progress_vacuum When vacuum is running for hours on a table with many indexes, we can see what phase it is in and how many index vacuum cycles have happened (index_vacuum_count), but not how much time each phase has taken. That makes it hard to tell what is actually slow. This commit adds three columns to pg_stat_progress_vacuum that report the total time spent in heap vacuuming, index vacuuming, and index cleanup. The values carry over across overflow cycles when the dead TID store fills up and vacuum restarts. These columns make it easy to see whether the bottleneck is heap scanning or index processing, analyze why vacuum is slow, and adjust maintenance_work_mem accordingly to reduce TID store overflow cycles. These columns also make it possible to estimate how long vacuum takes to finish. Polling these timing columns along with scanned blocks gives a good estimated time to finish vacuum. --- doc/src/sgml/monitoring.sgml | 36 +++++++++++++++ src/backend/access/heap/vacuumlazy.c | 68 ++++++++++++++++++++++++++++ src/backend/catalog/system_views.sql | 5 +- src/include/commands/progress.h | 3 ++ src/test/regress/expected/rules.out | 5 +- 5 files changed, 115 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index 08d5b824552..7912b9fce7f 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -7577,6 +7577,42 @@ FROM pg_stat_get_backend_idset() AS backendid; </itemizedlist> </para></entry> </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>heap_vacuum_time</structfield> <type>double precision</type> + </para> + <para> + Total time spent in heap vacuuming phase, in seconds (see + <xref linkend="vacuum-phases"/>). This includes time spent scanning + the heap to collect dead TIDs, plus the time spent in the heap + vacuuming pass (removing dead items from heap pages). The time is + accumulated across multiple passes when the TID store fills up. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>index_vacuum_time</structfield> <type>double precision</type> + </para> + <para> + Total time spent in the index vacuuming phase, in seconds (see + <xref linkend="vacuum-phases"/>). This includes the time to vacuum + all indexes on the table in each pass, and is accumulated across + multiple passes when all indexes have to be vacuumed again. + </para></entry> + </row> + + <row> + <entry role="catalog_table_entry"><para role="column_definition"> + <structfield>index_cleanup_time</structfield> <type>double precision</type> + </para> + <para> + Total time spent in the index cleanup phase, in seconds (see + <xref linkend="vacuum-phases"/>). This includes the time to + clean up all indexes on the table. + </para></entry> + </row> </tbody> </tgroup> </table> diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 39395aed0d5..bdcf424e42c 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -345,6 +345,12 @@ typedef struct LVRelState int num_dead_items_resets; Size total_dead_items_bytes; + /* Per-phase elapsed time tracking (in microseconds) */ + instr_time phase_start_time; /* when the current phase started */ + int64 heap_vacuum_elapsed_us; + int64 index_vacuum_elapsed_us; + int64 index_cleanup_elapsed_us; + /* * Total number of planned and actually launched parallel workers for * index vacuuming and index cleanup. @@ -767,6 +773,9 @@ heap_vacuum_rel(Relation rel, const VacuumParams *params, vacrel->num_index_scans = 0; vacrel->num_dead_items_resets = 0; vacrel->total_dead_items_bytes = 0; + vacrel->heap_vacuum_elapsed_us = 0; + vacrel->index_vacuum_elapsed_us = 0; + vacrel->index_cleanup_elapsed_us = 0; vacrel->tuples_deleted = 0; vacrel->tuples_frozen = 0; vacrel->lpdead_items = 0; @@ -1285,6 +1294,7 @@ lazy_scan_heap(LVRelState *vacrel) BlockNumber orig_eager_scan_success_limit = vacrel->eager_scan_remaining_successes; /* for logging */ Buffer vmbuffer = InvalidBuffer; + instr_time now; const int initprog_index[] = { PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_TOTAL_HEAP_BLKS, @@ -1298,6 +1308,9 @@ lazy_scan_heap(LVRelState *vacrel) initprog_val[2] = vacrel->dead_items_info->max_bytes; pgstat_progress_update_multi_param(3, initprog_index, initprog_val); + /* Start timing the heap scan phase */ + INSTR_TIME_SET_CURRENT(vacrel->phase_start_time); + /* Initialize for the first heap_vac_scan_next_block() call */ vacrel->current_block = InvalidBlockNumber; vacrel->next_unskippable_block = InvalidBlockNumber; @@ -1367,6 +1380,15 @@ lazy_scan_heap(LVRelState *vacrel) vmbuffer = InvalidBuffer; } + /* + * Accumulate heap vacuum time before switching to index vacuum. + */ + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SUBTRACT(now, vacrel->phase_start_time); + vacrel->heap_vacuum_elapsed_us += INSTR_TIME_GET_MICROSEC(now); + pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_VACUUM_TIME, + vacrel->heap_vacuum_elapsed_us); + /* Perform a round of index and heap vacuuming */ vacrel->consider_bypass_optimization = false; lazy_vacuum(vacrel); @@ -1383,6 +1405,9 @@ lazy_scan_heap(LVRelState *vacrel) /* Report that we are once again scanning the heap */ pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_SCAN_HEAP); + + /* Restart heap scan timing */ + INSTR_TIME_SET_CURRENT(vacrel->phase_start_time); } buf = read_stream_next_buffer(stream, &per_buffer_data); @@ -1596,6 +1621,15 @@ lazy_scan_heap(LVRelState *vacrel) read_stream_end(stream); + /* + * Accumulate final heap vacuum time before index vacuuming. + */ + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SUBTRACT(now, vacrel->phase_start_time); + vacrel->heap_vacuum_elapsed_us += INSTR_TIME_GET_MICROSEC(now); + pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_VACUUM_TIME, + vacrel->heap_vacuum_elapsed_us); + /* * Do index vacuuming (call each index's ambulkdelete routine), then do * related heap vacuuming @@ -2506,6 +2540,7 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) }; int64 progress_start_val[2]; int64 progress_end_val[3]; + instr_time now; Assert(vacrel->nindexes > 0); Assert(vacrel->do_index_vacuuming); @@ -2526,6 +2561,9 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) progress_start_val[1] = vacrel->nindexes; pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val); + /* Start timing index vacuum phase */ + INSTR_TIME_SET_CURRENT(vacrel->phase_start_time); + if (!ParallelVacuumIsActive(vacrel)) { for (int idx = 0; idx < vacrel->nindexes; idx++) @@ -2582,6 +2620,14 @@ lazy_vacuum_all_indexes(LVRelState *vacrel) * We deliberately include the case where we started a round of bulk * deletes that we weren't able to finish due to the failsafe triggering. */ + + /* Accumulate index vacuum elapsed time */ + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SUBTRACT(now, vacrel->phase_start_time); + vacrel->index_vacuum_elapsed_us += INSTR_TIME_GET_MICROSEC(now); + pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_VACUUM_TIME, + vacrel->index_vacuum_elapsed_us); + vacrel->num_index_scans++; progress_end_val[0] = 0; progress_end_val[1] = 0; @@ -2644,6 +2690,7 @@ lazy_vacuum_heap_rel(LVRelState *vacrel) Buffer vmbuffer = InvalidBuffer; LVSavedErrInfo saved_err_info; TidStoreIter *iter; + instr_time now; Assert(vacrel->do_index_vacuuming); Assert(vacrel->do_index_cleanup); @@ -2653,6 +2700,9 @@ lazy_vacuum_heap_rel(LVRelState *vacrel) pgstat_progress_update_param(PROGRESS_VACUUM_PHASE, PROGRESS_VACUUM_PHASE_VACUUM_HEAP); + /* Start timing heap vacuum (second pass) phase */ + INSTR_TIME_SET_CURRENT(vacrel->phase_start_time); + /* Update error traceback information */ update_vacuum_error_info(vacrel, &saved_err_info, VACUUM_ERRCB_PHASE_VACUUM_HEAP, @@ -2742,6 +2792,13 @@ lazy_vacuum_heap_rel(LVRelState *vacrel) vacrel->relname, vacrel->dead_items_info->num_items, vacuumed_pages))); + /* Accumulate heap vacuum (second pass) elapsed time */ + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SUBTRACT(now, vacrel->phase_start_time); + vacrel->heap_vacuum_elapsed_us += INSTR_TIME_GET_MICROSEC(now); + pgstat_progress_update_param(PROGRESS_VACUUM_HEAP_VACUUM_TIME, + vacrel->heap_vacuum_elapsed_us); + /* Revert to the previous phase information for error traceback */ restore_vacuum_error_info(vacrel, &saved_err_info); } @@ -2955,6 +3012,7 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) }; int64 progress_start_val[2]; int64 progress_end_val[2] = {0, 0}; + instr_time now; Assert(vacrel->do_index_cleanup); Assert(vacrel->nindexes > 0); @@ -2967,6 +3025,9 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) progress_start_val[1] = vacrel->nindexes; pgstat_progress_update_multi_param(2, progress_start_index, progress_start_val); + /* Start timing index cleanup phase */ + INSTR_TIME_SET_CURRENT(vacrel->phase_start_time); + if (!ParallelVacuumIsActive(vacrel)) { for (int idx = 0; idx < vacrel->nindexes; idx++) @@ -2992,6 +3053,13 @@ lazy_cleanup_all_indexes(LVRelState *vacrel) &(vacrel->worker_usage.cleanup)); } + /* Accumulate index cleanup elapsed time */ + INSTR_TIME_SET_CURRENT(now); + INSTR_TIME_SUBTRACT(now, vacrel->phase_start_time); + vacrel->index_cleanup_elapsed_us += INSTR_TIME_GET_MICROSEC(now); + pgstat_progress_update_param(PROGRESS_VACUUM_INDEX_CLEANUP_TIME, + vacrel->index_cleanup_elapsed_us); + /* Reset the progress counters */ pgstat_progress_update_multi_param(2, progress_end_index, progress_end_val); } diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql index 73a1c1c4670..50c827ae390 100644 --- a/src/backend/catalog/system_views.sql +++ b/src/backend/catalog/system_views.sql @@ -1342,7 +1342,10 @@ CREATE VIEW pg_stat_progress_vacuum AS CASE S.param13 WHEN 1 THEN 'manual' WHEN 2 THEN 'autovacuum' WHEN 3 THEN 'autovacuum_wraparound' - ELSE NULL END AS started_by + ELSE NULL END AS started_by, + S.param14 / 1000000::double precision AS heap_vacuum_time, + S.param15 / 1000000::double precision AS index_vacuum_time, + S.param16 / 1000000::double precision AS index_cleanup_time FROM pg_stat_get_progress_info('VACUUM') AS S LEFT JOIN pg_database D ON S.datid = D.oid; diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h index 2a12920c75f..dc4abc11647 100644 --- a/src/include/commands/progress.h +++ b/src/include/commands/progress.h @@ -31,6 +31,9 @@ #define PROGRESS_VACUUM_DELAY_TIME 10 #define PROGRESS_VACUUM_MODE 11 #define PROGRESS_VACUUM_STARTED_BY 12 +#define PROGRESS_VACUUM_HEAP_VACUUM_TIME 13 +#define PROGRESS_VACUUM_INDEX_VACUUM_TIME 14 +#define PROGRESS_VACUUM_INDEX_CLEANUP_TIME 15 /* Phases of vacuum (as advertised via PROGRESS_VACUUM_PHASE) */ #define PROGRESS_VACUUM_PHASE_SCAN_HEAP 1 diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out index a65a5bf0c4f..7242b929815 100644 --- a/src/test/regress/expected/rules.out +++ b/src/test/regress/expected/rules.out @@ -2202,7 +2202,10 @@ pg_stat_progress_vacuum| SELECT s.pid, WHEN 2 THEN 'autovacuum'::text WHEN 3 THEN 'autovacuum_wraparound'::text ELSE NULL::text - END AS started_by + END AS started_by, + ((s.param14)::double precision / (1000000)::double precision) AS heap_vacuum_time, + ((s.param15)::double precision / (1000000)::double precision) AS index_vacuum_time, + ((s.param16)::double precision / (1000000)::double precision) AS index_cleanup_time FROM (pg_stat_get_progress_info('VACUUM'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20) LEFT JOIN pg_database d ON ((s.datid = d.oid))); pg_stat_recovery| SELECT promote_triggered, -- 2.47.3 [application/sql] estimate_vacuum_completion.sql (1.3K, ../../CALj2ACVD08XgDcQpTSegKDiyJHwJ6eK89X+1WksWqUJxT86A_A@mail.gmail.com/4-estimate_vacuum_completion.sql) download ^ permalink raw reply [nested|flat] 179+ messages in thread
end of thread, other threads:[~2026-05-04 05:41 UTC | newest] Thread overview: 179+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2019-07-15 00:00 [PATCH 3/5] Fix handling of NULLs in MCV items and constants Tomas Vondra <[email protected]> 2023-08-14 10:59 [PATCH] Track DEALLOCATE statements in pg_stat_activity Dagfinn Ilmari Mannsåker <[email protected]> 2023-08-14 10:59 [PATCH] Track DEALLOCATE statements in pg_stat_activity Dagfinn Ilmari Mannsåker <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-01-31 15:01 [PATCH 2/2] Apply the same technique to PrintNewControlValues too Álvaro Herrera <[email protected]> 2026-05-04 05:41 Add heap and index vacuum timings to pg_stat_progress_vacuum Bharath Rupireddy <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox