Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita8238f8

Browse files
pg_upgrade: Preserve default char signedness value from old cluster.
Commit44fe30f introduced the 'default_char_signedness' field incontrolfile. 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 clusterhas signedness=false. For source clusters from v17 or earlier, whichlack the 'default_char_signedness' information, pg_upgrade assumes thesource cluster was initialized on the same platform where pg_upgradeis running. It then sets the 'default_char_signedness' value accordingto the current platform's default character signedness.Reviewed-by: Noah Misch <noah@leadboat.com>Discussion:https://postgr.es/m/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07%40amazon.com
1 parent30666d1 commita8238f8

File tree

4 files changed

+142
-1
lines changed

4 files changed

+142
-1
lines changed

‎src/bin/pg_upgrade/controldata.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include"postgres_fe.h"
1111

1212
#include<ctype.h>
13+
#include<limits.h>/* for CHAR_MIN */
1314

1415
#include"common/string.h"
1516
#include"pg_upgrade.h"
@@ -62,6 +63,7 @@ get_control_data(ClusterInfo *cluster)
6263
boolgot_date_is_int= false;
6364
boolgot_data_checksum_version= false;
6465
boolgot_cluster_state= false;
66+
boolgot_default_char_signedness= false;
6567
char*lc_collate=NULL;
6668
char*lc_ctype=NULL;
6769
char*lc_monetary=NULL;
@@ -501,6 +503,25 @@ get_control_data(ClusterInfo *cluster)
501503
cluster->controldata.data_checksum_version=str2uint(p);
502504
got_data_checksum_version= true;
503505
}
506+
elseif ((p=strstr(bufin,"Default char data signedness:"))!=NULL)
507+
{
508+
p=strchr(p,':');
509+
510+
if (p==NULL||strlen(p) <=1)
511+
pg_fatal("%d: controldata retrieval problem",__LINE__);
512+
513+
/* Skip the colon and any whitespace after it */
514+
p++;
515+
while (isspace((unsignedchar)*p))
516+
p++;
517+
518+
/* The value should be either 'signed' or 'unsigned' */
519+
if (strcmp(p,"signed")!=0&&strcmp(p,"unsigned")!=0)
520+
pg_fatal("%d: controldata retrieval problem",__LINE__);
521+
522+
cluster->controldata.default_char_signedness=strcmp(p,"signed")==0;
523+
got_default_char_signedness= true;
524+
}
504525
}
505526

506527
rc=pclose(output);
@@ -561,6 +582,21 @@ get_control_data(ClusterInfo *cluster)
561582
}
562583
}
563584

585+
/*
586+
* Pre-v18 database clusters don't have the default char signedness
587+
* information. We use the char signedness of the platform where
588+
* pg_upgrade was built.
589+
*/
590+
if (cluster->controldata.cat_ver<DEFAULT_CHAR_SIGNEDNESS_CAT_VER)
591+
{
592+
Assert(!got_default_char_signedness);
593+
#ifCHAR_MIN!=0
594+
cluster->controldata.default_char_signedness= true;
595+
#else
596+
cluster->controldata.default_char_signedness= false;
597+
#endif
598+
}
599+
564600
/* verify that we got all the mandatory pg_control data */
565601
if (!got_xid|| !got_oid||
566602
!got_multi|| !got_oldestxid||
@@ -572,7 +608,9 @@ get_control_data(ClusterInfo *cluster)
572608
!got_index|| !got_toast||
573609
(!got_large_object&&
574610
cluster->controldata.ctrl_ver >=LARGE_OBJECT_SIZE_PG_CONTROL_VER)||
575-
!got_date_is_int|| !got_data_checksum_version)
611+
!got_date_is_int|| !got_data_checksum_version||
612+
(!got_default_char_signedness&&
613+
cluster->controldata.cat_ver >=DEFAULT_CHAR_SIGNEDNESS_CAT_VER))
576614
{
577615
if (cluster==&old_cluster)
578616
pg_log(PG_REPORT,
@@ -641,6 +679,10 @@ get_control_data(ClusterInfo *cluster)
641679
if (!got_data_checksum_version)
642680
pg_log(PG_REPORT," data checksum version");
643681

682+
/* value added in Postgres 18 */
683+
if (!got_default_char_signedness)
684+
pg_log(PG_REPORT," default char signedness");
685+
644686
pg_fatal("Cannot continue without required control information, terminating");
645687
}
646688
}

‎src/bin/pg_upgrade/pg_upgrade.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
*/
5555
#defineRESTORE_TRANSACTION_SIZE 1000
5656

57+
staticvoidset_new_cluster_char_signedness(void);
5758
staticvoidset_locale_and_encoding(void);
5859
staticvoidprepare_new_cluster(void);
5960
staticvoidprepare_new_globals(void);
@@ -154,6 +155,7 @@ main(int argc, char **argv)
154155
*/
155156

