agora inbox for [email protected]help / color / mirror / Atom feed
[PATCH 3/5] Fix handling of NULLs in MCV items and constants 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ 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; 180+ 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] 180+ messages in thread
* [PATCH v47 8/9] Error out any process that would block at REPACK @ 2026-03-25 19:35 Álvaro Herrera <[email protected]> 0 siblings, 0 replies; 180+ messages in thread From: Álvaro Herrera @ 2026-03-25 19:35 UTC (permalink / raw) Any process waiting on REPACK to release its lock would actually cause it to deadlock when it tries to upgrade its lock to AEL, losing all work done to that point. We avoid this by teaching the deadlock detector to raise an error when this condition is detected. --- src/backend/commands/repack.c | 52 ++++++++---- src/backend/storage/lmgr/deadlock.c | 15 ++++ src/include/storage/proc.h | 6 +- src/test/modules/injection_points/Makefile | 1 + .../expected/repack_deadlock.out | 63 ++++++++++++++ src/test/modules/injection_points/meson.build | 1 + .../specs/repack_deadlock.spec | 83 +++++++++++++++++++ 7 files changed, 202 insertions(+), 19 deletions(-) create mode 100644 src/test/modules/injection_points/expected/repack_deadlock.out create mode 100644 src/test/modules/injection_points/specs/repack_deadlock.spec diff --git a/src/backend/commands/repack.c b/src/backend/commands/repack.c index 9c807f75d71..3acb2e1d2ba 100644 --- a/src/backend/commands/repack.c +++ b/src/backend/commands/repack.c @@ -276,6 +276,16 @@ ExecRepack(ParseState *pstate, RepackStmt *stmt, bool isTopLevel) /* Determine the lock mode to use. */ lockmode = RepackLockLevel((params.options & CLUOPT_CONCURRENT) != 0); + /* + * If in concurrent mode, set the PROC_IN_CONCURRENT_REPACK flag. This + * makes the deadlock checker cause anyone that would conflict with us + * to error out. It's important to set this flag ahead of actually locking + * the relation; it won't of course affect anyone until we do have a lock + * that others can conflict with. + */ + if ((params.options & CLUOPT_CONCURRENT) != 0) + MyProc->statusFlags |= PROC_IN_CONCURRENT_REPACK; + /* * If a single relation is specified, process it and we're done ... unless * the relation is a partitioned table, in which case we fall through. @@ -476,11 +486,8 @@ RepackLockLevel(bool concurrent) * If indexOid is InvalidOid, the table will be rewritten in physical order * instead of index order. * - * Note that, in the concurrent case, the function releases the lock at some - * point, in order to get AccessExclusiveLock for the final steps (i.e. to - * swap the relation files). To make things simpler, the caller should expect - * OldHeap to be closed on return, regardless CLUOPT_CONCURRENT. (The - * AccessExclusiveLock is kept till the end of the transaction.) + * On return, OldHeap is closed but locked with AccessExclusiveLock - the lock + * will be released at end of the transaction. * * 'cmd' indicates which command is being executed, to be used for error * messages. @@ -512,10 +519,12 @@ cluster_rel(RepackCommand cmd, Relation OldHeap, Oid indexOid, /* * Make sure we're not in a transaction block. * - * The reason is that repack_setup_logical_decoding() could deadlock - * if there's an XID already assigned. It would be possible to run in - * a transaction block if we had no XID, but this restriction is - * simpler for users to understand and we don't lose anything. + * The reason is that repack_setup_logical_decoding() could wait + * indefinitely for our XID to complete. (The deadlock detector would + * not recognize it because we'd be waiting for ourselves, i.e. no + * real lock conflict.) It would be possible to run in a transaction + * block if we had no XID, but this restriction is simpler for users + * to understand and we don't lose anything. */ PreventInTransactionBlock(isTopLevel, "REPACK (CONCURRENTLY)"); @@ -998,10 +1007,8 @@ rebuild_relation(Relation OldHeap, Relation index, bool verbose, * Note that the worker has to wait for all transactions with XID * already assigned to finish. If some of those transactions is * waiting for a lock conflicting with ShareUpdateExclusiveLock on our - * table (e.g. it runs CREATE INDEX), we can end up in a deadlock. - * Not sure this risk is worth unlocking/locking the table (and its - * clustering index) and checking again if it's still eligible for - * REPACK CONCURRENTLY. + * table (e.g. it runs CREATE INDEX), it should encounter ERROR in the + * deadlock checking code. */ start_repack_decoding_worker(tableOid); @@ -3090,7 +3097,16 @@ rebuild_relation_finish_concurrent(Relation NewHeap, Relation OldHeap, LockRelationOid(OldHeap->rd_rel->reltoastrelid, AccessExclusiveLock); /* - * Tuples and pages of the old heap will be gone, but the heap will stay. + * Now that we have all access-exclusive locks on all relations, we no + * longer want other processes to error out when trying to acquire a + * conflicting lock. Therefore, unset our flag. + */ + MyProc->statusFlags &= ~PROC_IN_CONCURRENT_REPACK; + + /* + * Tuples and pages of the old heap will be gone, but the heap itself will + * stay. In order for predicate locks to continue to work, convert them + * to relation-level locks. We do this both for table and indexes. */ TransferPredicateLocksToHeapRelation(OldHeap); foreach_ptr(RelationData, index, indexrels) @@ -3287,9 +3303,11 @@ start_repack_decoding_worker(Oid relid) /* * The decoding setup must be done before the caller can have XID assigned - * for any reason, otherwise the worker might end up in a deadlock, - * waiting for the caller's transaction to end. Therefore wait here until - * the worker indicates that it has the logical decoding initialized. + * for any reason, otherwise the worker might end up waiting for the + * caller's transaction to end. (Deadlock detector does not consider this + * a conflict because the worker is in the same locking group as the + * backend that launched it.) Therefore wait here until the worker + * indicates that it has the logical decoding initialized. */ ConditionVariablePrepareToSleep(&shared->cv); for (;;) diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index b8962d875b6..3d3ec0da111 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -620,6 +620,21 @@ FindLockCycleRecurseMember(PGPROC *checkProc, proc->statusFlags & PROC_IS_AUTOVACUUM) blocking_autovacuum_proc = proc; + /* + * Similarly, if we note that we're blocked by some process + * running REPACK (CONCURRENTLY), just fail. That process + * is going to upgrade its lock at some point, and it would + * be inappropriate for any other process to cause that + * to fail. + */ + if (checkProc == MyProc && + proc->statusFlags & PROC_IN_CONCURRENT_REPACK) + ereport(ERROR, + errcode(ERRCODE_OBJECT_IN_USE), + errmsg("could not wait for concurrent REPACK"), + errdetail("Process %d waits for REPACK running on process %d", + MyProc->pid, proc->pid)); + /* We're done looking at this proclock */ break; } diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h index 1dad125706e..8ad9718f3d6 100644 --- a/src/include/storage/proc.h +++ b/src/include/storage/proc.h @@ -69,10 +69,12 @@ struct XidCache #define PROC_AFFECTS_ALL_HORIZONS 0x20 /* this proc's xmin must be * included in vacuum horizons * in all databases */ +#define PROC_IN_CONCURRENT_REPACK 0x40 /* REPACK (CONCURRENTLY) */ -/* flags reset at EOXact */ +/* flags reset at EOXact. A bit of a misnomer ... */ #define PROC_VACUUM_STATE_MASK \ - (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND) + (PROC_IN_VACUUM | PROC_IN_SAFE_IC | PROC_VACUUM_FOR_WRAPAROUND | \ + PROC_IN_CONCURRENT_REPACK) /* * Xmin-related flags. Make sure any flags that affect how the process' Xmin diff --git a/src/test/modules/injection_points/Makefile b/src/test/modules/injection_points/Makefile index 2cd7d87c533..f7663859fe2 100644 --- a/src/test/modules/injection_points/Makefile +++ b/src/test/modules/injection_points/Makefile @@ -15,6 +15,7 @@ REGRESS_OPTS = --dlpath=$(top_builddir)/src/test/regress ISOLATION = basic \ inplace \ repack \ + repack_deadlock \ repack_toast \ syscache-update-pruned \ heap_lock_update diff --git a/src/test/modules/injection_points/expected/repack_deadlock.out b/src/test/modules/injection_points/expected/repack_deadlock.out new file mode 100644 index 00000000000..a86e4767536 --- /dev/null +++ b/src/test/modules/injection_points/expected/repack_deadlock.out @@ -0,0 +1,63 @@ +Parsed test spec with 2 sessions + +starting permutation: wait_before_lock add_column wakeup_before_lock check1 +injection_points_attach +----------------------- + +(1 row) + +step wait_before_lock: + REPACK (CONCURRENTLY) repack_deadlock USING INDEX repack_deadlock_pkey; + <waiting ...> +step add_column: + alter table repack_deadlock add column noise text; + <waiting ...> +step add_column: <... completed> +ERROR: could not wait for concurrent REPACK +step wakeup_before_lock: + SELECT injection_points_wakeup('repack-concurrently-before-lock'); + +injection_points_wakeup +----------------------- + +(1 row) + +step wait_before_lock: <... completed> +step check1: + INSERT INTO relfilenodes(node) + SELECT relfilenode FROM pg_class WHERE relname='repack_deadlock'; + + SELECT count(DISTINCT node) FROM relfilenodes; + + SELECT i, j FROM repack_deadlock ORDER BY i, j; + + INSERT INTO data_s1(i, j) + SELECT i, j FROM repack_deadlock; + + SELECT count(*) + FROM data_s1 d1 FULL JOIN data_s2 d2 USING (i, j) + WHERE d1.i ISNULL OR d2.i ISNULL; + +count +----- + 1 +(1 row) + +i|j +-+- +1|1 +2|2 +3|3 +4|4 +(4 rows) + +count +----- + 4 +(1 row) + +injection_points_detach +----------------------- + +(1 row) + diff --git a/src/test/modules/injection_points/meson.build b/src/test/modules/injection_points/meson.build index a414abb924b..1cd88d6db65 100644 --- a/src/test/modules/injection_points/meson.build +++ b/src/test/modules/injection_points/meson.build @@ -46,6 +46,7 @@ tests += { 'basic', 'inplace', 'repack', + 'repack_deadlock', 'repack_toast', 'syscache-update-pruned', 'heap_lock_update', diff --git a/src/test/modules/injection_points/specs/repack_deadlock.spec b/src/test/modules/injection_points/specs/repack_deadlock.spec new file mode 100644 index 00000000000..9d23a6588c2 --- /dev/null +++ b/src/test/modules/injection_points/specs/repack_deadlock.spec @@ -0,0 +1,83 @@ +# Test REPACK with a concurrent transaction that would cause a deadlock +setup +{ + CREATE EXTENSION injection_points; + + CREATE TABLE repack_deadlock(i int PRIMARY KEY, j int); + INSERT INTO repack_deadlock(i, j) VALUES (1, 1), (2, 2), (3, 3), (4, 4); + + CREATE TABLE relfilenodes(node oid); + + CREATE TABLE data_s1(i int, j int); + CREATE TABLE data_s2(i int, j int); +} + +teardown +{ + DROP TABLE repack_deadlock; + DROP EXTENSION injection_points; + + DROP TABLE relfilenodes; + DROP TABLE data_s1; + DROP TABLE data_s2; +} + +session s1 +setup +{ + SELECT injection_points_set_local(); + SELECT injection_points_attach('repack-concurrently-before-lock', 'wait'); +} +# Perform the initial load and wait for s2 to do some data changes. +step wait_before_lock +{ + REPACK (CONCURRENTLY) repack_deadlock USING INDEX repack_deadlock_pkey; +} +# Check the table from the perspective of s1. +# +# Besides the contents, we also check that relfilenode has changed. + +# Have each session write the contents into a table and use FULL JOIN to check +# if the outputs are identical. +step check1 +{ + INSERT INTO relfilenodes(node) + SELECT relfilenode FROM pg_class WHERE relname='repack_deadlock'; + + SELECT count(DISTINCT node) FROM relfilenodes; + + SELECT i, j FROM repack_deadlock ORDER BY i, j; + + INSERT INTO data_s1(i, j) + SELECT i, j FROM repack_deadlock; + + SELECT count(*) + FROM data_s1 d1 FULL JOIN data_s2 d2 USING (i, j) + WHERE d1.i ISNULL OR d2.i ISNULL; +} +teardown +{ + SELECT injection_points_detach('repack-concurrently-before-lock'); +} + +session s2 +# Change the existing data. UPDATE changes both key and non-key columns. Also +# update one row twice to test whether tuple version generated by this session +# can be found. +step add_column +{ + alter table repack_deadlock add column noise text; +} + +step wakeup_before_lock +{ + SELECT injection_points_wakeup('repack-concurrently-before-lock'); +} + +# Test if data changes introduced while one session is performing REPACK +# CONCURRENTLY find their way into the table. +permutation + wait_before_lock + add_column + wakeup_before_lock + check1 -- 2.47.3 --2fxmamo6mu2qbxgv Content-Type: text/x-diff; charset=utf-8 Content-Disposition: attachment; filename="v47-0009-Teach-snapshot-builder-to-skip-transactions-runn.patch" ^ permalink raw reply [nested|flat] 180+ 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; 180+ 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] 180+ messages in thread
end of thread, other threads:[~2026-05-04 05:41 UTC | newest] Thread overview: 180+ 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-03-25 19:35 [PATCH v47 8/9] Error out any process that would block at REPACK Á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