On Tue, Sep 25, 2012 at 08:41:19AM +0800, Rural Hunter wrote:
> >>I think the problem is on the options when I installed pgsql(both
> >>9.1 and 9.2)
> >>Select the locale to be used by the new database cluster.
> >>
> >>Locale
> >>
> >>[1] [Default locale]
> >>[2] C
> >>[3] POSIX
> >>[4] zh_CN.utf8
> >>[5] zh_HK.utf8
> >>[6] zh_SG.utf8
> >>[7] zh_TW.utf8
> >>Please choose an option [1] : 4
> >>I chose 4 instead of 1. I guess the default locale(option 1) is with dash.
> >Well, if you run that query on template0 in the old and new cluster, you
> >will see something different in the two of them.  Could you have used
> >default in one and a non-dash in the other.
> Yes, that's true. The upgrade is fine with both fresh installs(9.1
> and 9.2) with option above(without-dash). The problem only happens
> when I inited the 9.2 db with default locale(I guess that one has

OK, that is good to know.  I developed the attached C program that does
the setlocale canonical test.  On Debian Squeeze, I could not see any
change:  if I pass en_US.UTF-8, I get en_US.UTF-8 returned;  if I pass
en_US.UTF8, I get en_US.UTF8 returned.  Can anyone test this and find a
case where the local is canonicalized?  Run it this way:

        $ canonical
        LC_COLLATE = 3
        LC_CTYPE = 0
        $ canonical 0 en_US.UTF8
        en_US.UTF8

We are looking for cases where the second argument produces a
non-matching locale name as output.

I have also attached a patch that reports the mismatching locale or
encoding names --- this should at least help with debugging and show
that a dash is the problem.

> the dash). Just wondering why pg installer provides options without
> dash.

No idea.

-- 
  Bruce Momjian  <br...@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
#include <stdio.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>

int
main(int argc, char **argv)
{
	char	   *save;
	char	   *res;
	int 		category;

	if (argc == 1)
	{
		printf("LC_COLLATE = %d\n", LC_COLLATE);
		printf("LC_CTYPE = %d\n", LC_CTYPE);
		return 0;
	}
	
	category = atoi(argv[1]);
	
	save = setlocale(category, NULL);
	if (!save)
	{
		printf("failed to get the current locale\n");
		return 0;
	}

	/* 'save' may be pointing at a modifiable scratch variable, so copy it. */
	save = strdup(save);

	/* set the locale with setlocale, to see if it accepts it. */
	res = setlocale(category, argv[2]);

	if (!res)
	{
		printf("failed to get system local name for \"%s\"\n", res);
		return 0;
	}

	res = strdup(res);

	/* restore old value. */
	if (!setlocale(category, save))
	{
		printf("failed to restore old locale \"%s\"\n", save);
		return 0;
	}
		
	free(save);

	puts(res);
	return 0;
}
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
new file mode 100644
index beb177d..e4fec34
*** a/contrib/pg_upgrade/check.c
--- b/contrib/pg_upgrade/check.c
*************** static void
*** 406,421 ****
  check_locale_and_encoding(ControlData *oldctrl,
  						  ControlData *newctrl)
  {
! 	/* These are often defined with inconsistent case, so use pg_strcasecmp(). */
  	if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster lc_collate values do not match\n");
  	if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster lc_ctype values do not match\n");
  	if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
  		pg_log(PG_FATAL,
! 			   "old and new cluster encoding values do not match\n");
  }
  
  
--- 406,428 ----
  check_locale_and_encoding(ControlData *oldctrl,
  						  ControlData *newctrl)
  {
! 	/*
! 	 *	These are often defined with inconsistent case, so use pg_strcasecmp().
! 	 *	They also often use inconsistent hyphenation, which we cannot fix, e.g.
! 	 *	UTF-8 vs. UTF8, so at least we display the mismatching values.
! 	 */
  	if (pg_strcasecmp(oldctrl->lc_collate, newctrl->lc_collate) != 0)
  		pg_log(PG_FATAL,
! 			   "lc_collate cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->lc_collate, newctrl->lc_collate);
  	if (pg_strcasecmp(oldctrl->lc_ctype, newctrl->lc_ctype) != 0)
  		pg_log(PG_FATAL,
! 			   "lc_ctype cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->lc_ctype, newctrl->lc_ctype);
  	if (pg_strcasecmp(oldctrl->encoding, newctrl->encoding) != 0)
  		pg_log(PG_FATAL,
! 			   "encoding cluster values do not match:  old \"%s\", new \"%s\"\n",
! 			   oldctrl->encoding, newctrl->encoding);
  }
  
  
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to