Hello,

I am sorry for preview chotic mails. My web email client is stupid (I am too).

This patch correct bug, when localized day or month names was incorectly trnasformed to lower or upper string.

Regards
Pavel Stehule

_________________________________________________________________
Najdete si svou lasku a nove pratele na Match.com. http://www.msn.cz/
*** ./adt/formatting.c.orig	2007-02-04 13:09:09.000000000 +0100
--- ./adt/formatting.c	2007-02-04 15:58:52.000000000 +0100
***************
*** 82,87 ****
--- 82,88 ----
  #include "utils/int8.h"
  #include "utils/numeric.h"
  #include "utils/pg_locale.h"
+ #include "mb/pg_wchar.h"
  
  #define _(x)	gettext((x))
  
***************
*** 113,118 ****
--- 114,128 ----
  #define MAXFLOATWIDTH	64
  #define MAXDOUBLEWIDTH	128
  
+ /*
+  * External (defined in oracle_compat.c 
+  */
+ #if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
+ #define USE_WIDE_UPPER_LOWER
+ extern int upper_str(char *str);
+ extern int lower_str(char *str);
+ #endif
+ 
  /* ----------
   * External (defined in PgSQL datetime.c (timestamp utils))
   * ----------
***************
*** 946,951 ****
--- 956,970 ----
  static char *localize_day_full(int index);
  static char *localize_day(int index);
  
+ #ifdef USE_WIDE_UPPER_LOWER
+ static char *localized_str_toupper(char *buff);
+ static char *localized_str_tolower(char *buff);
+ #else
+ #define localized_str_toupper str_toupper
+ #define localized_str_tolower str_tolower
+ #endif /* USE_WIDE_UPPER_LOWER */
+ 
+ 
  /* ----------
   * Fast sequential search, use index for data selection which
   * go to seq. cycle (it is very fast for unwanted strings)
***************
*** 1500,1505 ****
--- 1519,1525 ----
  		*p_buff = pg_toupper((unsigned char) *p_buff);
  		++p_buff;
  	}
+ 
  	return buff;
  }
  
***************
*** 1523,1528 ****
--- 1543,1603 ----
  	return buff;
  }
  
+ 
+ #ifdef USE_WIDE_UPPER_LOWER
+ /* ----------
+  * Convert localized string to upper string. Input string is modified in place.
+  * ----------
+  */
+ static char *
+ localized_str_toupper(char *buff)
+ {
+ 	if (!buff)
+ 		return NULL;
+ 
+ 	if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
+ 		upper_str(buff);
+ 	else
+ 	{
+ 		char	   *p_buff = buff;
+ 
+ 		while (*p_buff)
+ 		{
+ 			*p_buff = pg_toupper((unsigned char) *p_buff);
+ 			++p_buff;
+ 		}
+ 	}
+ 
+ 	return buff;
+ }
+ 
+ /* ----------
+  * Convert localized string to upper string. Input string is modified in place.
+  * ----------
+  */
+ static char *
+ localized_str_tolower(char *buff)
+ {
+ 	if (!buff)
+ 		return NULL;
+ 
+ 	if (pg_database_encoding_max_length() > 1 && !lc_ctype_is_c())
+ 		lower_str(buff);
+ 	else
+ 	{
+ 		char	   *p_buff = buff;
+ 
+ 		while (*p_buff)
+ 		{
+ 			*p_buff = pg_toupper((unsigned char) *p_buff);
+ 			++p_buff;
+ 		}
+ 	}
+ 
+ 	return buff;
+ }
+ #endif /* USE_WIDE_UPPER_LOWER */
+ 
  /* ----------
   * Sequential search with to upper/lower conversion
   * ----------
***************
*** 2188,2197 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
  			else
  				strcpy(workbuff, months_full[tm->tm_mon - 1]);
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
  			return strlen(p_inout);
  
  		case DCH_Month:
--- 2263,2278 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
+ 				localized_str_toupper(workbuff);
+ 			}
  			else
+ 			{
  				strcpy(workbuff, months_full[tm->tm_mon - 1]);
! 				str_toupper(workbuff);
! 			}
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, workbuff);
  			return strlen(p_inout);
  
  		case DCH_Month:
***************
*** 2209,2218 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_month_full(tm->tm_mon - 1));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_MON:
--- 2290,2305 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
! 			{
! 				strcpy(workbuff, localize_month_full(tm->tm_mon - 1));
! 				localized_str_tolower(workbuff);
! 				sprintf(inout, "%*s", 0, workbuff);
! 			}
  			else
+ 			{
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, months_full[tm->tm_mon - 1]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_MON:
***************
*** 2220,2229 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(inout, localize_month(tm->tm_mon - 1));
  			else
  				strcpy(inout, months[tm->tm_mon - 1]);
! 			str_toupper(inout);
  			return strlen(p_inout);
  
  		case DCH_Mon:
--- 2307,2321 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_month(tm->tm_mon - 1));
+ 				localized_str_toupper(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, months[tm->tm_mon - 1]);
! 				str_toupper(inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_Mon:
***************
*** 2241,2250 ****
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
  				strcpy(inout, localize_month(tm->tm_mon - 1));
  			else
  				strcpy(inout, months[tm->tm_mon - 1]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_MM:
--- 2333,2347 ----
  			if (!tm->tm_mon)
  				return -1;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_month(tm->tm_mon - 1));
+ 				localized_str_tolower(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, months[tm->tm_mon - 1]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_MM:
***************
*** 2272,2287 ****
  		case DCH_DAY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(workbuff, localize_day_full(tm->tm_wday));
  			else
  				strcpy(workbuff, days[tm->tm_wday]);
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, str_toupper(workbuff));
  			return strlen(p_inout);
  
  		case DCH_Day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
  			return strlen(p_inout);
--- 2369,2390 ----
  		case DCH_DAY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(workbuff, localize_day_full(tm->tm_wday));
+ 				localized_str_toupper(workbuff);
+ 			}
  			else
+ 			{
  				strcpy(workbuff, days[tm->tm_wday]);
! 				str_toupper(workbuff);
! 			}
! 			sprintf(inout, "%*s", (S_FM(suf) || S_TM(suf)) ? 0 : -9, workbuff);
  			return strlen(p_inout);
  
  		case DCH_Day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));		    
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
  			return strlen(p_inout);
***************
*** 2289,2307 ****
  		case DCH_day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 				sprintf(inout, "%*s", 0, localize_day_full(tm->tm_wday));
  			else
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_DY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(inout, localize_day(tm->tm_wday));
  			else
  				strcpy(inout, days_short[tm->tm_wday]);
! 			str_toupper(inout);
  			return strlen(p_inout);
  
  		case DCH_Dy:
--- 2392,2423 ----
  		case DCH_day:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
! 			{
! 				strcpy(workbuff, localize_day_full(tm->tm_wday));
! 				localized_str_tolower(workbuff);
! 				sprintf(inout, "%*s", 0, workbuff);
! 				
! 			}
  			else
+ 			{
  				sprintf(inout, "%*s", S_FM(suf) ? 0 : -9, days[tm->tm_wday]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_DY:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_day(tm->tm_wday));
+ 				localized_str_toupper(inout);
+ 			}
  			else
+ 			{
  				strcpy(inout, days_short[tm->tm_wday]);
! 				str_toupper(inout);
! 			}
! 			
  			return strlen(p_inout);
  
  		case DCH_Dy:
***************
*** 2315,2324 ****
  		case DCH_dy:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
  				strcpy(inout, localize_day(tm->tm_wday));
  			else
  				strcpy(inout, days_short[tm->tm_wday]);
! 			*inout = pg_tolower((unsigned char) *inout);
  			return strlen(p_inout);
  
  		case DCH_DDD:
--- 2431,2446 ----
  		case DCH_dy:
  			INVALID_FOR_INTERVAL;
  			if (S_TM(suf))
+ 			{
  				strcpy(inout, localize_day(tm->tm_wday));
+ 				localized_str_tolower(inout);
+ 				
+ 			}
  			else
+ 			{
  				strcpy(inout, days_short[tm->tm_wday]);
! 				*inout = pg_tolower((unsigned char) *inout);
! 			}
  			return strlen(p_inout);
  
  		case DCH_DDD:
*** ./adt/oracle_compat.c.orig	2007-02-04 12:35:14.000000000 +0100
--- ./adt/oracle_compat.c	2007-02-04 16:06:18.000000000 +0100
***************
*** 46,51 ****
--- 46,53 ----
   */
  #if defined(HAVE_WCSTOMBS) && defined(HAVE_TOWLOWER)
  #define USE_WIDE_UPPER_LOWER
