1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-29 23:43:17 +03:00

Make LC_COLLATE and LC_CTYPE database-level settings. Collation and

ctype are now more like encoding, stored in new datcollate and datctype
columns in pg_database.

This is a stripped-down version of Radek Strnad's patch, with further
changes by me.
This commit is contained in:
Heikki Linnakangas
2008-09-23 09:20:39 +00:00
parent c52aab5525
commit 61d9674988
30 changed files with 440 additions and 248 deletions

View File

@@ -4,7 +4,7 @@
*
* Portions Copyright (c) 2002-2008, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.41 2008/05/19 18:08:16 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/pg_locale.c,v 1.42 2008/09/23 09:20:36 heikki Exp $
*
*-----------------------------------------------------------------------
*/
@@ -76,7 +76,7 @@ static bool CurrentLCTimeValid = false;
/* Environment variable storage area */
#define LC_ENV_BUFSIZE (LOCALE_NAME_BUFLEN + 20)
#define LC_ENV_BUFSIZE (NAMEDATALEN + 20)
static char lc_collate_envbuf[LC_ENV_BUFSIZE];
static char lc_ctype_envbuf[LC_ENV_BUFSIZE];
@@ -189,6 +189,31 @@ pg_perm_setlocale(int category, const char *locale)
}
/*
* Is the locale name valid for the locale category?
*/
bool
check_locale(int category, const char *value)
{
char *save;
bool ret;
save = setlocale(category, NULL);
if (!save)
return false; /* won't happen, we hope */
/* save may be pointing at a modifiable scratch variable, see above */
save = pstrdup(save);
/* set the locale with setlocale, to see if it accepts it. */
ret = (setlocale(category, value) != NULL);
setlocale(category, save); /* assume this won't fail */
pfree(save);
return ret;
}
/* GUC assign hooks */
/*
@@ -203,21 +228,9 @@ pg_perm_setlocale(int category, const char *locale)
static const char *
locale_xxx_assign(int category, const char *value, bool doit, GucSource source)
{
char *save;
save = setlocale(category, NULL);
if (!save)
return NULL; /* won't happen, we hope */
/* save may be pointing at a modifiable scratch variable, see above */
save = pstrdup(save);
if (!setlocale(category, value))
if (!check_locale(category, value))
value = NULL; /* set failure return marker */
setlocale(category, save); /* assume this won't fail */
pfree(save);
/* need to reload cache next time? */
if (doit && value != NULL)
{

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.185 2008/09/11 14:01:09 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/postinit.c,v 1.186 2008/09/23 09:20:36 heikki Exp $
*
*
*-------------------------------------------------------------------------
@@ -159,6 +159,8 @@ CheckMyDatabase(const char *name, bool am_superuser)
{
HeapTuple tup;
Form_pg_database dbform;
char *collate;
char *ctype;
/* Fetch our real pg_database row */
tup = SearchSysCache(DATABASEOID,
@@ -240,6 +242,28 @@ CheckMyDatabase(const char *name, bool am_superuser)
/* If we have no other source of client_encoding, use server encoding */
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
PGC_BACKEND, PGC_S_DEFAULT);
/* assign locale variables */
collate = NameStr(dbform->datcollate);
ctype = NameStr(dbform->datctype);
if (setlocale(LC_COLLATE, collate) == NULL)
ereport(FATAL,
(errmsg("database locale is incompatible with operating system"),
errdetail("The database was initialized with LC_COLLATE \"%s\", "
" which is not recognized by setlocale().", collate),
errhint("Recreate the database with another locale or install the missing locale.")));
if (setlocale(LC_CTYPE, ctype) == NULL)
ereport(FATAL,
(errmsg("database locale is incompatible with operating system"),
errdetail("The database was initialized with LC_CTYPE \"%s\", "
" which is not recognized by setlocale().", ctype),
errhint("Recreate the database with another locale or install the missing locale.")));
/* Make the locale settings visible as GUC variables, too */
SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
/*
* Lastly, set up any database-specific configuration variables.