From a70c3b59afd6715fbbd566c3b66ca2c42dfdd25d Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 2 Oct 2024 15:12:27 -0700 Subject: [PATCH v2 4/5] pg_upgrade: Add --set-char-signedness to set the default char signedness of new cluster. This change adds a new option --set-char-signedness to pg_upgrade. It enables user to set arbitrary signedness during pg_upgrade. This helps cases where user who knew they copied the v17 source cluster from x86 (signedness=true) to ARM (signedness=falese) can pg_upgrade properly without the prerequisite of acquiring an x86 VM. Reviewed-by: Discussion: https://postgr.es/m/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07%40amazon.com --- doc/src/sgml/ref/pgupgrade.sgml | 18 ++++++++++++++++++ src/bin/pg_upgrade/option.c | 12 +++++++++++- src/bin/pg_upgrade/pg_upgrade.c | 7 ++++++- src/bin/pg_upgrade/pg_upgrade.h | 3 +++ 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/doc/src/sgml/ref/pgupgrade.sgml b/doc/src/sgml/ref/pgupgrade.sgml index 4777381dac..91c96d70d7 100644 --- a/doc/src/sgml/ref/pgupgrade.sgml +++ b/doc/src/sgml/ref/pgupgrade.sgml @@ -276,6 +276,24 @@ PostgreSQL documentation + + option + + + Manually set the default char signedness of new clusters. Possible values + are signed and unsigned. + + + The signedness of the 'char' type in C is implementation-dependent. For instance, + 'signed char' is used by default on x86 CPUs, while 'unsigned char' is used on aarch + CPUs. pg_upgrade automatically inherits the char + signedness from the old cluster. This option is useful for upgrading the cluster + that user knew they copied it to a platform having different char signedness + (e.g. from x86 to aarch). + + + + diff --git a/src/bin/pg_upgrade/option.c b/src/bin/pg_upgrade/option.c index 6f41d63eed..9708e2e745 100644 --- a/src/bin/pg_upgrade/option.c +++ b/src/bin/pg_upgrade/option.c @@ -60,6 +60,7 @@ parseCommandLine(int argc, char *argv[]) {"copy", no_argument, NULL, 2}, {"copy-file-range", no_argument, NULL, 3}, {"sync-method", required_argument, NULL, 4}, + {"set-char-signedness", required_argument, NULL, 5}, {NULL, 0, NULL, 0} }; @@ -70,6 +71,7 @@ parseCommandLine(int argc, char *argv[]) user_opts.do_sync = true; user_opts.transfer_mode = TRANSFER_MODE_COPY; + user_opts.char_signedness = -1; os_info.progname = get_progname(argv[0]); @@ -211,7 +213,14 @@ parseCommandLine(int argc, char *argv[]) exit(1); user_opts.sync_method = pg_strdup(optarg); break; - + case 5: + if (pg_strcasecmp(optarg, "signed") == 0) + user_opts.char_signedness = 1; + else if (pg_strcasecmp(optarg, "unsigned") == 0) + user_opts.char_signedness = 0; + else + pg_fatal("invalid argument for option %s", "--set-char-signedness"); + break; default: fprintf(stderr, _("Try \"%s --help\" for more information.\n"), os_info.progname); @@ -307,6 +316,7 @@ usage(void) printf(_(" --copy copy files to new cluster (default)\n")); printf(_(" --copy-file-range copy files to new cluster with copy_file_range\n")); printf(_(" --sync-method=METHOD set method for syncing files to disk\n")); + printf(_(" --set-char-signedness=OPTION set new cluster char signedness to \"signed\" or \"unsigned\"")); printf(_(" -?, --help show this help, then exit\n")); printf(_("\n" "Before running pg_upgrade you must:\n" diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index 68cbac46ce..6be853672c 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -398,7 +398,12 @@ set_new_cluster_char_signedness(void) prep_status("Setting the default char signedness for new cluster"); - if (GET_MAJOR_VERSION(old_cluster.major_version) <= 17) + if (user_opts.char_signedness != -1) + { + /* Use the specified char signedness */ + new_char_signedness = (user_opts.char_signedness == 1); + } + else if (GET_MAJOR_VERSION(old_cluster.major_version) <= 17) { /* * Pre-v18 database clusters don't have the default char signedness diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h index a2cbf2d6d9..2fbed64d7f 100644 --- a/src/bin/pg_upgrade/pg_upgrade.h +++ b/src/bin/pg_upgrade/pg_upgrade.h @@ -328,6 +328,9 @@ typedef struct int jobs; /* number of processes/threads to use */ char *socketdir; /* directory to use for Unix sockets */ char *sync_method; + int char_signedness; /* default char signedness: -1 for initial + * value, 1 for "signed" and 0 for + * "unsigned" */ } UserOpts; typedef struct -- 2.39.3