Hi,

this patch allow to use database locale settings. It remove cluster locale settings, and append LCCTYPE and
LCCOLLATE items to CREATE DATABASE syntax.


Any considerations ?

best regards,
                                Alexey Slynko
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.182
diff -c -r1.182 xlog.c
*** src/backend/access/transam/xlog.c   24 Mar 2005 04:36:17 -0000      1.182
--- src/backend/access/transam/xlog.c   25 Mar 2005 09:42:17 -0000
***************
*** 3128,3145 ****
        ControlFile->enableIntTimes = FALSE;
  #endif
  
-       ControlFile->localeBuflen = LOCALE_NAME_BUFLEN;
-       localeptr = setlocale(LC_COLLATE, NULL);
-       if (!localeptr)
-               ereport(PANIC,
-                               (errmsg("invalid LC_COLLATE setting")));
-       StrNCpy(ControlFile->lc_collate, localeptr, LOCALE_NAME_BUFLEN);
-       localeptr = setlocale(LC_CTYPE, NULL);
-       if (!localeptr)
-               ereport(PANIC,
-                               (errmsg("invalid LC_CTYPE setting")));
-       StrNCpy(ControlFile->lc_ctype, localeptr, LOCALE_NAME_BUFLEN);
- 
        /* Contents are protected with a CRC */
        INIT_CRC64(ControlFile->crc);
        COMP_CRC64(ControlFile->crc,
--- 3128,3133 ----
***************
*** 3309,3341 ****
                         errhint("It looks like you need to recompile or 
initdb.")));
  #endif
  
-       if (ControlFile->localeBuflen != LOCALE_NAME_BUFLEN)
-               ereport(FATAL,
-                               (errmsg("database files are incompatible with 
server"),
-                                errdetail("The database cluster was 
initialized with LOCALE_NAME_BUFLEN %d,"
-                         " but the server was compiled with LOCALE_NAME_BUFLEN 
%d.",
-                                                  ControlFile->localeBuflen, 
LOCALE_NAME_BUFLEN),
-                        errhint("It looks like you need to recompile or 
initdb.")));
-       if (setlocale(LC_COLLATE, ControlFile->lc_collate) == NULL)
-               ereport(FATAL,
-               (errmsg("database files are incompatible with operating 
system"),
-                errdetail("The database cluster was initialized with 
LC_COLLATE \"%s\","
-                                  " which is not recognized by setlocale().",
-                                  ControlFile->lc_collate),
-                errhint("It looks like you need to initdb or install locale 
support.")));
-       if (setlocale(LC_CTYPE, ControlFile->lc_ctype) == NULL)
-               ereport(FATAL,
-               (errmsg("database files are incompatible with operating 
system"),
-                errdetail("The database cluster was initialized with LC_CTYPE 
\"%s\","
-                                  " which is not recognized by setlocale().",
-                                  ControlFile->lc_ctype),
-                errhint("It looks like you need to initdb or install locale 
support.")));
- 
-       /* Make the fixed locale settings visible as GUC variables, too */
-       SetConfigOption("lc_collate", ControlFile->lc_collate,
-                                       PGC_INTERNAL, PGC_S_OVERRIDE);
-       SetConfigOption("lc_ctype", ControlFile->lc_ctype,
-                                       PGC_INTERNAL, PGC_S_OVERRIDE);
  }
  
  void
--- 3297,3302 ----
Index: src/backend/commands/dbcommands.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.155
diff -c -r1.155 dbcommands.c
*** src/backend/commands/dbcommands.c   23 Mar 2005 00:03:28 -0000      1.155
--- src/backend/commands/dbcommands.c   25 Mar 2005 09:42:18 -0000
***************
*** 25,30 ****
--- 25,34 ----
  #include <unistd.h>
  #include <sys/stat.h>
  
+ #ifdef HAVE_LANGINFO_H
+ #include <langinfo.h>
+ #endif
+ 
  #include "access/genam.h"
  #include "access/heapam.h"
  #include "catalog/catname.h"
***************
*** 49,54 ****
--- 53,59 ----
  #include "utils/fmgroids.h"
  #include "utils/guc.h"
  #include "utils/lsyscache.h"
+ #include "utils/pg_locale.h"
  #include "utils/syscache.h"
  
  
***************
*** 57,65 ****
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP,
                        TransactionId *dbVacuumXidP, TransactionId 
*dbFrozenXidP,
!                       Oid *dbTablespace);
  static bool have_createdb_privilege(void);
  static void remove_dbtablespaces(Oid db_id);
  
  
  /*
--- 62,72 ----
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP,
                        TransactionId *dbVacuumXidP, TransactionId 
*dbFrozenXidP,
!                       Oid *dbTablespace, char **dbCollate, char **dbCtype);
  static bool have_createdb_privilege(void);
  static void remove_dbtablespaces(Oid db_id);
+ static char * get_locale_encoding(const char *ctype);
+ static int check_locale_encoding(int encid, const char *ctype);
  
  
  /*
***************
*** 70,78 ****
  {
        HeapScanDesc scan;
        Relation        rel;
!       Oid                     src_dboid;
        AclId           src_owner;
!       int                     src_encoding;
        bool            src_istemplate;
        bool            src_allowconn;
        Oid                     src_lastsysoid;
--- 77,87 ----
  {
        HeapScanDesc scan;
        Relation        rel;
!       Oid             src_dboid;
        AclId           src_owner;
!       int             src_encoding;
!       char            *src_collate;
!       char            *src_ctype;
        bool            src_istemplate;
        bool            src_allowconn;
        Oid                     src_lastsysoid;
***************
*** 85,101 ****
        TupleDesc       pg_database_dsc;
        Datum           new_record[Natts_pg_database];
        char            new_record_nulls[Natts_pg_database];
!       Oid                     dboid;
        AclId           datdba;
        ListCell   *option;
        DefElem    *dtablespacename = NULL;
        DefElem    *downer = NULL;
        DefElem    *dtemplate = NULL;
        DefElem    *dencoding = NULL;
        char       *dbname = stmt->dbname;
        char       *dbowner = NULL;
        char       *dbtemplate = NULL;
!       int                     encoding = -1;
  
  #ifndef WIN32
        char            buf[2 * MAXPGPATH + 100];
--- 94,114 ----
        TupleDesc       pg_database_dsc;
        Datum           new_record[Natts_pg_database];
        char            new_record_nulls[Natts_pg_database];
!       Oid             dboid;
        AclId           datdba;
        ListCell   *option;
        DefElem    *dtablespacename = NULL;
        DefElem    *downer = NULL;
        DefElem    *dtemplate = NULL;
        DefElem    *dencoding = NULL;
+       DefElem    *dlc_collate = NULL;
+       DefElem    *dlc_ctype = NULL;
        char       *dbname = stmt->dbname;
        char       *dbowner = NULL;
        char       *dbtemplate = NULL;
!       char       *lc_collate = NULL;
!       char       *lc_ctype = NULL;
!       int        encoding = -1;
  
  #ifndef WIN32
        char            buf[2 * MAXPGPATH + 100];
***************
*** 141,146 ****
--- 154,175 ----
                                                 errmsg("conflicting or 
redundant options")));
                        dencoding = defel;
                }
+               else if (strcmp(defel->defname, "lccollate") == 0)
+               {
+                       if (dlc_collate)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                               errmsg("conflicting or 
redundant options")));
+                       dlc_collate = defel;
+               }
+               else if (strcmp(defel->defname, "lcctype") == 0)
+               {
+                       if (dlc_ctype)
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_SYNTAX_ERROR),
+                                               errmsg("conflicting or 
redundant options")));
+                       dlc_ctype = defel;
+               }
                else if (strcmp(defel->defname, "location") == 0)
                {
                        ereport(WARNING,
***************
*** 186,191 ****
--- 215,236 ----
                        elog(ERROR, "unrecognized node type: %d",
                                 nodeTag(dencoding->arg));
        }
+       if (dlc_collate && dlc_collate->arg) {
+               lc_collate = strVal(dlc_collate->arg);
+               if ((locale_collate_assign(lc_collate, false, (GucSource)NULL)) 
== NULL)
+                       ereport(ERROR,
+                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                               errmsg("%s is not a valid LC_COLLATE name",
+                                               lc_collate)));
+       }
+       if (dlc_ctype && dlc_ctype->arg) {
+               lc_ctype = strVal(dlc_ctype->arg);
+               if ((locale_collate_assign(lc_ctype, false, (GucSource)NULL)) 
== NULL)
+                       ereport(ERROR,
+                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                               errmsg("%s is not a valid LC_CTYPE name",
+                                               lc_ctype)));
+       }
  
        /* obtain sysid of proposed owner */
        if (dbowner)
***************
*** 220,226 ****
         * after we grab the exclusive lock.
         */
        if (get_db_info(dbname, NULL, NULL, NULL,
!                                       NULL, NULL, NULL, NULL, NULL, NULL))
                ereport(ERROR,
                                (errcode(ERRCODE_DUPLICATE_DATABASE),
                                 errmsg("database \"%s\" already exists", 
dbname)));
--- 265,271 ----
         * after we grab the exclusive lock.
         */
        if (get_db_info(dbname, NULL, NULL, NULL,
!                                       NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL))
                ereport(ERROR,
                                (errcode(ERRCODE_DUPLICATE_DATABASE),
                                 errmsg("database \"%s\" already exists", 
dbname)));
***************
*** 233,239 ****
  
        if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
                                         &src_istemplate, &src_allowconn, 
&src_lastsysoid,
!                                        &src_vacuumxid, &src_frozenxid, 
&src_deftablespace))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                 errmsg("template database \"%s\" does not exist", 
dbtemplate)));
--- 278,285 ----
  
        if (!get_db_info(dbtemplate, &src_dboid, &src_owner, &src_encoding,
                                         &src_istemplate, &src_allowconn, 
&src_lastsysoid,
!                                        &src_vacuumxid, &src_frozenxid, 
&src_deftablespace,
!                                        &src_collate, &src_ctype))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                 errmsg("template database \"%s\" does not exist", 
dbtemplate)));
***************
*** 263,268 ****
--- 309,315 ----
                errmsg("source database \"%s\" is being accessed by other 
users",
                           dbtemplate)));
  
+ 
        /* If encoding is defaulted, use source's encoding */
        if (encoding < 0)
                encoding = src_encoding;
***************
*** 273,278 ****
--- 320,340 ----
                                (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                 errmsg("invalid server encoding %d", 
encoding)));
  
+       /* Set database lc_collate and lc_ctype */
+       if (!lc_collate)
+               lc_collate = src_collate;
+       if (!lc_ctype) 
+               lc_ctype = src_ctype;
+ 
+ #if defined(HAVE_LANGINFO_H) && defined(CODESET)
+       if (encoding > 0 && check_locale_encoding(encoding, lc_ctype) == -1)
+               ereport(ERROR,
+                               (errcode(ERRCODE_WRONG_OBJECT_TYPE),
+                                errmsg("encoding %s is not suitable for locale 
%s", 
+                                                       
pg_encoding_to_char(encoding), 
+                                                       lc_ctype)));
+ #endif
+ 
        /* Resolve default tablespace for new database */
        if (dtablespacename && dtablespacename->arg)
        {
***************
*** 463,469 ****
  
        /* Check to see if someone else created same DB name meanwhile. */
        if (get_db_info(dbname, NULL, NULL, NULL,
!                                       NULL, NULL, NULL, NULL, NULL, NULL))
        {
                /* Don't hold lock while doing recursive remove */
                heap_close(pg_database_rel, ExclusiveLock);
--- 525,531 ----
  
        /* Check to see if someone else created same DB name meanwhile. */
        if (get_db_info(dbname, NULL, NULL, NULL,
!                                       NULL, NULL, NULL, NULL, NULL, NULL, 
NULL, NULL))
        {
                /* Don't hold lock while doing recursive remove */
                heap_close(pg_database_rel, ExclusiveLock);
***************
*** 486,491 ****
--- 548,557 ----
                DirectFunctionCall1(namein, CStringGetDatum(dbname));
        new_record[Anum_pg_database_datdba - 1] = Int32GetDatum(datdba);
        new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
+       new_record[Anum_pg_database_datcollate - 1] = 
+               DirectFunctionCall1(namein, CStringGetDatum(lc_collate));
+       new_record[Anum_pg_database_datctype - 1] = 
+               DirectFunctionCall1(namein, CStringGetDatum(lc_ctype));
        new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
        new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
        new_record[Anum_pg_database_datlastsysoid - 1] = 
ObjectIdGetDatum(src_lastsysoid);
***************
*** 560,566 ****
        pgdbrel = heap_openr(DatabaseRelationName, ExclusiveLock);
  
        if (!get_db_info(dbname, &db_id, &db_owner, NULL,
!                                        &db_istemplate, NULL, NULL, NULL, 
NULL, NULL))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                                 errmsg("database \"%s\" does not exist", 
dbname)));
--- 626,632 ----
        pgdbrel = heap_openr(DatabaseRelationName, ExclusiveLock);
  
        if (!get_db_info(dbname, &db_id, &db_owner, NULL,
!                                        &db_istemplate, NULL, NULL, NULL, 
NULL, NULL, NULL, NULL))
                ereport(ERROR,
                                (errcode(ERRCODE_UNDEFINED_DATABASE),
                                 errmsg("database \"%s\" does not exist", 
dbname)));
***************
*** 947,953 ****
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP,
                        TransactionId *dbVacuumXidP, TransactionId 
*dbFrozenXidP,
!                       Oid *dbTablespace)
  {
        Relation        relation;
        ScanKeyData scanKey;
--- 1013,1019 ----
                        int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
                        Oid *dbLastSysOidP,
                        TransactionId *dbVacuumXidP, TransactionId 
*dbFrozenXidP,
!                       Oid *dbTablespace, char **dbCollate, char **dbCtype)
  {
        Relation        relation;
        ScanKeyData scanKey;
***************
*** 1002,1007 ****
--- 1068,1078 ----
                /* default tablespace for this database */
                if (dbTablespace)
                        *dbTablespace = dbform->dattablespace;
+               /* default locale settings for this database */
+               if (dbCollate)
+                       *dbCollate = NameStr(dbform->datcollate);
+               if (dbCtype)
+                       *dbCtype = NameStr(dbform->datctype);
        }
  
        systable_endscan(scan);
***************
*** 1379,1381 ****
--- 1450,1494 ----
        else
                strcat(buf, "UNKNOWN");
  }
+ 
+ #if defined(HAVE_LANGINFO_H) && defined(CODESET)
+    
+ static char *
+ get_locale_encoding(const char *ctype)
+ {
+       char       *save;
+       char       *sys;
+                         
+         save = setlocale(LC_CTYPE, NULL);
+         if (!save)
+                 return NULL;
+         save = pstrdup(save);
+                                 
+         setlocale(LC_CTYPE, ctype);
+         sys = nl_langinfo(CODESET);
+         sys = pstrdup(sys);
+                         
+         setlocale(LC_CTYPE, save);
+         pfree(save);
+             
+         return sys;
+ }
+         
+ static int
+ check_locale_encoding(int encid, const char *ctype)
+ {
+         char       *sys;
+         
+         sys = get_locale_encoding(ctype);
+         if (encid == pg_char_to_encoding(sys))
+         {
+                 pfree(sys);
+                 return 0;
+         }
+         
+         pfree(sys);
+         return -1;
+ }
+ 
+ #endif
+ 
Index: src/backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.484
diff -c -r2.484 gram.y
*** src/backend/parser/gram.y   14 Mar 2005 00:19:36 -0000      2.484
--- src/backend/parser/gram.y   25 Mar 2005 09:42:18 -0000
***************
*** 368,376 ****
  
        KEY
  
!       LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEFT LEVEL LIKE LIMIT
!       LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
!       LOCK_P
  
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
--- 368,377 ----
  
        KEY
  
!       LANCOMPILER LANGUAGE LARGE_P LAST_P 
!       LCCOLLATE LCCTYPE LEADING LEFT LEVEL 
!       LIKE LIMIT LISTEN LOAD LOCAL 
!       LOCALTIME LOCALTIMESTAMP LOCATION LOCK_P
  
        MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
***************
*** 4220,4225 ****
--- 4221,4242 ----
                                {
                                        $$ = makeDefElem("encoding", NULL);
                                }
+                       | LCCOLLATE opt_equal name
+                               {
+                                       $$ = makeDefElem("lccollate", (Node 
*)makeString($3));
+                               }
+                       | LCCOLLATE opt_equal DEFAULT
+                               {
+                                       $$ = makeDefElem("lccollate", NULL);
+                               }
+                       | LCCTYPE opt_equal name
+                               {
+                                       $$ = makeDefElem("lcctype", (Node 
*)makeString($3));
+                               }
+                       | LCCTYPE opt_equal DEFAULT
+                               {
+                                       $$ = makeDefElem("lcctype", NULL);
+                               }
                        | OWNER opt_equal name
                                {
                                        $$ = makeDefElem("owner", (Node 
*)makeString($3));
***************
*** 7763,7768 ****
--- 7780,7787 ----
                        | LANGUAGE
                        | LARGE_P
                        | LAST_P
+                       | LCCOLLATE
+                       | LCCTYPE
                        | LEVEL
                        | LISTEN
                        | LOAD
Index: src/backend/parser/keywords.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.154
diff -c -r1.154 keywords.c
*** src/backend/parser/keywords.c       31 Dec 2004 22:00:27 -0000      1.154
--- src/backend/parser/keywords.c       25 Mar 2005 09:42:18 -0000
***************
*** 181,186 ****
--- 181,188 ----
        {"language", LANGUAGE},
        {"large", LARGE_P},
        {"last", LAST_P},
+       {"lccollate", LCCOLLATE},
+       {"lcctype", LCCTYPE},
        {"leading", LEADING},
        {"left", LEFT},
        {"level", LEVEL},
Index: src/backend/utils/adt/pg_locale.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
retrieving revision 1.31
diff -c -r1.31 pg_locale.c
*** src/backend/utils/adt/pg_locale.c   16 Mar 2005 00:02:49 -0000      1.31
--- src/backend/utils/adt/pg_locale.c   25 Mar 2005 09:42:18 -0000
***************
*** 10,19 ****
   */
  
  /*----------
!  * Here is how the locale stuff is handled: LC_COLLATE and LC_CTYPE
!  * are fixed by initdb, stored in pg_control, and cannot be changed.
!  * Thus, the effects of strcoll(), strxfrm(), isupper(), toupper(),
!  * etc. are always in the same fixed locale.
   *
   * LC_MESSAGES is settable at run time and will take effect
   * immediately.
--- 10,17 ----
   */
  
  /*----------
!  * Here is how the locale stuff is handled: 
!  * LC_COLLATE and LC_CTYPE are defined by createdb and stored in pg_database.
   *
   * LC_MESSAGES is settable at run time and will take effect
   * immediately.
***************
*** 97,102 ****
--- 95,111 ----
        return value;
  }
  
+ const char *
+ locale_collate_assign(const char *value, bool doit, GucSource source)
+ {
+       return locale_xxx_assign(LC_COLLATE, value, doit, source);
+ }
+ 
+ const char *
+ locale_ctype_assign(const char *value, bool doit, GucSource source)
+ {
+       return locale_xxx_assign(LC_CTYPE, value, doit, source);
+ }
  
  const char *
  locale_monetary_assign(const char *value, bool doit, GucSource source)
Index: src/backend/utils/init/postinit.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/init/postinit.c,v
retrieving revision 1.144
diff -c -r1.144 postinit.c
*** src/backend/utils/init/postinit.c   19 Mar 2005 23:27:06 -0000      1.144
--- src/backend/utils/init/postinit.c   25 Mar 2005 09:42:18 -0000
***************
*** 36,41 ****
--- 36,42 ----
  #include "storage/proc.h"
  #include "storage/sinval.h"
  #include "storage/smgr.h"
+ #include "utils/builtins.h"
  #include "utils/flatfiles.h"
  #include "utils/fmgroids.h"
  #include "utils/guc.h"
***************
*** 114,120 ****
   * invalid database.  If we quit now, we should have managed to avoid
   * creating any serious problems.
   *
!  * This is also a handy place to fetch the database encoding info out
   * of pg_database.
   *
   * To avoid having to read pg_database more times than necessary
--- 115,121 ----
   * invalid database.  If we quit now, we should have managed to avoid
   * creating any serious problems.
   *
!  * This is also a handy place to fetch the database encoding and locale info 
out
   * of pg_database.
   *
   * To avoid having to read pg_database more times than necessary
***************
*** 129,134 ****
--- 130,137 ----
        ScanKeyData key;
        HeapTuple       tup;
        Form_pg_database dbform;
+       char            *lc_ctype;
+       char            *lc_collate;
  
        /*
         * Because we grab RowShareLock here, we can be sure that dropdb()
***************
*** 175,181 ****
                                name)));
  
        /*
!        * OK, we're golden.  Next to-do item is to save the encoding
         * info out of the pg_database tuple.
         */
        SetDatabaseEncoding(dbform->encoding);
--- 178,184 ----
                                name)));
  
        /*
!        * OK, we're golden.  Next to-do item is to save the encoding 
         * info out of the pg_database tuple.
         */
        SetDatabaseEncoding(dbform->encoding);