156157
copy_xact_xlog_xid();
158+
set_new_cluster_char_signedness();
157159

158160
/* New now using xids of the old system */
159161

@@ -388,6 +390,32 @@ setup(char *argv0)
388390
}
389391
}
390392

393+
/*
394+
* Set the new cluster's default char signedness using the old cluster's
395+
* value.
396+
*/
397+
staticvoid
398+
set_new_cluster_char_signedness(void)
399+
{
400+
boolnew_char_signedness;
401+
402+
/* Inherit the source database's signedness */
403+
new_char_signedness=old_cluster.controldata.default_char_signedness;
404+
405+
/* Change the char signedness of the new cluster, if necessary */
406+
if (new_cluster.controldata.default_char_signedness!=new_char_signedness)
407+
{
408+
prep_status("Setting the default char signedness for new cluster");
409+
410+
exec_prog(UTILITY_LOG_FILE,NULL, true, true,
411+
"\"%s/pg_resetwal\" --char-signedness %s \"%s\"",
412+
new_cluster.bindir,
413+
new_char_signedness ?"signed" :"unsigned",
414+
new_cluster.pgdata);
415+
416+
check_ok();
417+
}
418+
}
391419

392420
/*
393421
* Copy locale and encoding information into the new cluster's template0.

‎src/bin/pg_upgrade/pg_upgrade.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ extern char *output_files[];
125125
*/
126126
#defineJSONB_FORMAT_CHANGE_CAT_VER 201409291
127127

128+
/*
129+
* The control file was changed to have the default char signedness,
130+
* commit 44fe30fdab6746a287163e7cc093fd36cda8eb92
131+
*/
132+
#defineDEFAULT_CHAR_SIGNEDNESS_CAT_VER 202502212
128133

129134
/*
130135
* Each relation is represented by a relinfo structure.
@@ -245,6 +250,7 @@ typedef struct
245250
booldate_is_int;
246251
boolfloat8_pass_by_value;
247252
uint32data_checksum_version;
253+
booldefault_char_signedness;
248254
}ControlData;
249255

250256
/*
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Copyright (c) 2025, PostgreSQL Global Development Group
2+
3+
# Tests for handling the default char signedness during upgrade.
4+
5+
use strict;
6+
use warningsFATAL=>'all';
7+
8+
use PostgreSQL::Test::Cluster;
9+
use PostgreSQL::Test::Utils;
10+
use Test::More;
11+
12+
# Can be changed to test the other modes
13+
my$mode =$ENV{PG_TEST_PG_UPGRADE_MODE} ||'--copy';
14+
15+
# Initialize old and new clusters
16+
my$old = PostgreSQL::Test::Cluster->new('old');
17+
my$new = PostgreSQL::Test::Cluster->new('new');
18+
$old->init();
19+
$new->init();
20+
21+
# Check the default char signedness of both the old and the new clusters.
22+
# Newly created clusters unconditionally use 'signed'.
23+
command_like(
24+
['pg_controldata',$old->data_dir ],
25+
qr/Default char data signedness:\s+signed/,
26+
'default char signedness of old cluster is signed in control file');
27+
command_like(
28+
['pg_controldata',$new->data_dir ],
29+
qr/Default char data signedness:\s+signed/,
30+
'default char signedness of new cluster is signed in control file');
31+
32+
# Set the old cluster's default char signedness to unsigned for test.
33+
command_ok(
34+
['pg_resetwal','--char-signedness','unsigned','-f',$old->data_dir ],
35+
"set old cluster's default char signedness to unsigned");
36+
37+
# Check if the value is successfully updated.
38+
command_like(
39+
['pg_controldata',$old->data_dir ],
40+
qr/Default char data signedness:\s+unsigned/,
41+
'updated default char signedness is unsigned in control file');
42+
43+
# pg_upgrade should be successful.
44+
command_ok(
45+
[
46+
'pg_upgrade','--no-sync',
47+
'-d',$old->data_dir,
48+
'-D',$new->data_dir,
49+
'-b',$old->config_data('--bindir'),
50+
'-B',$new->config_data('--bindir'),
51+
'-s',$new->host,
52+
'-p',$old->port,
53+
'-P',$new->port,
54+
$mode
55+
],
56+
'run of pg_upgrade');
57+
58+
# Check if the default char signedness of the new cluster inherited
59+
# the old cluster's value.
60+
command_like(
61+
['pg_controldata',$new->data_dir ],
62+
qr/Default char data signedness:\s+unsigned/,
63+
'the default char signedness is updated during pg_upgrade');
64+
65+
done_testing();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp