diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 79dece9..077d29a 100644 *** a/src/backend/utils/adt/pg_locale.c --- b/src/backend/utils/adt/pg_locale.c *************** free_struct_lconv(struct lconv * s) *** 387,392 **** --- 387,410 ---- } + static char * + db_encoding_strdup(int encoding, const char *str) + { + char *pstr; + char *mstr; + + /* convert the string to the database encoding */ + pstr = (char *) pg_do_encoding_conversion( + (unsigned char *) str, strlen(str), + encoding, GetDatabaseEncoding()); + mstr = strdup(pstr); + if (pstr != str) + pfree(pstr); + + return mstr; + } + + /* * Return the POSIX lconv struct (contains number/money formatting * information) with locale information for all categories. *************** PGLC_localeconv(void) *** 398,403 **** --- 416,429 ---- struct lconv *extlconv; char *save_lc_monetary; char *save_lc_numeric; + char *decimal_point; + char *grouping; + char *thousands_sep; + int encoding; + + #ifdef WIN32 + char *save_lc_ctype; + #endif /* Did we do it already? */ if (CurrentLocaleConvValid) *************** PGLC_localeconv(void) *** 413,439 **** if (save_lc_numeric) save_lc_numeric = pstrdup(save_lc_numeric); ! setlocale(LC_MONETARY, locale_monetary); setlocale(LC_NUMERIC, locale_numeric); ! /* Get formatting information */ extlconv = localeconv(); /* * Must copy all values since restoring internal settings may overwrite * localeconv()'s results. */ CurrentLocaleConv = *extlconv; ! CurrentLocaleConv.currency_symbol = strdup(extlconv->currency_symbol); ! CurrentLocaleConv.decimal_point = strdup(extlconv->decimal_point); ! CurrentLocaleConv.grouping = strdup(extlconv->grouping); ! CurrentLocaleConv.thousands_sep = strdup(extlconv->thousands_sep); ! CurrentLocaleConv.int_curr_symbol = strdup(extlconv->int_curr_symbol); ! CurrentLocaleConv.mon_decimal_point = strdup(extlconv->mon_decimal_point); CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping); ! CurrentLocaleConv.mon_thousands_sep = strdup(extlconv->mon_thousands_sep); ! CurrentLocaleConv.negative_sign = strdup(extlconv->negative_sign); ! CurrentLocaleConv.positive_sign = strdup(extlconv->positive_sign); CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn; /* Try to restore internal settings */ --- 439,486 ---- if (save_lc_numeric) save_lc_numeric = pstrdup(save_lc_numeric); ! #ifdef WIN32 ! /* set user's value of ctype locale */ ! save_lc_ctype = setlocale(LC_CTYPE, NULL); ! if (save_lc_ctype) ! save_lc_ctype = pstrdup(save_lc_ctype); ! #endif ! ! /* Get formatting information for numeric */ ! #ifdef WIN32 ! setlocale(LC_CTYPE, locale_numeric); ! #endif setlocale(LC_NUMERIC, locale_numeric); + extlconv = localeconv(); + encoding = pg_get_encoding_from_locale(locale_numeric); ! decimal_point = db_encoding_strdup(encoding, extlconv->decimal_point); ! grouping = strdup(extlconv->grouping); ! thousands_sep = db_encoding_strdup(encoding, extlconv->thousands_sep); ! ! /* Get formatting information for monetary */ ! #ifdef WIN32 ! setlocale(LC_CTYPE, locale_monetary); ! #endif ! setlocale(LC_MONETARY, locale_monetary); extlconv = localeconv(); + encoding = pg_get_encoding_from_locale(locale_monetary); /* * Must copy all values since restoring internal settings may overwrite * localeconv()'s results. */ CurrentLocaleConv = *extlconv; ! CurrentLocaleConv.decimal_point = decimal_point; ! CurrentLocaleConv.grouping = grouping; ! CurrentLocaleConv.thousands_sep = thousands_sep; ! CurrentLocaleConv.currency_symbol = db_encoding_strdup(encoding, extlconv->currency_symbol); ! CurrentLocaleConv.int_curr_symbol = db_encoding_strdup(encoding, extlconv->int_curr_symbol); ! CurrentLocaleConv.mon_decimal_point = db_encoding_strdup(encoding, extlconv->mon_decimal_point); CurrentLocaleConv.mon_grouping = strdup(extlconv->mon_grouping); ! CurrentLocaleConv.mon_thousands_sep = db_encoding_strdup(encoding, extlconv->mon_thousands_sep); ! CurrentLocaleConv.negative_sign = db_encoding_strdup(encoding, extlconv->negative_sign); ! CurrentLocaleConv.positive_sign = db_encoding_strdup(encoding, extlconv->positive_sign); CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn; /* Try to restore internal settings */ *************** PGLC_localeconv(void) *** 449,454 **** --- 496,510 ---- pfree(save_lc_numeric); } + #ifdef WIN32 + /* try to restore internal ctype settings */ + if (save_lc_ctype) + { + setlocale(LC_CTYPE, save_lc_ctype); + pfree(save_lc_ctype); + } + #endif + CurrentLocaleConvValid = true; return &CurrentLocaleConv; }