Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a76eda3

Browse files
committed
Merge branch 'PGPRO10_DEV' into PGPRO10
2 parents d99b136 + b46a212 commit a76eda3

File tree

6 files changed

+395
-27
lines changed

6 files changed

+395
-27
lines changed

src/backend/commands/dbcommands.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,13 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
149149
char *dbcanonname = NULL;
150150
char dbcollprovider;
151151
char *dbcollate_full_name;
152+
char *icu_wincollate = NULL;
152153
char *langtag = NULL;
153154
const char *collate;
155+
#ifdef WIN32
156+
char *dbcollate_original;
157+
char *dbctype_original;
158+
#endif
154159

155160
/* Extract options from the statement node tree */
156161
foreach(option, stmt->options)
@@ -393,6 +398,11 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
393398

394399
/* Check that the chosen locales are valid, and get canonical spellings */
395400

401+
#ifdef WIN32
402+
dbcollate_original = dbcollate;
403+
dbctype_original = dbctype;
404+
#endif
405+
396406
if (!check_locale(LC_CTYPE, dbctype, &canonname, '\0'))
397407
ereport(ERROR,
398408
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -429,6 +439,15 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
429439
/* check lc_collate and lc_ctype for icu if we need it */
430440
if (dbcollprovider == COLLPROVIDER_ICU)
431441
{
442+
#ifdef WIN32
443+
/* set the libc canonnames for dbcollate and dbctype */
444+
445+
check_winlocale(dbcollate_original, &canonname, NULL);
446+
dbcollate = canonname;
447+
448+
check_winlocale(dbctype_original, &canonname, NULL);
449+
dbctype = canonname;
450+
#endif
432451
if (!check_locale(LC_COLLATE, dbcollate, NULL, dbcollprovider))
433452
ereport(ERROR,
434453
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -448,8 +467,17 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
448467
#ifdef USE_ICU
449468
if (dbcollprovider == COLLPROVIDER_ICU)
450469
{
451-
langtag = get_icu_language_tag(dbcollate);
452-
collate = get_icu_collate(dbcollate, langtag);
470+
#ifdef WIN32
471+
if (!locale_is_c(dbcollate))
472+
{
473+
check_winlocale(dbcollate, NULL, &icu_wincollate);
474+
collate = (const char *) icu_wincollate;
475+
}
476+
#else /* not WIN32 */
477+
collate = (const char *) dbcollate;
478+
#endif /* not WIN32 */
479+
langtag = get_icu_language_tag(collate);
480+
collate = get_icu_collate(collate, langtag);
453481
}
454482
else
455483
#endif
@@ -790,6 +818,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
790818
pfree(dbcanonname);
791819
if (langtag)
792820
pfree(langtag);
821+
if (icu_wincollate)
822+
pfree(icu_wincollate);
793823

794824
PG_END_ENSURE_ERROR_CLEANUP(createdb_failure_callback,
795825
PointerGetDatum(&fparms));

src/backend/utils/adt/pg_locale.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1836,24 +1836,39 @@ char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen,
18361836
* If locale is "" return the environment value from setlocale().
18371837
*
18381838
* Otherwise return a malloc'd copy of locale if it is not NULL.
1839+
*
1840+
* In Windows, check that the name is not long (for example,
1841+
* "English_United States[.encoding]").
18391842
*/
18401843
static char *
18411844
check_icu_locale(const char *locale)
18421845
{
1843-
if (locale)
1846+
char *canonname = NULL;
1847+
char *winlocale = NULL;
1848+
char *result;
1849+
1850+
#ifdef WIN32
1851+
if (!locale_is_c(locale))
18441852
{
1845-
if (strlen(locale) == 0)
1846-
{
1847-
char *canonname;
1853+
check_winlocale(locale, NULL, &winlocale);
1854+
locale = (const char *) winlocale;
1855+
}
1856+
#else /* not WIN32 */
1857+
if (locale && strlen(locale) == 0)
1858+
{
1859+
check_locale(LC_COLLATE, locale, &canonname, COLLPROVIDER_LIBC);
1860+
locale = (const char *) canonname;
1861+
}
1862+
#endif /* not WIN32 */
18481863

1849-
check_locale(LC_COLLATE, locale, &canonname, COLLPROVIDER_LIBC);
1850-
return canonname;
1851-
}
1864+
result = locale ? pstrdup(locale) : NULL;
18521865

1853-
return pstrdup(locale);
1854-
}
1866+
if (canonname)
1867+
pfree(canonname);
1868+
if (winlocale)
1869+
pfree(winlocale);
18551870

1856-
return NULL;
1871+
return result;
18571872
}
18581873

18591874
/*

src/backend/utils/init/postinit.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ CheckMyDatabase(const char *name, bool am_superuser)
295295
char *datcollate;
296296
char collprovider;
297297
char *collversion;
298+
char *wincollate = NULL;
298299
char *langtag = NULL;
299300
const char *collcollate;
300301
char *actual_versionstr;
@@ -437,8 +438,16 @@ CheckMyDatabase(const char *name, bool am_superuser)
437438
#ifdef USE_ICU
438439
if (collprovider == COLLPROVIDER_ICU)
439440
{
440-
langtag = get_icu_language_tag(collate);
441-
collcollate = get_icu_collate(collate, langtag);
441+
collcollate = (const char *) collate;
442+
#ifdef WIN32
443+
if (!locale_is_c(collcollate))
444+
{
445+
check_winlocale(collcollate, NULL, &wincollate);
446+
collcollate = (const char *) wincollate;
447+
}
448+
#endif /* WIN32 */
449+
langtag = get_icu_language_tag(collcollate);
450+
collcollate = get_icu_collate(collcollate, langtag);
442451
}
443452
else
444453
#endif
@@ -486,6 +495,8 @@ CheckMyDatabase(const char *name, bool am_superuser)
486495
pfree(langtag);
487496
if (actual_versionstr)
488497
pfree(actual_versionstr);
498+
if (wincollate)
499+
pfree(wincollate);
489500

490501
check_strxfrm_bug();
491502

src/bin/initdb/initdb.c

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,6 +2357,10 @@ static void
23572357
setlocales(void)
23582358
{
23592359
char *canonname;
2360+
#ifdef WIN32
2361+
char *lc_collate_original;
2362+
char *lc_ctype_original;
2363+
#endif
23602364

23612365
/*
23622366
* Set up the collation provider if possible and canonicalize the locale
@@ -2405,6 +2409,11 @@ setlocales(void)
24052409
* current environment
24062410
*/
24072411

2412+
#ifdef WIN32
2413+
lc_collate_original = pstrdup(lc_collate);
2414+
lc_ctype_original = pstrdup(lc_ctype);
2415+
#endif
2416+
24082417
check_locale_name(LC_CTYPE, lc_ctype, &canonname, '\0');
24092418
lc_ctype = canonname;
24102419

@@ -2433,6 +2442,23 @@ setlocales(void)
24332442
/* check lc_collate and lc_ctype for icu if we need it */
24342443
if (collprovider == COLLPROVIDER_ICU)
24352444
{
2445+
#ifdef WIN32
2446+
/* set the libc canonnames for lc_collate and lc_ctype */
2447+
2448+
check_winlocale(lc_collate_original, &canonname, NULL);
2449+
if (canonname == NULL && lc_collate_original != NULL)
2450+
exit(1); /* check_winlocale printed the error */
2451+
2452+
pfree(lc_collate);
2453+
lc_collate = canonname;
2454+
2455+
check_winlocale(lc_ctype_original, &canonname, NULL);
2456+
if (canonname == NULL && lc_ctype_original != NULL)
2457+
exit(1); /* check_winlocale printed the error */
2458+
2459+
pfree(lc_ctype);
2460+
lc_ctype = canonname;
2461+
#endif
24362462
check_locale_name(LC_COLLATE, lc_collate, NULL, collprovider);
24372463
if (strcmp(lc_collate, lc_ctype) != 0)
24382464
{
@@ -2459,6 +2485,11 @@ setlocales(void)
24592485
#endif
24602486

24612487
set_collation_version();
2488+
2489+
#ifdef WIN32
2490+
free(lc_collate_original);
2491+
free(lc_ctype_original);
2492+
#endif
24622493
}
24632494

24642495
/*
@@ -3474,26 +3505,44 @@ main(int argc, char *argv[])
34743505
*
34753506
* Otherwise return a malloc'd copy of locale if it is not NULL.
34763507
*
3508+
* In Windows, check that the name is not long (for example,
3509+
* "English_United States[.encoding]").
3510+
*
34773511
* This should match the backend's check_icu_locale() function.
34783512
*/
34793513
static char *
34803514
check_icu_locale_name(const char *locale)
34813515
{
3482-
if (locale)
3483-
{
3484-
if (strlen(locale) == 0)
3485-
{
3486-
char *canonname;
3516+
char *canonname = NULL;
3517+
char *winlocale = NULL;
3518+
char *result;
34873519

3488-
check_locale_name(LC_COLLATE, locale, &canonname,
3489-
COLLPROVIDER_LIBC);
3490-
return canonname;
3491-
}
3520+
#ifdef WIN32
3521+
if (!locale_is_c(locale))
3522+
{
3523+
check_winlocale(locale, NULL, &winlocale);
34923524

3493-
return pstrdup(locale);
3525+
if (winlocale == NULL && locale != NULL)
3526+
exit(1); /* check_winlocale printed the error */
3527+
else
3528+
locale = winlocale;
3529+
}
3530+
#else /* not WIN32 */
3531+
if (locale && strlen(locale) == 0)
3532+
{
3533+
check_locale_name(LC_COLLATE, locale, &canonname, COLLPROVIDER_LIBC);
3534+
locale = (const char *) canonname;
34943535
}
3536+
#endif /* not WIN32 */
34953537

3496-
return NULL;
3538+
result = locale ? pstrdup(locale) : NULL;
3539+
3540+
if (canonname)
3541+
pfree(canonname);
3542+
if (winlocale)
3543+
pfree(winlocale);
3544+
3545+
return result;
34973546
}
34983547
#endif /* USE_ICU */
34993548

@@ -3503,6 +3552,7 @@ check_icu_locale_name(const char *locale)
35033552
static void
35043553
set_collation_version(void)
35053554
{
3555+
char *wincollate = NULL;
35063556
char *langtag = NULL;
35073557
const char *collate;
35083558
bool failure;
@@ -3512,15 +3562,29 @@ set_collation_version(void)
35123562
if (collprovider == COLLPROVIDER_ICU)
35133563
{
35143564
#ifdef USE_ICU
3515-
langtag = get_icu_language_tag(lc_collate);
3565+
#ifdef WIN32
3566+
if (!locale_is_c(lc_collate))
3567+
{
3568+
check_winlocale(lc_collate, NULL, &wincollate);
3569+
3570+
if (wincollate == NULL && lc_collate != NULL)
3571+
exit(1); /* check_winlocale printed the error */
3572+
else
3573+
collate = (const char *) wincollate;
3574+
}
3575+
#else /* not WIN32 */
3576+
collate = (const char *) lc_collate;
3577+
#endif /* not WIN32 */
3578+
3579+
langtag = get_icu_language_tag(collate);
35163580
if (!langtag)
35173581
{
35183582
/* get_icu_language_tag printed the main error message */
35193583
fprintf(stderr, _("Rerun %s with a different locale selection.\n"),
35203584
progname);
35213585
exit(1);
35223586
}
3523-
collate = get_icu_collate(lc_collate, langtag);
3587+
collate = get_icu_collate(collate, langtag);
35243588
#else
35253589
fprintf(stderr,
35263590
_("%s: ICU is not supported in this build\n"
@@ -3542,4 +3606,6 @@ set_collation_version(void)
35423606

35433607
if (langtag)
35443608
free(langtag);
3609+
if (wincollate)
3610+
free(wincollate);
35453611
}

src/include/port.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,10 @@ extern char *get_collation_actual_version(char collprovider,
490490
extern UCollator *open_collator(const char *collate);
491491
extern char * get_icu_language_tag(const char *localename);
492492
extern const char *get_icu_collate(const char *locale, const char *langtag);
493+
#ifdef WIN32
494+
extern void check_winlocale(const char *winlocale, char **libc_canononame,
495+
char **icu_canonname);
496+
#endif /* WIN32 */
493497
#endif /* USE_ICU */
494498

495499
#endif /* not LIBPQ_MAKE */

0 commit comments

Comments
 (0)