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

Commit9637bad

Browse files
committed
pg_upgrade: copy locale and encoding information to new cluster.
Previously, pg_upgrade checked that the old and new clusters werecompatible, including the locale and encoding. But the new cluster wasjust created, and only template0 from the new cluster will bepreserved (template1 and postgres are both recreated during theupgrade process).Because template0 is not sensitive to locale or encoding, just updatethe pg_database entry to be the same as template0 from the originalcluster.This commit makes it easier to change the default initdb locale orencoding settings without causing needless incompatibilities.Discussion:https://postgr.es/m/d62b2874-729b-d26a-2d0a-0d64f509eca4@enterprisedb.comReviewed-by: Peter Eisentraut
1 parent8dff2f2 commit9637bad

File tree

7 files changed

+192
-183
lines changed

7 files changed

+192
-183
lines changed

‎src/bin/pg_upgrade/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ clean distclean maintainer-clean:
5151
rm -rf delete_old_cluster.sh log/ tmp_check/\
5252
reindex_hash.sql
5353

54+
exportwith_icu
55+
5456
check:
5557
$(prove_check)
5658

‎src/bin/pg_upgrade/check.c

Lines changed: 0 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
#include"pg_upgrade.h"
1717

1818
staticvoidcheck_new_cluster_is_empty(void);
19-
staticvoidcheck_databases_are_compatible(void);
20-
staticvoidcheck_locale_and_encoding(DbInfo*olddb,DbInfo*newdb);
21-
staticboolequivalent_locale(intcategory,constchar*loca,constchar*locb);
2219
staticvoidcheck_is_install_user(ClusterInfo*cluster);
2320
staticvoidcheck_proper_datallowconn(ClusterInfo*cluster);
2421
staticvoidcheck_for_prepared_transactions(ClusterInfo*cluster);
@@ -33,7 +30,6 @@ static void check_for_jsonb_9_4_usage(ClusterInfo *cluster);
3330
staticvoidcheck_for_pg_role_prefix(ClusterInfo*cluster);
3431
staticvoidcheck_for_new_tablespace_dir(ClusterInfo*new_cluster);
3532
staticvoidcheck_for_user_defined_encoding_conversions(ClusterInfo*cluster);
36-
staticchar*get_canonical_locale_name(intcategory,constchar*locale);
3733

3834

3935
/*
@@ -194,7 +190,6 @@ check_new_cluster(void)
194190
get_db_and_rel_infos(&new_cluster);
195191

196192
check_new_cluster_is_empty();
197-
check_databases_are_compatible();
198193

199194
check_loadable_libraries();
200195

@@ -349,94 +344,6 @@ check_cluster_compatibility(bool live_check)
349344
}
350345

351346

352-
/*
353-
* check_locale_and_encoding()
354-
*
355-
* Check that locale and encoding of a database in the old and new clusters
356-
* are compatible.
357-
*/
358-
staticvoid
359-
check_locale_and_encoding(DbInfo*olddb,DbInfo*newdb)
360-
{
361-
if (olddb->db_encoding!=newdb->db_encoding)
362-
pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"",
363-
olddb->db_name,
364-
pg_encoding_to_char(olddb->db_encoding),
365-
pg_encoding_to_char(newdb->db_encoding));
366-
if (!equivalent_locale(LC_COLLATE,olddb->db_collate,newdb->db_collate))
367-
pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"",
368-
olddb->db_name,olddb->db_collate,newdb->db_collate);
369-
if (!equivalent_locale(LC_CTYPE,olddb->db_ctype,newdb->db_ctype))
370-
pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"",
371-
olddb->db_name,olddb->db_ctype,newdb->db_ctype);
372-
if (olddb->db_collprovider!=newdb->db_collprovider)
373-
pg_fatal("locale providers for database \"%s\" do not match: old \"%s\", new \"%s\"",
374-
olddb->db_name,
375-
collprovider_name(olddb->db_collprovider),
376-
collprovider_name(newdb->db_collprovider));
377-
if ((olddb->db_iculocale==NULL&&newdb->db_iculocale!=NULL)||
378-
(olddb->db_iculocale!=NULL&&newdb->db_iculocale==NULL)||
379-
(olddb->db_iculocale!=NULL&&newdb->db_iculocale!=NULL&&strcmp(olddb->db_iculocale,newdb->db_iculocale)!=0))
380-
pg_fatal("ICU locale values for database \"%s\" do not match: old \"%s\", new \"%s\"",
381-
olddb->db_name,
382-
olddb->db_iculocale ?olddb->db_iculocale :"(null)",
383-
newdb->db_iculocale ?newdb->db_iculocale :"(null)");
384-
}
385-
386-
/*
387-
* equivalent_locale()
388-
*
389-
* Best effort locale-name comparison. Return false if we are not 100% sure
390-
* the locales are equivalent.
391-
*
392-
* Note: The encoding parts of the names are ignored. This function is
393-
* currently used to compare locale names stored in pg_database, and
394-
* pg_database contains a separate encoding field. That's compared directly
395-
* in check_locale_and_encoding().
396-
*/
397-
staticbool
398-
equivalent_locale(intcategory,constchar*loca,constchar*locb)
399-
{
400-
constchar*chara;
401-
constchar*charb;
402-
char*canona;
403-
char*canonb;
404-
intlena;
405-
intlenb;
406-
407-
/*
408-
* If the names are equal, the locales are equivalent. Checking this first
409-
* avoids calling setlocale() in the common case that the names are equal.
410-
* That's a good thing, if setlocale() is buggy, for example.
411-
*/
412-
if (pg_strcasecmp(loca,locb)==0)
413-
return true;
414-
415-
/*
416-
* Not identical. Canonicalize both names, remove the encoding parts, and
417-
* try again.
418-
*/
419-
canona=get_canonical_locale_name(category,loca);
420-
chara=strrchr(canona,'.');
421-
lena=chara ? (chara-canona) :strlen(canona);
422-
423-
canonb=get_canonical_locale_name(category,locb);
424-
charb=strrchr(canonb,'.');
425-
lenb=charb ? (charb-canonb) :strlen(canonb);
426-
427-
if (lena==lenb&&pg_strncasecmp(canona,canonb,lena)==0)
428-
{
429-
pg_free(canona);
430-
pg_free(canonb);
431-
return true;
432-
}
433-
434-
pg_free(canona);
435-
pg_free(canonb);
436-
return false;
437-
}
438-
439-
440347
staticvoid
441348
check_new_cluster_is_empty(void)
442349
{
@@ -460,35 +367,6 @@ check_new_cluster_is_empty(void)
460367
}
461368
}
462369