***************
*** 186,191 ****
--- 189,221 ----
        SetConfigOption("client_encoding", GetDatabaseEncodingName(),
                                        PGC_BACKEND, PGC_S_DEFAULT);
  
+       /* 
+        * Set up database locale 
+        */
+       lc_collate = NameStr(dbform->datcollate);
+       lc_ctype = NameStr(dbform->datctype);
+ 
+       if (setlocale(LC_COLLATE, lc_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().",
+                                       lc_collate),
+                       errhint("It looks like you need to recreate database or 
install locale support.")));
+       if (setlocale(LC_CTYPE, lc_ctype) == NULL)
+               ereport(FATAL,
+                       (errmsg("database locale are incompatible with 
operating system"),
+                       errdetail("The database was initialized with LC_CTYPE 
\"%s\","
+                                       " which is not recognized by 
setlocale().",
+                                       lc_ctype),
+                       errhint("It looks like you need to recreate database or 
install locale support.")));
+ 
+       /* Record it as a GUC internal option, too */
+       SetConfigOption("lc_collate", lc_collate,
+                                       PGC_INTERNAL, PGC_S_DATABASE);
+       SetConfigOption("lc_ctype", lc_ctype,
+                                       PGC_INTERNAL, PGC_S_DATABASE);
+ 
        /*
         * Lastly, set up any database-specific configuration variables.
         */
***************
*** 466,471 ****
--- 496,502 ----
        /* set default namespace search path */
        InitializeSearchPath();
  
+               
        /* initialize client encoding */
        InitializeClientEncoding();
  
Index: src/bin/initdb/initdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.79
diff -c -r1.79 initdb.c
*** src/bin/initdb/initdb.c     14 Mar 2005 18:31:23 -0000      1.79
--- src/bin/initdb/initdb.c     25 Mar 2005 09:42:18 -0000
***************
*** 1272,1277 ****
--- 1272,1281 ----
  
        bki_lines = replace_token(bki_lines, "ENCODING", encodingid);
  
+       bki_lines = replace_token(bki_lines, "LC_COLLATE", lc_collate);
+ 
+       bki_lines = replace_token(bki_lines, "LC_CTYPE", lc_ctype);
+ 
        /*
         * Pass correct LC_xxx environment to bootstrap.
         *
***************
*** 2423,2429 ****
                printf(_("The database cluster will be initialized with locale 
%s.\n"), lc_ctype);
        else
        {
!               printf(_("The database cluster will be initialized with 
locales\n"
                                 "  COLLATE:  %s\n"
                                 "  CTYPE:    %s\n"
                                 "  MESSAGES: %s\n"
--- 2427,2433 ----
                printf(_("The database cluster will be initialized with locale 
%s.\n"), lc_ctype);
        else
        {
!               printf(_("The database template1 will be initialized with 
locales\n"
                                 "  COLLATE:  %s\n"
                                 "  CTYPE:    %s\n"
                                 "  MESSAGES: %s\n"
Index: src/bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.21
diff -c -r1.21 pg_controldata.c
*** src/bin/pg_controldata/pg_controldata.c     22 Feb 2005 04:39:00 -0000      
1.21
--- src/bin/pg_controldata/pg_controldata.c     25 Mar 2005 09:42:18 -0000
***************
*** 173,181 ****
        printf(_("Maximum number of function arguments: %u\n"), 
ControlFile.funcMaxArgs);
        printf(_("Date/time type storage:               %s\n"),
                   (ControlFile.enableIntTimes ? _("64-bit integers") : 
_("floating-point numbers")));
-       printf(_("Maximum length of locale name:        %u\n"), 
ControlFile.localeBuflen);
-       printf(_("LC_COLLATE:                           %s\n"), 
ControlFile.lc_collate);
-       printf(_("LC_CTYPE:                             %s\n"), 
ControlFile.lc_ctype);
- 
        return 0;
  }
--- 173,177 ----
Index: src/bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.29
diff -c -r1.29 pg_resetxlog.c
*** src/bin/pg_resetxlog/pg_resetxlog.c 22 Feb 2005 04:40:20 -0000      1.29
--- src/bin/pg_resetxlog/pg_resetxlog.c 25 Mar 2005 09:42:18 -0000
***************
*** 423,444 ****
  #else
        ControlFile.enableIntTimes = FALSE;
  #endif
-       ControlFile.localeBuflen = LOCALE_NAME_BUFLEN;
- 
-       localeptr = setlocale(LC_COLLATE, "");
-       if (!localeptr)
-       {
-               fprintf(stderr, _("%s: invalid LC_COLLATE setting\n"), 
progname);
-               exit(1);
-       }
-       StrNCpy(ControlFile.lc_collate, localeptr, LOCALE_NAME_BUFLEN);
-       localeptr = setlocale(LC_CTYPE, "");
-       if (!localeptr)
-       {
-               fprintf(stderr, _("%s: invalid LC_CTYPE setting\n"), progname);
-               exit(1);
-       }
-       StrNCpy(ControlFile.lc_ctype, localeptr, LOCALE_NAME_BUFLEN);
  
        /*
         * XXX eventually, should try to grovel through old XLOG to develop
--- 423,428 ----
***************
*** 484,492 ****
        printf(_("Maximum number of function arguments: %u\n"), 
ControlFile.funcMaxArgs);
        printf(_("Date/time type storage:               %s\n"),
                   (ControlFile.enableIntTimes ? _("64-bit integers") : 
_("floating-point numbers")));
-       printf(_("Maximum length of locale name:        %u\n"), 
ControlFile.localeBuflen);
-       printf(_("LC_COLLATE:                           %s\n"), 
ControlFile.lc_collate);
-       printf(_("LC_CTYPE:                             %s\n"), 
ControlFile.lc_ctype);
  }
  
  
--- 468,473 ----
Index: src/bin/psql/describe.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.113
diff -c -r1.113 describe.c
*** src/bin/psql/describe.c     16 Mar 2005 23:52:18 -0000      1.113
--- src/bin/psql/describe.c     25 Mar 2005 09:42:18 -0000
***************
*** 361,366 ****
--- 361,372 ----
        appendPQExpBuffer(&buf,
                ",\n       pg_catalog.pg_encoding_to_char(d.encoding) as 
\"%s\"",
                                          _("Encoding"));
+       appendPQExpBuffer(&buf,
+               ",\n       d.datcollate as \"%s\"",
+                                        _("LC_COLLATE"));
+       appendPQExpBuffer(&buf,
+               ",\n       d.datctype as \"%s\"",
+                                        _("LC_CTYPE"));
        if (verbose)
                appendPQExpBuffer(&buf,
                                                  ",\n       
pg_catalog.obj_description(d.oid, 'pg_database') as \"%s\"",
Index: src/bin/scripts/createdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/createdb.c,v
retrieving revision 1.14
diff -c -r1.14 createdb.c
*** src/bin/scripts/createdb.c  31 Dec 2004 22:03:17 -0000      1.14
--- src/bin/scripts/createdb.c  25 Mar 2005 09:42:18 -0000
***************
*** 34,39 ****
--- 34,41 ----
                {"tablespace", required_argument, NULL, 'D'},
                {"template", required_argument, NULL, 'T'},
                {"encoding", required_argument, NULL, 'E'},
+               {"lc-collate", required_argument, NULL, 1},
+               {"lc-ctype", required_argument, NULL, 2},
                {NULL, 0, NULL, 0}
        };
  
***************
*** 53,58 ****
--- 55,62 ----
        char       *tablespace = NULL;
        char       *template = NULL;
        char       *encoding = NULL;
+       char       *lc_collate = NULL;
+       char       *lc_ctype = NULL;
  
        PQExpBufferData sql;
  
***************
*** 98,103 ****
--- 102,113 ----
                        case 'E':
                                encoding = optarg;
                                break;
+                       case 1:
+                               lc_collate = optarg;
+                               break;
+                       case 2:
+                               lc_ctype = optarg;
+                               break;
                        default:
                                fprintf(stderr, _("Try \"%s --help\" for more 
information.\n"), progname);
                                exit(1);
***************
*** 155,161 ****
--- 165,176 ----
                appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
        if (template)
                appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
+       if (lc_collate)
+               appendPQExpBuffer(&sql, " LCCOLLATE %s", fmtId(lc_collate));
+       if (lc_ctype)
+               appendPQExpBuffer(&sql, " LCCTYPE %s", fmtId(lc_ctype));
        appendPQExpBuffer(&sql, ";\n");
+       
  
        conn = connectDatabase("template1", host, port, username, password, 
progname);
  
***************
*** 218,236 ****
        printf(_("Usage:\n"));
        printf(_("  %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
        printf(_("\nOptions:\n"));
!       printf(_("  -D, --tablespace=TABLESPACE  default tablespace for the 
database\n"));
!       printf(_("  -E, --encoding=ENCODING      encoding for the database\n"));
!       printf(_("  -O, --owner=OWNER            database user to own the new 
database\n"));
!       printf(_("  -T, --template=TEMPLATE      template database to copy\n"));
!       printf(_("  -e, --echo                   show the commands being sent 
to the server\n"));
!       printf(_("  -q, --quiet                  don't write any messages\n"));
!       printf(_("  --help                       show this help, then exit\n"));
!       printf(_("  --version                    output version information, 
then exit\n"));
        printf(_("\nConnection options:\n"));
!       printf(_("  -h, --host=HOSTNAME          database server host or socket 
directory\n"));
!       printf(_("  -p, --port=PORT              database server port\n"));
!       printf(_("  -U, --username=USERNAME      user name to connect as\n"));
!       printf(_("  -W, --password               prompt for password\n"));
        printf(_("\nBy default, a database with the same name as the current 
user is created.\n"));
        printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
  }
--- 233,252 ----
        printf(_("Usage:\n"));
        printf(_("  %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
        printf(_("\nOptions:\n"));
!       printf(_("  -D, --tablespace=TABLESPACE         default tablespace for 
the database\n"));
!       printf(_("  -E, --encoding=ENCODING             encoding for the 
database\n"));
!       printf(_("  --lc-collate, --lc-ctype=LOCALE     initialize database 
with given locale\n"));
!       printf(_("  -O, --owner=OWNER                   database user to own 
the new database\n"));
!       printf(_("  -T, --template=TEMPLATE             template database to 
copy\n"));
!       printf(_("  -e, --echo                          show the commands being 
sent to the server\n"));
!       printf(_("  -q, --quiet                         don't write any 
messages\n"));
!       printf(_("  --help                              show this help, then 
exit\n"));
!       printf(_("  --version                           output version 
information, then exit\n"));
        printf(_("\nConnection options:\n"));
!       printf(_("  -h, --host=HOSTNAME                 database server host or 
socket directory\n"));
!       printf(_("  -p, --port=PORT                     database server 
port\n"));
!       printf(_("  -U, --username=USERNAME             user name to connect 
as\n"));
!       printf(_("  -W, --password                      prompt for 
password\n"));
        printf(_("\nBy default, a database with the same name as the current 
user is created.\n"));
        printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
  }
Index: src/include/catalog/pg_attribute.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_attribute.h,v
retrieving revision 1.113
diff -c -r1.113 pg_attribute.h
*** src/include/catalog/pg_attribute.h  31 Dec 2004 22:03:24 -0000      1.113
--- src/include/catalog/pg_attribute.h  25 Mar 2005 09:42:18 -0000
***************
*** 285,298 ****
  DATA(insert ( 1262 datname                    19 -1 NAMEDATALEN       1 0 -1 
-1 f p i t f f t 0));
  DATA(insert ( 1262 datdba                     23 -1 4   2 0 -1 -1 t p i t f f 
t 0));
  DATA(insert ( 1262 encoding                   23 -1 4   3 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 datistemplate      16 -1 1   4 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1262 datallowconn               16 -1 1   5 0 -1 -1 t p c t f f 
t 0));
! DATA(insert ( 1262 datlastsysoid      26 -1 4   6 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1262 datvacuumxid               28 -1 4   7 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 datfrozenxid               28 -1 4   8 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 dattablespace      26 -1 4   9 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1262 datconfig    1009 -1 -1 10 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1262 datacl               1034 -1 -1 11 1 -1 -1 f x i f f f t 
0));
  DATA(insert ( 1262 ctid                               27 0  6  -1 0 -1 -1 f p 
s t f f t 0));
  DATA(insert ( 1262 oid                                26 0  4  -2 0 -1 -1 t p 
i t f f t 0));
  DATA(insert ( 1262 xmin                               28 0  4  -3 0 -1 -1 t p 
i t f f t 0));
--- 285,300 ----
  DATA(insert ( 1262 datname                    19 -1 NAMEDATALEN       1 0 -1 
-1 f p i t f f t 0));
  DATA(insert ( 1262 datdba                     23 -1 4   2 0 -1 -1 t p i t f f 
t 0));
  DATA(insert ( 1262 encoding                   23 -1 4   3 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 datcollate         19 -1 NAMEDATALEN 4 0 -1 -1 f p i t f f 
t 0));
! DATA(insert ( 1262 datctype           19 -1 NAMEDATALEN 5 0 -1 -1 f p i t f f 
t 0));
! DATA(insert ( 1262 datistemplate      16 -1 1   6 0 -1 -1 t p c t f f t 0));
! DATA(insert ( 1262 datallowconn               16 -1 1   7 0 -1 -1 t p c t f f 
t 0));
! DATA(insert ( 1262 datlastsysoid      26 -1 4   8 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1262 datvacuumxid               28 -1 4   9 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 datfrozenxid               28 -1 4  10 0 -1 -1 t p i t f f 
t 0));
! DATA(insert ( 1262 dattablespace      26 -1 4  11 0 -1 -1 t p i t f f t 0));
! DATA(insert ( 1262 datconfig          1009 -1 -1 12 1 -1 -1 f x i f f f t 0));
! DATA(insert ( 1262 datacl             1034 -1 -1 13 1 -1 -1 f x i f f f t 0));
  DATA(insert ( 1262 ctid                               27 0  6  -1 0 -1 -1 f p 
s t f f t 0));
  DATA(insert ( 1262 oid                                26 0  4  -2 0 -1 -1 t p 
i t f f t 0));
  DATA(insert ( 1262 xmin                               28 0  4  -3 0 -1 -1 t p 
i t f f t 0));
Index: src/include/catalog/pg_class.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_class.h,v
retrieving revision 1.85
diff -c -r1.85 pg_class.h
*** src/include/catalog/pg_class.h      31 Dec 2004 22:03:24 -0000      1.85
--- src/include/catalog/pg_class.h      25 Mar 2005 09:42:18 -0000
***************
*** 148,154 ****
  DESCR("");
  DATA(insert OID = 1261 (  pg_group            PGNSP 87 PGUID 0 1261 1664 0 0 
0 0 f t r 3      0 0 0 0 0 f f f f _null_ ));
  DESCR("");
! DATA(insert OID = 1262 (  pg_database PGNSP 88 PGUID 0 1262 1664 0 0 0 0 f t 
r 11 0 0 0 0 0 t f f f _null_ ));
  DESCR("");
  DATA(insert OID = 1213 (  pg_tablespace PGNSP 90 PGUID 0 1213 1664 0 0 0 0 f 
t r 4    0 0 0 0 0 t f f f _null_ ));
  DESCR("");
--- 148,154 ----
  DESCR("");
  DATA(insert OID = 1261 (  pg_group            PGNSP 87 PGUID 0 1261 1664 0 0 
0 0 f t r 3      0 0 0 0 0 f f f f _null_ ));
  DESCR("");
! DATA(insert OID = 1262 (  pg_database PGNSP 88 PGUID 0 1262 1664 0 0 0 0 f t 
r 13 0 0 0 0 0 t f f f _null_ ));
  DESCR("");
  DATA(insert OID = 1213 (  pg_tablespace PGNSP 90 PGUID 0 1213 1664 0 0 0 0 f 
t r 4    0 0 0 0 0 t f f f _null_ ));
  DESCR("");
Index: src/include/catalog/pg_control.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_control.h,v
retrieving revision 1.19
diff -c -r1.19 pg_control.h
*** src/include/catalog/pg_control.h    31 Dec 2004 22:03:24 -0000      1.19
--- src/include/catalog/pg_control.h    25 Mar 2005 09:42:18 -0000
***************
*** 121,130 ****
        /* flag indicating internal format of timestamp, interval, time */
        uint32          enableIntTimes; /* int64 storage enabled? */
  
-       /* active locales */
-       uint32          localeBuflen;
-       char            lc_collate[LOCALE_NAME_BUFLEN];
-       char            lc_ctype[LOCALE_NAME_BUFLEN];
  } ControlFileData;
  
  #endif   /* PG_CONTROL_H */
--- 121,126 ----
Index: src/include/catalog/pg_database.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_database.h,v
retrieving revision 1.34
diff -c -r1.34 pg_database.h
*** src/include/catalog/pg_database.h   31 Dec 2004 22:03:24 -0000      1.34
--- src/include/catalog/pg_database.h   25 Mar 2005 09:42:18 -0000
***************
*** 36,41 ****
--- 36,43 ----
        NameData        datname;                /* database name */
        int4            datdba;                 /* sysid of owner */
        int4            encoding;               /* character encoding */
+       NameData        datcollate;             /* locale LC_COLLATE */
+       NameData        datctype;               /* locale LC_CTYPE */
        bool            datistemplate;  /* allowed as CREATE DATABASE template? 
*/
        bool            datallowconn;   /* new connections allowed? */
        Oid                     datlastsysoid;  /* highest OID to consider a 
system OID */
***************
*** 57,76 ****
   *            compiler constants for pg_database
   * ----------------
   */
! #define Natts_pg_database                             11
  #define Anum_pg_database_datname              1
  #define Anum_pg_database_datdba                       2
  #define Anum_pg_database_encoding             3
! #define Anum_pg_database_datistemplate        4
! #define Anum_pg_database_datallowconn 5
! #define Anum_pg_database_datlastsysoid        6
! #define Anum_pg_database_datvacuumxid 7
! #define Anum_pg_database_datfrozenxid 8
! #define Anum_pg_database_dattablespace        9
! #define Anum_pg_database_datconfig            10
! #define Anum_pg_database_datacl                       11
  
! DATA(insert OID = 1 (  template1 PGUID ENCODING t t 0 0 0 1663 _null_ _null_ 
));
  DESCR("Default template database");
  #define TemplateDbOid                 1
  
--- 59,80 ----
   *            compiler constants for pg_database
   * ----------------
   */
! #define Natts_pg_database                             13
  #define Anum_pg_database_datname              1
  #define Anum_pg_database_datdba                       2
  #define Anum_pg_database_encoding             3
! #define Anum_pg_database_datcollate   4
! #define Anum_pg_database_datctype     5       
! #define Anum_pg_database_datistemplate        6
! #define Anum_pg_database_datallowconn 7
! #define Anum_pg_database_datlastsysoid        8
! #define Anum_pg_database_datvacuumxid 9
! #define Anum_pg_database_datfrozenxid 10      
! #define Anum_pg_database_dattablespace        11      
! #define Anum_pg_database_datconfig            12
! #define Anum_pg_database_datacl                       13
  
! DATA(insert OID = 1 (  template1 PGUID ENCODING LC_CTYPE LC_COLLATE t t 0 0 0 
1663 _null_ _null_ ));
  DESCR("Default template database");
  #define TemplateDbOid                 1
  
Index: src/include/utils/pg_locale.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/pg_locale.h,v
retrieving revision 1.20
diff -c -r1.20 pg_locale.h
*** src/include/utils/pg_locale.h       16 Mar 2005 00:02:49 -0000      1.20
--- src/include/utils/pg_locale.h       25 Mar 2005 09:42:18 -0000
***************
*** 22,27 ****
--- 22,31 ----
  extern char *locale_numeric;
  extern char *locale_time;
  
+ extern const char *locale_collate_assign(const char *value,
+                                          bool doit, GucSource source);
+ extern const char *locale_ctype_assign(const char *value,
+                                          bool doit, GucSource source);
  extern const char *locale_messages_assign(const char *value,
                                           bool doit, GucSource source);
  extern const char *locale_monetary_assign(const char *value,
---------------------------(end of broadcast)---------------------------
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]

Reply via email to