diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c
index 79dece9..e172edf 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,426 ----
  	struct lconv *extlconv;
  	char	   *save_lc_monetary;
  	char	   *save_lc_numeric;
+ 	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 */
--- 436,472 ----
  	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);
+ 
+ 	setlocale(LC_CTYPE, locale_monetary);
+ #endif
+ 
  	setlocale(LC_MONETARY, locale_monetary);
  	setlocale(LC_NUMERIC, locale_numeric);
  
  	/* Get formatting information */
  	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.currency_symbol = db_encoding_strdup(encoding, extlconv->currency_symbol);
! 	CurrentLocaleConv.decimal_point = db_encoding_strdup(encoding, extlconv->decimal_point);
! 	CurrentLocaleConv.grouping = db_encoding_strdup(encoding, extlconv->grouping);
! 	CurrentLocaleConv.thousands_sep = db_encoding_strdup(encoding, extlconv->thousands_sep);
! 	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 ****
--- 482,496 ----
  		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;
  }
