@@ -21,6 +21,7 @@ static void check_for_prepared_transactions(ClusterInfo *cluster);
21
21
static void check_for_isn_and_int8_passing_mismatch (ClusterInfo * cluster );
22
22
static void check_for_reg_data_type_usage (ClusterInfo * cluster );
23
23
static void get_bin_version (ClusterInfo * cluster );
24
+ static char * get_canonical_locale_name (int category , const char * locale );
24
25
25
26
26
27
/*
@@ -359,8 +360,23 @@ set_locale_and_encoding(ClusterInfo *cluster)
359
360
i_datcollate = PQfnumber (res , "datcollate" );
360
361
i_datctype = PQfnumber (res , "datctype" );
361
362
362
- ctrl -> lc_collate = pg_strdup (PQgetvalue (res , 0 , i_datcollate ));
363
- ctrl -> lc_ctype = pg_strdup (PQgetvalue (res , 0 , i_datctype ));
363
+ if (GET_MAJOR_VERSION (cluster -> major_version ) < 902 )
364
+ {
365
+ /*
366
+ * Pre-9.2 did not canonicalize the supplied locale names
367
+ * to match what the system returns, while 9.2+ does, so
368
+ * convert pre-9.2 to match.
369
+ */
370
+ ctrl -> lc_collate = get_canonical_locale_name (LC_COLLATE ,
371
+ pg_strdup (PQgetvalue (res , 0 , i_datcollate )));
372
+ ctrl -> lc_ctype = get_canonical_locale_name (LC_CTYPE ,
373
+ pg_strdup (PQgetvalue (res , 0 , i_datctype )));
374
+ }
375
+ else
376
+ {
377
+ ctrl -> lc_collate = pg_strdup (PQgetvalue (res , 0 , i_datcollate ));
378
+ ctrl -> lc_ctype = pg_strdup (PQgetvalue (res , 0 , i_datctype ));
379
+ }
364
380
365
381
PQclear (res );
366
382
}
@@ -390,16 +406,23 @@ static void
390
406
check_locale_and_encoding (ControlData * oldctrl ,
391
407
ControlData * newctrl )
392
408
{
393
- /* These are often defined with inconsistent case, so use pg_strcasecmp(). */
409
+ /*
410
+ * These are often defined with inconsistent case, so use pg_strcasecmp().
411
+ * They also often use inconsistent hyphenation, which we cannot fix, e.g.
412
+ * UTF-8 vs. UTF8, so at least we display the mismatching values.
413
+ */
394
414
if (pg_strcasecmp (oldctrl -> lc_collate , newctrl -> lc_collate ) != 0 )
395
415
pg_log (PG_FATAL ,
396
- "old and new cluster lc_collate values do not match\n" );
416
+ "lc_collate cluster values do not match: old \"%s\", new \"%s\"\n" ,
417
+ oldctrl -> lc_collate , newctrl -> lc_collate );
397
418
if (pg_strcasecmp (oldctrl -> lc_ctype , newctrl -> lc_ctype ) != 0 )
398
419
pg_log (PG_FATAL ,
399
- "old and new cluster lc_ctype values do not match\n" );
420
+ "lc_ctype cluster values do not match: old \"%s\", new \"%s\"\n" ,
421
+ oldctrl -> lc_ctype , newctrl -> lc_ctype );
400
422
if (pg_strcasecmp (oldctrl -> encoding , newctrl -> encoding ) != 0 )
401
423
pg_log (PG_FATAL ,
402
- "old and new cluster encoding values do not match\n" );
424
+ "encoding cluster values do not match: old \"%s\", new \"%s\"\n" ,
425
+ oldctrl -> encoding , newctrl -> encoding );
403
426
}
404
427
405
428
@@ -931,3 +954,40 @@ get_bin_version(ClusterInfo *cluster)
931
954
932
955
cluster -> bin_version = (pre_dot * 100 + post_dot ) * 100 ;
933
956
}
957
+
958
+
959
+ /*
960
+ * get_canonical_locale_name
961
+ *
962
+ * Send the locale name to the system, and hope we get back a canonical
963
+ * version. This should match the backend's check_locale() function.
964
+ */
965
+ static char *
966
+ get_canonical_locale_name (int category , const char * locale )
967
+ {
968
+ char * save ;
969
+ char * res ;
970
+
971
+ save = setlocale (category , NULL );
972
+ if (!save )
973
+ pg_log (PG_FATAL , "failed to get the current locale\n" );
974
+
975
+ /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
976
+ save = pg_strdup (save );
977
+
978
+ /* set the locale with setlocale, to see if it accepts it. */
979
+ res = setlocale (category , locale );
980
+
981
+ if (!res )
982
+ pg_log (PG_FATAL , "failed to get system local name for \"%s\"\n" , res );
983
+
984
+ res = pg_strdup (res );
985
+
986
+ /* restore old value. */
987
+ if (!setlocale (category , save ))
988
+ pg_log (PG_FATAL , "failed to restore old locale \"%s\"\n" , save );
989
+
990
+ free (save );
991
+
992
+ return res ;
993
+ }
0 commit comments