*** src/backend/access/transam/xlog.c
--- src/backend/access/transam/xlog.c
***************
*** 3847,3853 **** WriteControlFile(void)
  {
  	int			fd;
  	char		buffer[PG_CONTROL_SIZE];		/* need not be aligned */
- 	char	   *localeptr;
  
  	/*
  	 * Initialize version and compatibility-check fields
--- 3847,3852 ----
***************
*** 3875,3893 **** WriteControlFile(void)
  #endif
  	ControlFile->float4ByVal = FLOAT4PASSBYVAL;
  	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
! 
! 	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_CRC32(ControlFile->crc);
  	COMP_CRC32(ControlFile->crc,
--- 3874,3880 ----
  #endif
  	ControlFile->float4ByVal = FLOAT4PASSBYVAL;
  	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
! 	
  	/* Contents are protected with a CRC */
  	INIT_CRC32(ControlFile->crc);
  	COMP_CRC32(ControlFile->crc,
***************
*** 4126,4159 **** ReadControlFile(void)
  						   " but the server was compiled without USE_FLOAT8_BYVAL."),
  				 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 (pg_perm_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 (pg_perm_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
--- 4113,4118 ----
*** src/backend/commands/dbcommands.c
--- src/backend/commands/dbcommands.c
***************
*** 69,75 **** static bool get_db_info(const char *name, LOCKMODE lockmode,
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace);
  static bool have_createdb_privilege(void);
  static void remove_dbtablespaces(Oid db_id);
  static bool check_db_file_conflict(Oid db_id);
--- 69,75 ----
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace, char **dbCollation, char **dbCtype);
  static bool have_createdb_privilege(void);
  static void remove_dbtablespaces(Oid db_id);
  static bool check_db_file_conflict(Oid db_id);
***************
*** 87,92 **** createdb(const CreatedbStmt *stmt)
--- 87,94 ----
  	Oid			src_dboid;
  	Oid			src_owner;
  	int			src_encoding;
+ 	char	   *src_collation;
+ 	char	   *src_ctype;
  	bool		src_istemplate;
  	bool		src_allowconn;
  	Oid			src_lastsysoid;
***************
*** 104,113 **** createdb(const CreatedbStmt *stmt)
--- 106,119 ----
  	DefElem    *downer = NULL;
  	DefElem    *dtemplate = NULL;
  	DefElem    *dencoding = NULL;
+ 	DefElem    *dcollation = NULL;
+ 	DefElem    *dctype = NULL;
  	DefElem    *dconnlimit = NULL;
  	char	   *dbname = stmt->dbname;
  	char	   *dbowner = NULL;
  	const char *dbtemplate = NULL;
+ 	char	   *lc_collate = NULL;
+ 	char	   *lc_ctype = NULL;
  	int			encoding = -1;
  	int			dbconnlimit = -1;
  	int			ctype_encoding;
***************
*** 152,157 **** createdb(const CreatedbStmt *stmt)
--- 158,179 ----
  						 errmsg("conflicting or redundant options")));
  			dencoding = defel;
  		}
