diff -cprN head/src/backend/utils/error/elog.c work/src/backend/utils/error/elog.c
*** head/src/backend/utils/error/elog.c	2009-07-04 04:14:25.000000000 +0900
--- work/src/backend/utils/error/elog.c	2009-10-07 11:15:16.251326894 +0900
*************** static int	syslog_facility = LOG_LOCAL0;
*** 111,118 ****
  static void write_syslog(int level, const char *line);
  #endif
  
  #ifdef WIN32
! static void write_eventlog(int level, const char *line);
  #endif
  
  /* We provide a small stack of ErrorData records for re-entrant cases */
--- 111,120 ----
  static void write_syslog(int level, const char *line);
  #endif
  
+ static void write_console(const char *line, int len);
+ 
  #ifdef WIN32
! static void write_eventlog(int level, const char *line, int len);
  #endif
  
  /* We provide a small stack of ErrorData records for re-entrant cases */
*************** write_syslog(int level, const char *line
*** 1567,1576 ****
   * Write a message line to the windows event log
   */
  static void
! write_eventlog(int level, const char *line)
  {
! 	int			eventlevel = EVENTLOG_ERROR_TYPE;
! 	static HANDLE evtHandle = INVALID_HANDLE_VALUE;
  
  	if (evtHandle == INVALID_HANDLE_VALUE)
  	{
--- 1569,1579 ----
   * Write a message line to the windows event log
   */
  static void
! write_eventlog(int level, const char *line, int len)
  {
! 	WCHAR		   *utf16;
! 	int				eventlevel = EVENTLOG_ERROR_TYPE;
! 	static HANDLE	evtHandle = INVALID_HANDLE_VALUE;
  
  	if (evtHandle == INVALID_HANDLE_VALUE)
  	{
*************** write_eventlog(int level, const char *li
*** 1606,1613 ****
  			break;
  	}
  
  
! 	ReportEvent(evtHandle,
  				eventlevel,
  				0,
  				0,				/* All events are Id 0 */
--- 1609,1637 ----
  			break;
  	}
  
+ 	/*
+ 	 * Convert message to UTF16 text and write it with ReportEventW,
+ 	 * but fall-back into ReportEventA if conversion failed.
+ 	 */
+ 	if (errordata_stack_depth < ERRORDATA_STACK_SIZE - 1 &&
+ 		GetDatabaseEncoding() != GetPlatformEncoding() &&
+ 		(utf16 = pgwin32_toUTF16(line, len, NULL)) != NULL)
+ 	{
+ 		ReportEventW(evtHandle,
+ 				eventlevel,
+ 				0,
+ 				0,				/* All events are Id 0 */
+ 				NULL,
+ 				1,
+ 				0,
+ 				(LPCWSTR *) &utf16,
+ 				NULL);
  
! 		pfree(utf16);
! 	}
! 	else
! 	{
! 		ReportEventA(evtHandle,
  				eventlevel,
  				0,
  				0,				/* All events are Id 0 */
*************** write_eventlog(int level, const char *li
*** 1616,1624 ****
--- 1640,1690 ----
  				0,
  				&line,
  				NULL);
+ 	}
  }
+ 
  #endif   /* WIN32 */
  
+ static void
+ write_console(const char *line, int len)
+ {
+ #ifdef WIN32
+ 	if (errordata_stack_depth < ERRORDATA_STACK_SIZE - 1 &&
+ 		GetDatabaseEncoding() != GetPlatformEncoding())
+ 	{
+ 		static bool	redirected = false;
+ 		WCHAR	   *utf16;
+ 		int			utf16len;
+ 
+ 		if (!redirected &&
+ 			(utf16 = pgwin32_toUTF16(line, len, &utf16len)) != NULL)
+ 		{
+ 			HANDLE		stdHandle;
+ 			DWORD		written;
+ 
+ 			stdHandle = GetStdHandle(STD_ERROR_HANDLE);
+ 			if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
+ 			{
+ 				pfree(utf16);
+ 				return;
+ 			}
+ 
+ 			/* WriteConsoleW could fail if stderr is redirected. */
+ 			pfree(utf16);
+ 			redirected = true;
+ 		}
+ 	}
+ #else
+ 	/*
+ 	 * Conversion on non-win32 platform is not implemented yet.
+ 	 * It requires non-throw version of pg_do_encoding_conversion(),
+ 	 * that converts unconvertable characters to '?' without errors.
+ 	 */
+ #endif
+ 
+ 	write(fileno(stderr), line, len);
+ }
+ 
  /*
   * setup formatted_log_time, for consistent times between CSV and regular logs
   */
*************** send_message_to_server_log(ErrorData *ed
*** 2206,2212 ****
  	/* Write to eventlog, if enabled */
  	if (Log_destination & LOG_DESTINATION_EVENTLOG)
  	{
! 		write_eventlog(edata->elevel, buf.data);
  	}
  #endif   /* WIN32 */
  
--- 2272,2278 ----
  	/* Write to eventlog, if enabled */
  	if (Log_destination & LOG_DESTINATION_EVENTLOG)
  	{
! 		write_eventlog(edata->elevel, buf.data, buf.len);
  	}
  #endif   /* WIN32 */
  
*************** send_message_to_server_log(ErrorData *ed
*** 2230,2239 ****
  		 * because that's really a pipe to the syslogger process.
  		 */
  		else if (pgwin32_is_service())
! 			write_eventlog(edata->elevel, buf.data);
  #endif
  		else
! 			write(fileno(stderr), buf.data, buf.len);
  	}
  
  	/* If in the syslogger process, try to write messages direct to file */
--- 2296,2305 ----
  		 * because that's really a pipe to the syslogger process.
  		 */
  		else if (pgwin32_is_service())
! 			write_eventlog(edata->elevel, buf.data, buf.len);
  #endif
  		else
! 			write_console(buf.data, buf.len);
  	}
  
  	/* If in the syslogger process, try to write messages direct to file */
*************** send_message_to_server_log(ErrorData *ed
*** 2256,2267 ****
  		{
  			const char *msg = _("Not safe to send CSV data\n");
  
! 			write(fileno(stderr), msg, strlen(msg));
  			if (!(Log_destination & LOG_DESTINATION_STDERR) &&
  				whereToSendOutput != DestDebug)
  			{
  				/* write message to stderr unless we just sent it above */
! 				write(fileno(stderr), buf.data, buf.len);
  			}
  			pfree(buf.data);
  		}
--- 2322,2333 ----
  		{
  			const char *msg = _("Not safe to send CSV data\n");
  
! 			write_console(msg, strlen(msg));
  			if (!(Log_destination & LOG_DESTINATION_STDERR) &&
  				whereToSendOutput != DestDebug)
  			{
  				/* write message to stderr unless we just sent it above */
! 				write_console(buf.data, buf.len);
  			}
  			pfree(buf.data);
  		}
*************** void
*** 2642,2647 ****
--- 2708,2716 ----
  write_stderr(const char *fmt,...)
  {
  	va_list		ap;
+ #ifdef WIN32
+ 	char		errbuf[2048];		/* Arbitrary size? */
+ #endif
  
  	fmt = _(fmt);
  
*************** write_stderr(const char *fmt,...)
*** 2651,2656 ****
--- 2720,2726 ----
  	vfprintf(stderr, fmt, ap);
  	fflush(stderr);
  #else
+ 	vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
  
  	/*
  	 * On Win32, we print to stderr if running on a console, or write to
*************** write_stderr(const char *fmt,...)
*** 2658,2673 ****
  	 */
  	if (pgwin32_is_service())	/* Running as a service */
  	{
! 		char		errbuf[2048];		/* Arbitrary size? */
! 
! 		vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
! 
! 		write_eventlog(ERROR, errbuf);
  	}
  	else
  	{
  		/* Not running as service, write to stderr */
! 		vfprintf(stderr, fmt, ap);
  		fflush(stderr);
  	}
  #endif
--- 2728,2739 ----
  	 */
  	if (pgwin32_is_service())	/* Running as a service */
  	{
! 		write_eventlog(ERROR, errbuf, strlen(errbuf));
  	}
  	else
  	{
  		/* Not running as service, write to stderr */
! 		write_console(errbuf, strlen(errbuf));
  		fflush(stderr);
  	}
  #endif
diff -cprN head/src/backend/utils/mb/encnames.c work/src/backend/utils/mb/encnames.c
*** head/src/backend/utils/mb/encnames.c	2009-04-24 17:43:50.000000000 +0900
--- work/src/backend/utils/mb/encnames.c	2009-10-07 11:04:14.224280217 +0900
*************** sizeof(pg_encname_tbl) / sizeof(pg_encna
*** 303,432 ****
  pg_enc2name pg_enc2name_tbl[] =
  {
  	{
! 		"SQL_ASCII", PG_SQL_ASCII
  	},
  	{
! 		"EUC_JP", PG_EUC_JP
  	},
  	{
! 		"EUC_CN", PG_EUC_CN
  	},
  	{
! 		"EUC_KR", PG_EUC_KR
  	},
  	{
! 		"EUC_TW", PG_EUC_TW
  	},
  	{
! 		"EUC_JIS_2004", PG_EUC_JIS_2004
  	},
  	{
! 		"UTF8", PG_UTF8
  	},
  	{
! 		"MULE_INTERNAL", PG_MULE_INTERNAL
  	},
  	{
! 		"LATIN1", PG_LATIN1
  	},
  	{
! 		"LATIN2", PG_LATIN2
  	},
  	{
! 		"LATIN3", PG_LATIN3
  	},
  	{
! 		"LATIN4", PG_LATIN4
  	},
  	{
! 		"LATIN5", PG_LATIN5
  	},
  	{
! 		"LATIN6", PG_LATIN6
  	},
  	{
! 		"LATIN7", PG_LATIN7
  	},
  	{
! 		"LATIN8", PG_LATIN8
  	},
  	{
! 		"LATIN9", PG_LATIN9
  	},
  	{
! 		"LATIN10", PG_LATIN10
  	},
  	{
! 		"WIN1256", PG_WIN1256
  	},
  	{
! 		"WIN1258", PG_WIN1258
  	},
  	{
! 		"WIN866", PG_WIN866
  	},
  	{
! 		"WIN874", PG_WIN874
  	},
  	{
! 		"KOI8R", PG_KOI8R
  	},
  	{
! 		"WIN1251", PG_WIN1251
  	},
  	{
! 		"WIN1252", PG_WIN1252
  	},
  	{
! 		"ISO_8859_5", PG_ISO_8859_5
  	},
  	{
! 		"ISO_8859_6", PG_ISO_8859_6
  	},
  	{
! 		"ISO_8859_7", PG_ISO_8859_7
  	},
  	{
! 		"ISO_8859_8", PG_ISO_8859_8
  	},
  	{
! 		"WIN1250", PG_WIN1250
  	},
  	{
! 		"WIN1253", PG_WIN1253
  	},
  	{
! 		"WIN1254", PG_WIN1254
  	},
  	{
! 		"WIN1255", PG_WIN1255
  	},
  	{
! 		"WIN1257", PG_WIN1257
  	},
  	{
! 		"KOI8U", PG_KOI8U
  	},
  	{
! 		"SJIS", PG_SJIS
  	},
  	{
! 		"BIG5", PG_BIG5
  	},
  	{
! 		"GBK", PG_GBK
  	},
  	{
! 		"UHC", PG_UHC
  	},
  	{
! 		"GB18030", PG_GB18030
  	},
  	{
! 		"JOHAB", PG_JOHAB
  	},
  	{
! 		"SHIFT_JIS_2004", PG_SHIFT_JIS_2004
  	}
  };
  
--- 303,432 ----
  pg_enc2name pg_enc2name_tbl[] =
  {
  	{
! 		"SQL_ASCII", PG_SQL_ASCII, 0
  	},
  	{
! 		"EUC_JP", PG_EUC_JP, 20932
  	},
  	{
! 		"EUC_CN", PG_EUC_CN, 20936
  	},
  	{
! 		"EUC_KR", PG_EUC_KR, 51949
  	},
  	{
! 		"EUC_TW", PG_EUC_TW, 0
  	},
  	{
! 		"EUC_JIS_2004", PG_EUC_JIS_2004, 20932
  	},
  	{
! 		"UTF8", PG_UTF8, 65001
  	},
  	{
! 		"MULE_INTERNAL", PG_MULE_INTERNAL, 0
  	},
  	{
! 		"LATIN1", PG_LATIN1, 28591
  	},
  	{
! 		"LATIN2", PG_LATIN2, 28592
  	},
  	{
! 		"LATIN3", PG_LATIN3, 28593
  	},
  	{
! 		"LATIN4", PG_LATIN4, 28594
  	},
  	{
! 		"LATIN5", PG_LATIN5, 28599
  	},
  	{
! 		"LATIN6", PG_LATIN6, 0
  	},
  	{
! 		"LATIN7", PG_LATIN7, 0
  	},
  	{
! 		"LATIN8", PG_LATIN8, 0
  	},
  	{
! 		"LATIN9", PG_LATIN9, 28605
  	},
  	{
! 		"LATIN10", PG_LATIN10, 0
  	},
  	{
! 		"WIN1256", PG_WIN1256, 1256
  	},
  	{
! 		"WIN1258", PG_WIN1258, 1258
  	},
  	{
! 		"WIN866", PG_WIN866, 866
  	},
  	{
! 		"WIN874", PG_WIN874, 874
  	},
  	{
! 		"KOI8R", PG_KOI8R, 20866
  	},
  	{
! 		"WIN1251", PG_WIN1251, 1251
  	},
  	{
! 		"WIN1252", PG_WIN1252, 1252
  	},
  	{
! 		"ISO_8859_5", PG_ISO_8859_5, 28595
  	},
  	{
! 		"ISO_8859_6", PG_ISO_8859_6, 28596
  	},
  	{
! 		"ISO_8859_7", PG_ISO_8859_7, 28597
  	},
  	{
! 		"ISO_8859_8", PG_ISO_8859_8, 28598
  	},
  	{
! 		"WIN1250", PG_WIN1250, 1250
  	},
  	{
! 		"WIN1253", PG_WIN1253, 1253
  	},
  	{
! 		"WIN1254", PG_WIN1254, 1254
  	},
  	{
! 		"WIN1255", PG_WIN1255, 1255
  	},
  	{
! 		"WIN1257", PG_WIN1257, 1257
  	},
  	{
! 		"KOI8U", PG_KOI8U, 21866
  	},
  	{
! 		"SJIS", PG_SJIS, 932
  	},
  	{
! 		"BIG5", PG_BIG5, 950
  	},
  	{
! 		"GBK", PG_GBK, 936
  	},
  	{
! 		"UHC", PG_UHC, 0
  	},
  	{
! 		"GB18030", PG_GB18030, 54936
  	},
  	{
! 		"JOHAB", PG_JOHAB, 0
  	},
  	{
! 		"SHIFT_JIS_2004", PG_SHIFT_JIS_2004, 932
  	}
  };
  
diff -cprN head/src/backend/utils/mb/mbutils.c work/src/backend/utils/mb/mbutils.c
*** head/src/backend/utils/mb/mbutils.c	2009-07-08 04:28:56.000000000 +0900
--- work/src/backend/utils/mb/mbutils.c	2009-10-07 11:04:14.224280217 +0900
*************** static FmgrInfo *ToClientConvProc = NULL
*** 58,63 ****
--- 58,64 ----
   */
  static pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
  static pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
+ static pg_enc2name *PlatformEncoding = NULL;
  
  /*
   * During backend startup we can't set client encoding because we (a)
*************** pg_client_encoding(PG_FUNCTION_ARGS)
*** 978,980 ****
--- 979,1041 ----
  	Assert(ClientEncoding);
  	return DirectFunctionCall1(namein, CStringGetDatum(ClientEncoding->name));
  }
+ 
+ int
+ GetPlatformEncoding(void)
+ {
+ 	if (PlatformEncoding == NULL)
+ 		PlatformEncoding = &pg_enc2name_tbl[pg_get_encoding_from_locale("")];
+ 	return PlatformEncoding->encoding;
+ }
+ 
+ #ifdef WIN32
+ 
+ /*
+  * Result is palloc'ed null-terminated utf16 string. The character length
+  * is also passed to utf16len if not null. Returns NULL iff failed.
+  */
+ WCHAR *
+ pgwin32_toUTF16(const char *str, int len, int *utf16len)
+ {
+ 	WCHAR	   *utf16;
+ 	int			dstlen;
+ 	UINT		codepage;
+ 
+ 	codepage = pg_enc2name_tbl[GetDatabaseEncoding()].codepage;
+ 
+ 	/*
+ 	 * Use MultiByteToWideChar directly if there is a corresponding codepage,
+ 	 * or double conversion through UTF8.
+ 	 */
+ 	if (codepage != 0)
+ 	{
+ 		utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
+ 		dstlen = MultiByteToWideChar(codepage, 0, str, len, utf16, len);
+ 		utf16[dstlen] = L'\0';
+ 	}
+ 	else
+ 	{
+ 		char	   *utf8;
+ 
+ 		utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
+ 										len, GetDatabaseEncoding(), PG_UTF8);
+ 		if (utf8 != str)
+ 			len = strlen(utf8);
+ 
+ 		utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
+ 		dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len);
+ 		utf16[dstlen] = L'\0';
+ 
+ 		if (utf8 != str)
+ 			pfree(utf8);
+ 	}
+ 
+ 	if (dstlen == 0 && len > 0)
+ 		return NULL;	/* error */
+ 
+ 	if (utf16len)
+ 		*utf16len = len;
+ 	return utf16;
+ }
+ 
+ #endif
diff -cprN head/src/include/mb/pg_wchar.h work/src/include/mb/pg_wchar.h
*** head/src/include/mb/pg_wchar.h	2009-06-11 23:49:11.000000000 +0900
--- work/src/include/mb/pg_wchar.h	2009-10-07 11:04:14.225327260 +0900
*************** typedef struct pg_enc2name
*** 257,262 ****
--- 257,263 ----
  {
  	char	   *name;
  	pg_enc		encoding;
+ 	unsigned	codepage;	/* codepage for WIN32 */
  } pg_enc2name;
  
  extern pg_enc2name pg_enc2name_tbl[];
*************** extern const char *pg_get_client_encodin
*** 402,407 ****
--- 403,409 ----
  extern void SetDatabaseEncoding(int encoding);
  extern int	GetDatabaseEncoding(void);
  extern const char *GetDatabaseEncodingName(void);
+ extern int	GetPlatformEncoding(void);
  extern void pg_bind_textdomain_codeset(const char *domainname);
  
  extern int	pg_valid_client_encoding(const char *name);
*************** extern void mic2latin_with_table(const u
*** 458,461 ****
--- 460,467 ----
  
  extern bool pg_utf8_islegal(const unsigned char *source, int length);
  
+ #ifdef WIN32
+ extern WCHAR *pgwin32_toUTF16(const char *str, int len, int *utf16len);
+ #endif
+ 
  #endif   /* PG_WCHAR_H */
