diff -cpr HEAD/src/backend/utils/adt/selfuncs.c fix_strxfrm/src/backend/utils/adt/selfuncs.c
*** HEAD/src/backend/utils/adt/selfuncs.c	Mon Apr  9 09:26:35 2007
--- fix_strxfrm/src/backend/utils/adt/selfuncs.c	Mon Apr  9 18:11:56 2007
*************** convert_string_datum(Datum value, Oid ty
*** 3126,3131 ****
--- 3126,3188 ----
  		size_t		xfrmlen;
  		size_t		xfrmlen2;
  
+ #ifdef WIN32
+ 		/* Win32 does not have UTF-8, so we need to map to UTF-16 */
+ 		if (GetDatabaseEncoding() == PG_UTF8)
+ 		{
+ 			LPWSTR	wval;
+ 			LPWSTR	wxfrmstr;
+ 			size_t	len;
+ 
+ 			len = strlen(val);
+ 			if (len == 0)
+ 				return val;
+ 
+ 			/*
+ 			 * Convert UTF-8 to UTF-16
+ 			 */
+ 			wval = (LPWSTR) palloc((len + 1) * sizeof(WCHAR));
+ 			if (!MultiByteToWideChar(CP_UTF8, 0, val, -1, wval, len + 1))
+ 				ereport(ERROR,
+ 				 (errmsg("could not convert string to UTF-16: error %lu",
+ 						 GetLastError())));
+ 
+ 			/*
+ 			 * Perform locale-aware conversion
+ 			 *
+ 			 * There is a bug in the result value of wcsxfrm()
+ 			 * http://support.microsoft.com/kb/331014/
+ 			 * However, we can involuntary use the result to decide allocation
+ 			 * size because length in bytes are always longher than length
+ 			 * in wide characters. 
+ 			 */
+ 			xfrmlen = wcsxfrm(NULL, wval, 0);
+ 			if (xfrmlen >= INT_MAX)
+ 				ereport(ERROR,
+ 				 (errmsg("wcsxfrm(%s) failed: error %lu",
+ 						 val, GetLastError())));
+ 			wxfrmstr = (LPWSTR) palloc((xfrmlen + 1) * sizeof(WCHAR));
+ 			xfrmlen2 = wcsxfrm(wxfrmstr, wval, xfrmlen + 1);
+ 			Assert(xfrmlen2 <= xfrmlen);
+ 			pfree(wval);
+ 
+ 			/*
+ 			 * Re-convert UTF-16 to UTF-8
+ 			 * Do not use xfrmlen2 to avoid the above bug!
+ 			 */
+ 			len = wcslen(wxfrmstr) * pg_encoding_max_length(PG_UTF8) + 1;
+ 			pfree(val);
+ 			val = (char *) palloc(len);
+ 			if (!WideCharToMultiByte(CP_UTF8, 0, wxfrmstr, -1, val, len, NULL, NULL))
+ 				ereport(ERROR,
+ 				 (errmsg("could not convert string to UTF-8: error %lu",
+ 						 GetLastError())));
+ 
+ 			pfree(wxfrmstr);
+ 			return val;
+ 		}
+ #endif   /* WIN32 */
+ 
  		/*
  		 * Note: originally we guessed at a suitable output buffer size, and
  		 * only needed to call strxfrm twice if our guess was too small.
*************** convert_string_datum(Datum value, Oid ty
*** 3152,3157 ****
--- 3209,3217 ----
  #else
  		xfrmlen = strxfrm(NULL, val, 0);
  #endif
+ 		if (xfrmlen >= INT_MAX)
+ 			ereport(ERROR,
+ 			 (errmsg("strxfrm(%s) failed", val)));
  		xfrmstr = (char *) palloc(xfrmlen + 1);
  		xfrmlen2 = strxfrm(xfrmstr, val, xfrmlen + 1);
  		Assert(xfrmlen2 <= xfrmlen);