463-
/*
464-
* Check that every database that already exists in the new cluster is
465-
* compatible with the corresponding database in the old one.
466-
*/
467-
staticvoid
468-
check_databases_are_compatible(void)
469-
{
470-
intnewdbnum;
471-
intolddbnum;
472-
DbInfo*newdbinfo;
473-
DbInfo*olddbinfo;
474-
475-
for (newdbnum=0;newdbnum<new_cluster.dbarr.ndbs;newdbnum++)
476-
{
477-
newdbinfo=&new_cluster.dbarr.dbs[newdbnum];
478-
479-
/* Find the corresponding database in the old cluster */
480-
for (olddbnum=0;olddbnum<old_cluster.dbarr.ndbs;olddbnum++)
481-
{
482-
olddbinfo=&old_cluster.dbarr.dbs[olddbnum];
483-
if (strcmp(newdbinfo->db_name,olddbinfo->db_name)==0)
484-
{
485-
check_locale_and_encoding(olddbinfo,newdbinfo);
486-
break;
487-
}
488-
}
489-
}
490-
}
491-
492370
/*
493371
* A previous run of pg_upgrade might have failed and the new cluster
494372
* directory recreated, but they might have forgotten to remove
@@ -1524,41 +1402,3 @@ check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
15241402
else
15251403
check_ok();
15261404
}
1527-
1528-
1529-
/*
1530-
* get_canonical_locale_name
1531-
*
1532-
* Send the locale name to the system, and hope we get back a canonical
1533-
* version. This should match the backend's check_locale() function.
1534-
*/
1535-
staticchar*
1536-
get_canonical_locale_name(intcategory,constchar*locale)
1537-
{
1538-
char*save;
1539-
char*res;
1540-
1541-
/* get the current setting, so we can restore it. */
1542-
save=setlocale(category,NULL);
1543-
if (!save)
1544-
pg_fatal("failed to get the current locale");
1545-
1546-
/* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1547-
save=pg_strdup(save);
1548-
1549-
/* set the locale with setlocale, to see if it accepts it. */
1550-
res=setlocale(category,locale);
1551-
1552-
if (!res)
1553-
pg_fatal("failed to get system locale name for \"%s\"",locale);
1554-
1555-
res=pg_strdup(res);
1556-
1557-
/* restore old value. */
1558-
if (!setlocale(category,save))
1559-
pg_fatal("failed to restore old locale \"%s\"",save);
1560-
1561-
pg_free(save);
1562-
1563-
returnres;
1564-
}

‎src/bin/pg_upgrade/info.c

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static void create_rel_filename_map(const char *old_data, const char *new_data,
2020
staticvoidreport_unmatched_relation(constRelInfo*rel,constDbInfo*db,
2121
boolis_new_db);
2222
staticvoidfree_db_and_rel_infos(DbInfoArr*db_arr);
23+
staticvoidget_template0_info(ClusterInfo*cluster);
2324
staticvoidget_db_infos(ClusterInfo*cluster);
2425
staticvoidget_rel_infos(ClusterInfo*cluster,DbInfo*dbinfo);
2526
staticvoidfree_rel_infos(RelInfoArr*rel_arr);
@@ -278,6 +279,7 @@ get_db_and_rel_infos(ClusterInfo *cluster)
278279
if (cluster->dbarr.dbs!=NULL)
279280
free_db_and_rel_infos(&cluster->dbarr);
280281

282+
get_template0_info(cluster);
281283
get_db_infos(cluster);
282284

283285
for (dbnum=0;dbnum<cluster->dbarr.ndbs;dbnum++)
@@ -293,6 +295,55 @@ get_db_and_rel_infos(ClusterInfo *cluster)
293295
}
294296

