v2-0003-pg_upgrade-Inherit-default-char-signedness-from-o.patch
application/octet-stream
Filename: v2-0003-pg_upgrade-Inherit-default-char-signedness-from-o.patch
Type: application/octet-stream
Part: 3
Patch
Format: format-patch
Series: patch v2-0003
Subject: pg_upgrade: Inherit default char signedness from old cluster.
| File | + | − |
|---|---|---|
| src/bin/pg_upgrade/controldata.c | 25 | 1 |
| src/bin/pg_upgrade/pg_upgrade.c | 40 | 0 |
| src/bin/pg_upgrade/pg_upgrade.h | 1 | 0 |
From 49b24b4c67b43765d06ff699cd481c2abe094c8d Mon Sep 17 00:00:00 2001
From: Masahiko Sawada <sawada.mshk@gmail.com>
Date: Wed, 2 Oct 2024 15:11:23 -0700
Subject: [PATCH v2 3/5] pg_upgrade: Inherit default char signedness from old
cluster.
Commit XXX introduced the 'default_char_signedness' field in
controlfile. Newly created database clusters always set this field to
'signed'.
This change ensures that pg_upgrade updates the
'default_char_signedness' to 'unsigned' if the source database cluster
has signedness=false. For source clusters from v17 or earlier, which
lack the 'default_char_signedness' information, pg_upgrade assumes the
source cluster was initialized on the same platform where pg_upgrae is
running. It then sets the 'default_char_signedness' value according to
the current platform's default character signedness.
Reviewed-by:
Discussion: https://postgr.es/m/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07%40amazon.com
---
src/bin/pg_upgrade/controldata.c | 26 ++++++++++++++++++++-
src/bin/pg_upgrade/pg_upgrade.c | 40 ++++++++++++++++++++++++++++++++
src/bin/pg_upgrade/pg_upgrade.h | 1 +
3 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/src/bin/pg_upgrade/controldata.c b/src/bin/pg_upgrade/controldata.c
index 854c6887a2..6c63b25647 100644
--- a/src/bin/pg_upgrade/controldata.c
+++ b/src/bin/pg_upgrade/controldata.c
@@ -62,6 +62,7 @@ get_control_data(ClusterInfo *cluster)
bool got_date_is_int = false;
bool got_data_checksum_version = false;
bool got_cluster_state = false;
+ bool got_default_char_signedness = false;
char *lc_collate = NULL;
char *lc_ctype = NULL;
char *lc_monetary = NULL;
@@ -206,6 +207,13 @@ get_control_data(ClusterInfo *cluster)
got_data_checksum_version = true;
}
+ /* Only in <= 17 */
+ if (GET_MAJOR_VERSION(cluster->major_version) <= 1700)
+ {
+ cluster->controldata.default_char_signedness = true;
+ got_default_char_signedness = true;
+ }
+
/* we have the result of cmd in "output". so parse it line by line now */
while (fgets(bufin, sizeof(bufin), output))
{
@@ -501,6 +509,17 @@ get_control_data(ClusterInfo *cluster)
cluster->controldata.data_checksum_version = str2uint(p);
got_data_checksum_version = true;
}
+ else if ((p = strstr(bufin, "char data signedness:")) != NULL)
+ {
+ p = strchr(p, ':');
+
+ if (p == NULL || strlen(p) <= 1)
+ pg_fatal("%d: controldata retrieval problem", __LINE__);
+
+ p++; /* remove ':' char */
+ cluster->controldata.default_char_signedness = strstr(p, "signed") != NULL;
+ got_default_char_signedness = true;
+ }
}
rc = pclose(output);
@@ -572,7 +591,8 @@ get_control_data(ClusterInfo *cluster)
!got_index || !got_toast ||
(!got_large_object &&
cluster->controldata.ctrl_ver >= LARGE_OBJECT_SIZE_PG_CONTROL_VER) ||
- !got_date_is_int || !got_data_checksum_version)
+ !got_date_is_int || !got_data_checksum_version ||
+ !got_default_char_signedness)
{
if (cluster == &old_cluster)
pg_log(PG_REPORT,
@@ -641,6 +661,10 @@ get_control_data(ClusterInfo *cluster)
if (!got_data_checksum_version)
pg_log(PG_REPORT, " data checksum version");
+ /* value added in Postgres 18 */
+ if (!got_default_char_signedness)
+ pg_log(PG_REPORT, " default char signedness");
+
pg_fatal("Cannot continue without required control information, terminating");
}
}
diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c
index 663235816f..68cbac46ce 100644
--- a/src/bin/pg_upgrade/pg_upgrade.c
+++ b/src/bin/pg_upgrade/pg_upgrade.c
@@ -39,6 +39,7 @@
#include "postgres_fe.h"
#include <time.h>
+#include <limits.h> /* for CHAR_MIN */
#include "catalog/pg_class_d.h"
#include "common/file_perm.h"
@@ -54,6 +55,7 @@
*/
#define RESTORE_TRANSACTION_SIZE 1000
+static void set_new_cluster_char_signedness(void);
static void set_locale_and_encoding(void);
static void prepare_new_cluster(void);
static void prepare_new_globals(void);
@@ -154,6 +156,7 @@ main(int argc, char **argv)
*/
copy_xact_xlog_xid();
+ set_new_cluster_char_signedness();
/* New now using xids of the old system */
@@ -388,6 +391,43 @@ setup(char *argv0)
}
}
+static void
+set_new_cluster_char_signedness(void)
+{
+ bool new_char_signedness;
+
+ prep_status("Setting the default char signedness for new cluster");
+
+ if (GET_MAJOR_VERSION(old_cluster.major_version) <= 17)
+ {
+ /*
+ * Pre-v18 database clusters don't have the default char signedness
+ * information. We use the char signedness of the platform where
+ * pg_upgrade was built.
+ */
+#if CHAR_MIN != 0
+ new_char_signedness = true;
+#else
+ new_char_signedness = false;
+#endif
+ }
+ else
+ {
+ /* Set the source database signedness */
+ new_char_signedness = old_cluster.controldata.default_char_signedness;
+ }
+
+ /* Change the char signedness of the new cluster, if necessary */
+ if (new_cluster.controldata.default_char_signedness != new_char_signedness)
+ {
+ exec_prog(UTILITY_LOG_FILE, NULL, true, true,
+ "\"%s/pg_resetwal\" --char-signedness %s \"%s\"",
+ new_cluster.bindir,
+ new_char_signedness ? "signed" : "unsigned",
+ new_cluster.pgdata);
+ check_ok();
+ }
+}
/*
* Copy locale and encoding information into the new cluster's template0.
diff --git a/src/bin/pg_upgrade/pg_upgrade.h b/src/bin/pg_upgrade/pg_upgrade.h
index 53f693c2d4..a2cbf2d6d9 100644
--- a/src/bin/pg_upgrade/pg_upgrade.h
+++ b/src/bin/pg_upgrade/pg_upgrade.h
@@ -245,6 +245,7 @@ typedef struct
bool date_is_int;
bool float8_pass_by_value;
uint32 data_checksum_version;
+ bool default_char_signedness;
} ControlData;
/*
--
2.39.3