Search Postgresql Archives

Re: trouble with to_char('L')

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Where are we on this issue?

---------------------------------------------------------------------------

Hiroshi Inoue wrote:
> Tom Lane wrote:
> > Alvaro Herrera <alvherre@xxxxxxxxxxxxxxxxx> writes:
> >> Does this imply that we shouldn't allow UTF8 database on Windows at all?
> > 
> > That would be pretty unfortunate :-(
> > 
> > I think what this suggests is that there probably needs to be some
> > encoding conversion logic near the places we examine localeconv()
> > output.
> 
> Attached is a patch to the current CVS.
> It uses a similar way like LC_TIME stuff does.
> 
> regards,
> Hiroshi Inoue

> Index: pg_locale.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
> retrieving revision 1.49
> diff -c -c -r1.49 pg_locale.c
> *** pg_locale.c	1 Apr 2009 09:17:32 -0000	1.49
> --- pg_locale.c	22 Apr 2009 21:08:33 -0000
> ***************
> *** 386,391 ****
> --- 386,449 ----
>   		free(s->positive_sign);
>   }
>   
> + #ifdef	WIN32
> + #define	MAX_BYTES_PER_CHARACTER	4
> + static char *dbstr_win32(bool matchenc, const char *str)
> + {
> + 	int	encoding = GetDatabaseEncoding();
> + 	bool	is_ascii = true;
> + 	size_t	len, ilen, wclen, dstlen;
> + 	wchar_t	*wbuf;
> + 	char	*dst, *ibuf;
> + 
> + 	if (matchenc)
> + 		return strdup(str);
> + 	/* Is the str an ascii string ? */
> + 	for (ibuf = str; *ibuf; ibuf++)
> + 	{
> + 		if (!isascii(*ibuf))
> + 		{
> + 			is_ascii = false;
> + 			break;
> + 		}
> + 	}
> + 	/* Simply returns the strdup()ed ascii string */
> + 	if (is_ascii)
> + 		return strdup(str);
> + 
> + 	ilen = strlen(str) + 1;
> + 	wclen = ilen * sizeof(wchar_t);
> + 	wbuf = (wchar_t *) palloc(wclen);
> + 	len = mbstowcs(wbuf, str, ilen);
> + 	if (len == -1)
> + 		elog(ERROR,
> + 			"could not convert string to Wide characters:error %lu", GetLastError());
> + 
> + 	dstlen = len * MAX_BYTES_PER_CHARACTER + 1;
> + 	dst = malloc(dstlen);
> +   
> + 	len = WideCharToMultiByte(CP_UTF8, 0, wbuf, len, dst, dstlen, NULL, NULL);
> + 	pfree(wbuf);
> + 	if (len == 0)
> + 		elog(ERROR,
> + 			"could not convert string to UTF-8:error %lu", GetLastError());
> + 
> + 	dst[len] = '\0';
> + 	if (encoding != PG_UTF8)
> + 	{
> + 		char *convstr = pg_do_encoding_conversion(dst, len, PG_UTF8, encoding);
> + 		if (dst != convstr)
> + 		{
> + 			strlcpy(dst, convstr, dstlen);
> + 			pfree(convstr);
> + 		}
> + 	}
> + 
> + 	return dst;
> + }
> + 
> + #define	strdup(str)	dbstr_win32(is_encoding_match, str)
> + #endif /* WIN32 */
>   
>   /*
>    * Return the POSIX lconv struct (contains number/money formatting
> ***************
> *** 398,403 ****
> --- 456,466 ----
>   	struct lconv *extlconv;
>   	char	   *save_lc_monetary;
>   	char	   *save_lc_numeric;
> + #ifdef	WIN32
> + 	char	   *save_lc_ctype = NULL;
> + 	bool	lc_ctype_change = false, is_encoding_match;
> + #endif /* WIN32 */
> + 
>   
>   	/* Did we do it already? */
>   	if (CurrentLocaleConvValid)
> ***************
> *** 413,418 ****
> --- 476,492 ----
>   	if (save_lc_numeric)
>   		save_lc_numeric = pstrdup(save_lc_numeric);
>   
> + #ifdef	WIN32
> + 	save_lc_ctype = setlocale(LC_CTYPE, NULL);
> + 	if (save_lc_ctype && stricmp(locale_monetary, save_lc_ctype) != 0)
> + 	{
> + 		lc_ctype_change = true;
> + 		save_lc_ctype = pstrdup(save_lc_ctype);
> + 		setlocale(LC_CTYPE, locale_monetary);
> + 	}
> + 	is_encoding_match = (pg_get_encoding_from_locale(locale_monetary) == GetDatabaseEncoding());
> + #endif
> + 
>   	setlocale(LC_MONETARY, locale_monetary);
>   	setlocale(LC_NUMERIC, locale_numeric);
>   
> ***************
> *** 437,442 ****
> --- 511,524 ----
>   	CurrentLocaleConv.n_sign_posn = extlconv->n_sign_posn;
>   
>   	/* Try to restore internal settings */
> + #ifdef	WIN32
> + #undef	strdup
> + 	if (lc_ctype_change)
> + 	{
> + 		setlocale(LC_CTYPE, save_lc_ctype);
> + 		pfree(save_lc_ctype);
> + 	}
> + #endif /* WIN32 */
>   	if (save_lc_monetary)
>   	{
>   		setlocale(LC_MONETARY, save_lc_monetary);
> 
> 
> -- 
> Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general

-- 
  Bruce Momjian  <bruce@xxxxxxxxxx>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com
  PG East:  http://www.enterprisedb.com/community/nav-pg-east-2010.do
  + If your life is a hard drive, Christ can be your backup. +

-- 
Sent via pgsql-general mailing list (pgsql-general@xxxxxxxxxxxxxx)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Postgresql Jobs]     [Postgresql Admin]     [Postgresql Performance]     [Linux Clusters]     [PHP Home]     [PHP on Windows]     [Kernel Newbies]     [PHP Classes]     [PHP Books]     [PHP Databases]     [Postgresql & PHP]     [Yosemite]
  Powered by Linux