+ 		else if (strcmp(defel->defname, "collate") == 0)
+ 		{
+ 			if (dcollation)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("conflicting or redundant options")));
+ 			dcollation = defel;
+ 		}
+ 		else if (strcmp(defel->defname, "ctype") == 0)
+ 		{
+ 			if (dctype)
+ 				ereport(ERROR,
+ 						(errcode(ERRCODE_SYNTAX_ERROR),
+ 						 errmsg("conflicting or redundant options")));
+ 			dctype = defel;
+ 		}
  		else if (strcmp(defel->defname, "connectionlimit") == 0)
  		{
  			if (dconnlimit)
***************
*** 205,210 **** createdb(const CreatedbStmt *stmt)
--- 227,247 ----
  			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 (dcollation && dcollation->arg)
+ 		lc_collate = strVal(dcollation->arg);
+ 	if (dctype && dctype->arg)
+ 		lc_ctype = strVal(dctype->arg);
+ 	
  	if (dconnlimit && dconnlimit->arg)
  		dbconnlimit = intVal(dconnlimit->arg);
  
***************
*** 243,249 **** createdb(const CreatedbStmt *stmt)
  	if (!get_db_info(dbtemplate, ShareLock,
  					 &src_dboid, &src_owner, &src_encoding,
  					 &src_istemplate, &src_allowconn, &src_lastsysoid,
! 					 &src_frozenxid, &src_deftablespace))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("template database \"%s\" does not exist",
--- 280,286 ----
  	if (!get_db_info(dbtemplate, ShareLock,
  					 &src_dboid, &src_owner, &src_encoding,
  					 &src_istemplate, &src_allowconn, &src_lastsysoid,
! 					 &src_frozenxid, &src_deftablespace, &src_collation, &src_ctype))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("template database \"%s\" does not exist",
***************
*** 305,310 **** createdb(const CreatedbStmt *stmt)
--- 342,359 ----
  			 errdetail("The server's LC_CTYPE setting requires encoding %s.",
  					   pg_encoding_to_char(ctype_encoding))));
  
+ 	/*
+ 	 * Message about reindexing new database
+ 	 *
+ 	 * We know that template0 doesn't contain any indexes that depend on
+ 	 * collation or ctype.
+ 	 */
+ 	if (strcmp(dbtemplate, "template0") != 0 &&
+ 		(strcmp(lc_collate, src_collation) || strcmp(lc_ctype, src_ctype)))
+ 		ereport(NOTICE,
+ 				(errmsg("database \"%s\" needs to be reindexed manually (REINDEX DATABASE)",
+ 						dbname)));		
+ 
  	/* Resolve default tablespace for new database */
  	if (dtablespacename && dtablespacename->arg)
  	{
***************
*** 369,374 **** createdb(const CreatedbStmt *stmt)
--- 418,432 ----
  		/* Note there is no additional permission check in this path */
  	}
  
+ 	/*	
+ 	 * If collation is specified for database, use it, otherwise inherit
+ 	 * database cluster's collation.
+ 	 */
+ 	if (lc_collate == NULL)
+ 		lc_collate = src_collation;
+ 	if (lc_ctype == NULL)
+ 		lc_ctype = src_ctype;
+ 
  	/*
  	 * Check for db name conflict.	This is just to give a more friendly error
  	 * message than "unique index violation".  There's a race condition but
***************
*** 421,426 **** createdb(const CreatedbStmt *stmt)
--- 479,486 ----
  		DirectFunctionCall1(namein, CStringGetDatum(dbname));
  	new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
  	new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
+ 	new_record[Anum_pg_database_collation - 1] = DirectFunctionCall1(namein, CStringGetDatum(lc_collate));
+ 	new_record[Anum_pg_database_ctype - 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_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
***************
*** 629,635 **** dropdb(const char *dbname, bool missing_ok)
  	pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 &db_istemplate, NULL, NULL, NULL, NULL))
  	{
  		if (!missing_ok)
  		{
--- 689,695 ----
  	pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 &db_istemplate, NULL, NULL, NULL, NULL, NULL, NULL))
  	{
  		if (!missing_ok)
  		{
***************
*** 781,787 **** RenameDatabase(const char *oldname, const char *newname)
  	rel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 NULL, NULL, NULL, NULL, NULL))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("database \"%s\" does not exist", oldname)));
--- 841,847 ----
  	rel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 NULL, NULL, NULL, NULL, NULL, NULL, NULL))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("database \"%s\" does not exist", oldname)));
***************
*** 1168,1174 **** get_db_info(const char *name, LOCKMODE lockmode,
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace)
  {
  	bool		result = false;
  	Relation	relation;
--- 1228,1234 ----
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace, char **dbCollation, char **dbCtype)
  {
  	bool		result = false;
  	Relation	relation;
***************
*** 1259,1264 **** get_db_info(const char *name, LOCKMODE lockmode,
--- 1319,1329 ----
  				/* default tablespace for this database */
  				if (dbTablespace)
  					*dbTablespace = dbform->dattablespace;
+  				/* default locale settings for this database */
+  				if (dbCollation)
+  					*dbCollation = pstrdup(NameStr(dbform->collation));
+  				if (dbCtype)
+  					*dbCtype = pstrdup(NameStr(dbform->ctype));
  				ReleaseSysCache(tuple);
  				result = true;
  				break;
*** src/backend/parser/gram.y
--- src/backend/parser/gram.y
***************
*** 398,404 **** static TypeName *TableFuncTypeName(List *columns);
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! 	CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
--- 398,404 ----
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! 	CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
***************
*** 5458,5463 **** createdb_opt_item:
--- 5458,5479 ----
  				{
  					$$ = makeDefElem("encoding", NULL);
  				}
+ 			| COLLATE opt_equal Sconst
+ 				{
+ 					$$ = makeDefElem("collate", (Node *)makeString($3));
+ 				}
+ 			| COLLATE opt_equal DEFAULT
+ 				{
+ 					$$ = makeDefElem("collate", NULL);
+ 				}
+ 			| CTYPE opt_equal Sconst
+ 				{
+ 					$$ = makeDefElem("ctype", (Node *)makeString($3));
+ 				}
+ 			| CTYPE opt_equal DEFAULT
+ 				{
+ 					$$ = makeDefElem("ctype", NULL);
+ 				}
  			| CONNECTION LIMIT opt_equal SignedIconst
  				{
  					$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
***************
*** 9216,9221 **** unreserved_keyword:
--- 9232,9238 ----
  			| CREATEROLE
  			| CREATEUSER
  			| CSV
+ 			| CTYPE
  			| CURRENT_P
  			| CURSOR
  			| CYCLE
*** src/backend/parser/keywords.c
--- src/backend/parser/keywords.c
***************
*** 114,119 **** const ScanKeyword ScanKeywords[] = {
--- 114,120 ----
  	{"createuser", CREATEUSER, UNRESERVED_KEYWORD},
  	{"cross", CROSS, TYPE_FUNC_NAME_KEYWORD},
  	{"csv", CSV, UNRESERVED_KEYWORD},
+ 	{"ctype", CTYPE, UNRESERVED_KEYWORD},
  	{"current", CURRENT_P, UNRESERVED_KEYWORD},
  	{"current_date", CURRENT_DATE, RESERVED_KEYWORD},
  	{"current_role", CURRENT_ROLE, RESERVED_KEYWORD},
*** src/backend/utils/adt/pg_locale.c
--- src/backend/utils/adt/pg_locale.c
***************
*** 228,233 **** locale_xxx_assign(int category, const char *value, bool doit, GucSource source)
--- 228,245 ----
  	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)
*** src/backend/utils/init/postinit.c
--- src/backend/utils/init/postinit.c
***************
*** 159,164 **** CheckMyDatabase(const char *name, bool am_superuser)
--- 159,166 ----
  {
  	HeapTuple	tup;
  	Form_pg_database dbform;
+ 	char	   *collate;
+ 	char	   *ctype;
  
  	/* Fetch our real pg_database row */
  	tup = SearchSysCache(DATABASEOID,
***************
*** 240,245 **** CheckMyDatabase(const char *name, bool am_superuser)
--- 242,270 ----
  	/* 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->collation);
+ 	ctype = NameStr(dbform->ctype);
+ 					
+ 	if (setlocale(LC_COLLATE, collate) == NULL)
+ 		ereport(FATAL, 
+ 			(errmsg("database local is incompatible with OS"),
+ 			errdetail("The database was initialized with LC_COLLATE \"%s\", "
+ 						" which is not recognized by setlocale().", collate),
+ 			errhint("Try to recreate the database or install locale support.")));
+ 			
+ 	if (setlocale(LC_CTYPE, ctype) == NULL)
+ 		ereport(FATAL, 
+ 			(errmsg("database local is incompatible with OS"),
+ 			errdetail("The database was initialized with LC_CTYPE \"%s\", "
+ 						" which is not recognized by setlocale().", ctype),
+ 			errhint("Try to recreate the database or install locale support.")));
+ 			
+ 	/* Record it as a GUC internal option, too */
+ 	
+ 	SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_DATABASE);
+ 	SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_DATABASE);
  
  	/*
  	 * Lastly, set up any database-specific configuration variables.
*** src/bin/initdb/initdb.c
--- src/bin/initdb/initdb.c
***************
*** 1171,1176 **** setup_config(void)
--- 1171,1184 ----
  	conflines = replace_token(conflines, "#port = 5432", repltok);
  #endif
  
+ 	snprintf(repltok, sizeof(repltok), "lc_collate = '%s'",
+ 			 escape_quotes(lc_collate));
+ 	conflines = replace_token(conflines, "#lc_collate = 'C'", repltok);
+ 	
+ 	snprintf(repltok, sizeof(repltok), "lc_ctype = '%s'",
+ 			 escape_quotes(lc_collate));
+ 	conflines = replace_token(conflines, "#lc_ctype = 'C'", repltok);
+ 
  	snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
  			 escape_quotes(lc_messages));
  	conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);
***************
*** 1353,1358 **** bootstrap_template1(char *short_version)
--- 1361,1370 ----
  
  	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.
  	 *
***************
*** 2806,2815 **** main(int argc, char *argv[])
  		strcmp(lc_ctype, lc_numeric) == 0 &&
  		strcmp(lc_ctype, lc_monetary) == 0 &&
  		strcmp(lc_ctype, lc_messages) == 0)
! 		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"
--- 2818,2827 ----
  		strcmp(lc_ctype, lc_numeric) == 0 &&
  		strcmp(lc_ctype, lc_monetary) == 0 &&
  		strcmp(lc_ctype, lc_messages) == 0)
! 		printf(_("The database template1 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"
*** src/bin/pg_controldata/pg_controldata.c
--- src/bin/pg_controldata/pg_controldata.c
***************
*** 220,231 **** main(int argc, char *argv[])
  		   (ControlFile.float4ByVal ? _("by value") : _("by reference")));
  	printf(_("Float8 argument passing:              %s\n"),
  		   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
- 	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;
  }
--- 220,224 ----
*** src/bin/pg_resetxlog/pg_resetxlog.c
--- src/bin/pg_resetxlog/pg_resetxlog.c
***************
*** 493,514 **** GuessControlValues(void)
  #endif
  	ControlFile.float4ByVal = FLOAT4PASSBYVAL;
  	ControlFile.float8ByVal = FLOAT8PASSBYVAL;
- 	ControlFile.localeBuflen = LOCALE_NAME_BUFLEN;
- 
- 	localeptr = setlocale(LC_COLLATE, "");
- 	if (!localeptr)
- 	{
- 		fprintf(stderr, _("%s: invalid LC_COLLATE setting\n"), progname);
- 		exit(1);
- 	}
- 	strlcpy(ControlFile.lc_collate, localeptr, sizeof(ControlFile.lc_collate));
- 	localeptr = setlocale(LC_CTYPE, "");
- 	if (!localeptr)
- 	{
- 		fprintf(stderr, _("%s: invalid LC_CTYPE setting\n"), progname);
- 		exit(1);
- 	}
- 	strlcpy(ControlFile.lc_ctype, localeptr, sizeof(ControlFile.lc_ctype));
  
  	/*
  	 * XXX eventually, should try to grovel through old XLOG to develop more
--- 493,498 ----
***************
*** 584,595 **** PrintControlValues(bool guessed)
  		   (ControlFile.float4ByVal ? _("by value") : _("by reference")));
  	printf(_("Float8 argument passing:              %s\n"),
  		   (ControlFile.float8ByVal ? _("by value") : _("by reference")));
- 	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);
  }
  
  
--- 568,573 ----
*** src/bin/scripts/createdb.c
--- src/bin/scripts/createdb.c
***************
*** 32,37 **** main(int argc, char *argv[])
--- 32,39 ----
  		{"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}
  	};
  
***************
*** 50,55 **** main(int argc, char *argv[])
--- 52,59 ----
  	char	   *tablespace = NULL;
  	char	   *template = NULL;
  	char	   *encoding = NULL;
+ 	char	   *lc_collate = NULL;
+ 	char	   *lc_ctype = NULL;
  
  	PQExpBufferData sql;
  
***************
*** 95,100 **** main(int argc, char *argv[])
--- 99,110 ----
  			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);
***************
*** 152,159 **** main(int argc, char *argv[])
  		appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
  	if (template)
  		appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
  	appendPQExpBuffer(&sql, ";\n");
! 
  	conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
  						   host, port, username, password, progname);
  
--- 162,174 ----
  		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(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
  						   host, port, username, password, progname);
  
***************
*** 207,224 **** help(const char *progname)
  	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(_("  --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               force password prompt\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"));
  }
--- 222,240 ----
  	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	locale 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(_("  --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               	force password prompt\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"));
  }
*** src/include/catalog/pg_control.h
--- src/include/catalog/pg_control.h
***************
*** 144,154 **** typedef struct ControlFileData
  	bool		float4ByVal;	/* float4 pass-by-value? */
  	bool		float8ByVal;	/* float8, int8, etc pass-by-value? */
  
- 	/* active locales */
- 	uint32		localeBuflen;
- 	char		lc_collate[LOCALE_NAME_BUFLEN];
- 	char		lc_ctype[LOCALE_NAME_BUFLEN];
- 
  	/* CRC of all above ... MUST BE LAST! */
  	pg_crc32	crc;
  } ControlFileData;
--- 144,149 ----
*** src/include/catalog/pg_database.h
--- src/include/catalog/pg_database.h
***************
*** 33,38 **** CATALOG(pg_database,1262) BKI_SHARED_RELATION
--- 33,40 ----
  	NameData	datname;		/* database name */
  	Oid			datdba;			/* owner of database */
  	int4		encoding;		/* character encoding */
+ 	NameData	collation;		/* LC_COLLATE of database */
+ 	NameData	ctype;			/* LC_CTYPE of database */
  	bool		datistemplate;	/* allowed as CREATE DATABASE template? */
  	bool		datallowconn;	/* new connections allowed? */
  	int4		datconnlimit;	/* max connections allowed (-1=no limit) */
***************
*** 54,73 **** typedef FormData_pg_database *Form_pg_database;
   *		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_datconnlimit	6
! #define Anum_pg_database_datlastsysoid	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 -1 0 0 1663 _null_ _null_ ));
  SHDESCR("default template database");
  #define TemplateDbOid			1
  
--- 56,77 ----
   *		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_collation		4
! #define Anum_pg_database_ctype			5
! #define Anum_pg_database_datistemplate	6
! #define Anum_pg_database_datallowconn	7
! #define Anum_pg_database_datconnlimit	8
! #define Anum_pg_database_datlastsysoid	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_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_ _null_));
  SHDESCR("default template database");
  #define TemplateDbOid			1
  
*** src/interfaces/ecpg/preproc/preproc.y
--- src/interfaces/ecpg/preproc/preproc.y
***************
*** 428,434 **** add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enu
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! 	CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
--- 428,434 ----
  	CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
  	COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
  	CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
! 	CREATEROLE CREATEUSER CROSS CSV CTYPE CURRENT_P CURRENT_DATE CURRENT_ROLE
  	CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
  
  	DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
