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 #include + #ifdef HAVE_LANGINFO_H + #include + #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 .\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 .\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,