+ int upper_str(char *str);
+ int lower_str(char *str);
  #endif
  
  static text *dotrim(const char *string, int stringlen,
***************
*** 258,263 ****
--- 260,333 ----
  #define wcstotext	win32_wcstotext
  #endif   /* WIN32 */
  
+ #ifdef USE_WIDE_UPPER_LOWER
+ /* 
+  * upper_text is used for correct multibyte upper function str_toupper.
+  * Expected safety long buffer (used only for internal purpouse). 
+  * Returns length of converted string. lower_str is similar.
+  */
+ int
+ upper_str(char *str)
+ {
+ 	wchar_t	  *workspace;
+ 	text 	  *txt;
+ 	text	  *result;
+ 	int 		nbytes = strlen(str);
+ 	int	   	i;
+ 	
+ 	txt = palloc(nbytes + VARHDRSZ);
+ 	memcpy(VARDATA(txt), str, nbytes);
+ 	VARATT_SIZEP(txt) = nbytes + VARHDRSZ;
+ 
+ 	workspace = texttowcs(txt);
+ 
+ 	for (i = 0; workspace[i] != 0; i++)
+ 		workspace[i] = towupper(workspace[i]);
+ 
+ 	result = wcstotext(workspace, i);
+ 
+ 	/* copy back result */	
+ 	nbytes = VARSIZE(result) - VARHDRSZ;
+ 	memcpy(str, VARDATA(result), nbytes);
+ 	str[nbytes] = '\0';
+ 
+ 	pfree(workspace);
+ 	pfree(result);
+ 	
+ 	return nbytes;
+ }
+ 
+ int
+ lower_str(char *str)
+ {
+ 	wchar_t	  *workspace;
+ 	text 	  *txt;
+ 	text	  *result;
+ 	int 		nbytes = strlen(str);
+ 	int	   	i;
+ 	
+ 	txt = palloc(nbytes + VARHDRSZ);
+ 	memcpy(VARDATA(txt), str, nbytes);
+ 	VARATT_SIZEP(txt) = nbytes + VARHDRSZ;
+ 
+ 	workspace = texttowcs(txt);
+ 
+ 	for (i = 0; workspace[i] != 0; i++)
+ 		workspace[i] = towlower(workspace[i]);
+ 
+ 	result = wcstotext(workspace, i);
+ 
+ 	/* copy back result */	
+ 	nbytes = VARSIZE(result) - VARHDRSZ;
+ 	memcpy(str, VARDATA(result), nbytes);
+ 	str[nbytes] = '\0';
+ 
+ 	pfree(workspace);
+ 	pfree(result);
+ 	
+ 	return nbytes;
+ }
+ #endif	/* USE_WIDE_UPPER_LOWER */
  
  /********************************************************************
   *

---------------------------(end of broadcast)---------------------------
TIP 6: explain analyze is your friend

Reply via email to