295297

298+
/*
299+
* Get information about template0, which will be copied from the old cluster
300+
* to the new cluster.
301+
*/
302+
staticvoid
303+
get_template0_info(ClusterInfo*cluster)
304+
{
305+
PGconn*conn=connectToServer(cluster,"template1");
306+
DbLocaleInfo*locale;
307+
PGresult*dbres;
308+
inti_datencoding;
309+
inti_datlocprovider;
310+
inti_datcollate;
311+
inti_datctype;
312+
inti_daticulocale;
313+
314+
dbres=executeQueryOrDie(conn,
315+
"SELECT encoding, datlocprovider, "
316+
" datcollate, datctype, daticulocale "
317+
"FROMpg_catalog.pg_database "
318+
"WHERE datname='template0'");
319+
320+
if (PQntuples(dbres)!=1)
321+
pg_fatal("template0 not found");
322+
323+
locale=pg_malloc(sizeof(DbLocaleInfo));
324+
325+
i_datencoding=PQfnumber(dbres,"encoding");
326+
i_datlocprovider=PQfnumber(dbres,"datlocprovider");
327+
i_datcollate=PQfnumber(dbres,"datcollate");
328+
i_datctype=PQfnumber(dbres,"datctype");
329+
i_daticulocale=PQfnumber(dbres,"daticulocale");
330+
331+
locale->db_encoding=atoi(PQgetvalue(dbres,0,i_datencoding));
332+
locale->db_collprovider=PQgetvalue(dbres,0,i_datlocprovider)[0];
333+
locale->db_collate=pg_strdup(PQgetvalue(dbres,0,i_datcollate));
334+
locale->db_ctype=pg_strdup(PQgetvalue(dbres,0,i_datctype));
335+
if (PQgetisnull(dbres,0,i_daticulocale))
336+
locale->db_iculocale=NULL;
337+
else
338+
locale->db_iculocale=pg_strdup(PQgetvalue(dbres,0,i_daticulocale));
339+
340+
cluster->template0=locale;
341+
342+
PQclear(dbres);
343+
PQfinish(conn);
344+
}
345+
346+
296347
/*
297348
* get_db_infos()
298349
*
@@ -309,11 +360,6 @@ get_db_infos(ClusterInfo *cluster)
309360
DbInfo*dbinfos;
310361
inti_datname,
311362
i_oid,
312-
i_encoding,
313-
i_datcollate,
314-
i_datctype,
315-
i_datlocprovider,
316-
i_daticulocale,
317363
i_spclocation;
318364
charquery[QUERY_ALLOC];
319365

@@ -337,11 +383,6 @@ get_db_infos(ClusterInfo *cluster)
337383

338384
i_oid=PQfnumber(res,"oid");
339385
i_datname=PQfnumber(res,"datname");
340-
i_encoding=PQfnumber(res,"encoding");
341-
i_datcollate=PQfnumber(res,"datcollate");
342-
i_datctype=PQfnumber(res,"datctype");
343-
i_datlocprovider=PQfnumber(res,"datlocprovider");
344-
i_daticulocale=PQfnumber(res,"daticulocale");
345386
i_spclocation=PQfnumber(res,"spclocation");
346387

347388
ntups=PQntuples(res);
@@ -351,14 +392,6 @@ get_db_infos(ClusterInfo *cluster)
351392
{
352393
dbinfos[tupnum].db_oid=atooid(PQgetvalue(res,tupnum,i_oid));
353394
dbinfos[tupnum].db_name=pg_strdup(PQgetvalue(res,tupnum,i_datname));
354-
dbinfos[tupnum].db_encoding=atoi(PQgetvalue(res,tupnum,i_encoding));
355-
dbinfos[tupnum].db_collate=pg_strdup(PQgetvalue(res,tupnum,i_datcollate));
356-
dbinfos[tupnum].db_ctype=pg_strdup(PQgetvalue(res,tupnum,i_datctype));
357-
dbinfos[tupnum].db_collprovider=PQgetvalue(res,tupnum,i_datlocprovider)[0];
358-
if (PQgetisnull(res,tupnum,i_daticulocale))
359-
dbinfos[tupnum].db_iculocale=NULL;
360-
else
361-
dbinfos[tupnum].db_iculocale=pg_strdup(PQgetvalue(res,tupnum,i_daticulocale));
362395
snprintf(dbinfos[tupnum].db_tablespace,sizeof(dbinfos[tupnum].db_tablespace),"%s",
363396
PQgetvalue(res,tupnum,i_spclocation));
364397
}

‎src/bin/pg_upgrade/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ tests += {
3838
'sd':meson.current_source_dir(),
3939
'bd':meson.current_build_dir(),
4040
'tap': {
41+
'env': {'with_icu': icu.found() ?'yes' :'no'},
4142
'tests': [
4243
't/001_basic.pl',
4344
't/002_pg_upgrade.pl',

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp