Index: backend/parser/keywords.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.199
diff -c -r1.199 keywords.c
*** backend/parser/keywords.c	16 Jul 2008 01:30:22 -0000	1.199
--- backend/parser/keywords.c	31 Aug 2008 19:21:08 -0000
***************
*** 45,50 ****
--- 45,51 ----
  	/* name, value, category */
  	{"abort", ABORT_P, UNRESERVED_KEYWORD},
  	{"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD},
+ 	{"accent", ACCENT, UNRESERVED_KEYWORD},
  	{"access", ACCESS, UNRESERVED_KEYWORD},
  	{"action", ACTION, UNRESERVED_KEYWORD},
  	{"add", ADD_P, UNRESERVED_KEYWORD},
***************
*** 94,99 ****
--- 95,101 ----
  	{"cluster", CLUSTER, UNRESERVED_KEYWORD},
  	{"coalesce", COALESCE, COL_NAME_KEYWORD},
  	{"collate", COLLATE, RESERVED_KEYWORD},
+ 	{"collation", COLLATION, UNRESERVED_KEYWORD},
  	{"column", COLUMN, RESERVED_KEYWORD},
  	{"comment", COMMENT, UNRESERVED_KEYWORD},
  	{"commit", COMMIT, UNRESERVED_KEYWORD},
***************
*** 220,225 ****
--- 222,229 ----
  	{"language", LANGUAGE, UNRESERVED_KEYWORD},
  	{"large", LARGE_P, UNRESERVED_KEYWORD},
  	{"last", LAST_P, UNRESERVED_KEYWORD},
+ 	{"lccollate", LCCOLLATE, UNRESERVED_KEYWORD},
+ 	{"lcctype", LCCTYPE, UNRESERVED_KEYWORD},
  	{"leading", LEADING, RESERVED_KEYWORD},
  	{"least", LEAST, COL_NAME_KEYWORD},
  	{"left", LEFT, TYPE_FUNC_NAME_KEYWORD},
***************
*** 284,289 ****
--- 288,294 ----
  	{"overlay", OVERLAY, COL_NAME_KEYWORD},
  	{"owned", OWNED, UNRESERVED_KEYWORD},
  	{"owner", OWNER, UNRESERVED_KEYWORD},
+ 	{"pad", PAD, UNRESERVED_KEYWORD},
  	{"parser", PARSER, UNRESERVED_KEYWORD},
  	{"partial", PARTIAL, UNRESERVED_KEYWORD},
  	{"password", PASSWORD, UNRESERVED_KEYWORD},
***************
*** 331,336 ****
--- 336,342 ----
  	{"second", SECOND_P, UNRESERVED_KEYWORD},
  	{"security", SECURITY, UNRESERVED_KEYWORD},
  	{"select", SELECT, RESERVED_KEYWORD},
+ 	{"sensitive", SENSITIVE, UNRESERVED_KEYWORD},
  	{"sequence", SEQUENCE, UNRESERVED_KEYWORD},
  	{"serializable", SERIALIZABLE, UNRESERVED_KEYWORD},
  	{"session", SESSION, UNRESERVED_KEYWORD},
***************
*** 343,348 ****
--- 349,355 ----
  	{"simple", SIMPLE, UNRESERVED_KEYWORD},
  	{"smallint", SMALLINT, COL_NAME_KEYWORD},
  	{"some", SOME, RESERVED_KEYWORD},
+ 	{"space", SPACE, UNRESERVED_KEYWORD},
  	{"stable", STABLE, UNRESERVED_KEYWORD},
  	{"standalone", STANDALONE_P, UNRESERVED_KEYWORD},
  	{"start", START, UNRESERVED_KEYWORD},
***************
*** 351,356 ****
--- 358,364 ----
  	{"stdin", STDIN, UNRESERVED_KEYWORD},
  	{"stdout", STDOUT, UNRESERVED_KEYWORD},
  	{"storage", STORAGE, UNRESERVED_KEYWORD},
+ 	{"strcolfn", STRCOLFN, UNRESERVED_KEYWORD},
  	{"strict", STRICT_P, UNRESERVED_KEYWORD},
  	{"strip", STRIP_P, UNRESERVED_KEYWORD},
  	{"substring", SUBSTRING, COL_NAME_KEYWORD},
Index: backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.618
diff -c -r2.618 gram.y
*** backend/parser/gram.y	18 Jul 2008 03:32:52 -0000	2.618
--- backend/parser/gram.y	31 Aug 2008 19:21:08 -0000
***************
*** 155,174 ****
  }
  
  %type <node>	stmt schema_stmt
! 		AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt
! 		AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
! 		AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt
! 		AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
! 		ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
! 		CreateDomainStmt CreateGroupStmt CreateOpClassStmt
! 		CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
  		CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
  		CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
! 		CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt
! 		DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
! 		DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
! 		DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
! 		GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
  		LockStmt NotifyStmt ExplainableStmt PreparableStmt
  		CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
  		RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
--- 155,173 ----
  }
  
  %type <node>	stmt schema_stmt
! 		AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt 
! 		AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt 
! 		AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt AnalyzeStmt 
! 		ClosePortalStmt ClusterStmt CommentStmt	ConstraintsSetStmt CopyStmt 
! 		CreateAsStmt CreateCastStmt	CreateCollationStmt CreateDomainStmt 
! 		CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
  		CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
  		CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
! 		CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt 
! 		DropCollationStmt DropGroupStmt DropOpClassStmt DropOpFamilyStmt 
! 		DropPLangStmt DropStmt DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt 
! 		DropRoleStmt DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt 
! 		FetchStmt GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
  		LockStmt NotifyStmt ExplainableStmt PreparableStmt
  		CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
  		RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
***************
*** 296,301 ****
--- 295,303 ----
  %type <list>	OptSeqOptList SeqOptList
  %type <defelt>	SeqOptElem
  
+ %type <list>	OptCollationList
+ %type <defelt>	OptCollationElem
+ 
  %type <istmt>	insert_rest
  
  %type <vsetstmt> set_rest SetResetClause
***************
*** 372,378 ****
   */
  
  /* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
  	AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
  	ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
  
--- 374,380 ----
   */
  
  /* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCENT ACCESS ACTION ADD_P ADMIN AFTER
  	AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
  	ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
  
***************
*** 381,387 ****
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	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
--- 383,389 ----
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	CLUSTER COALESCE COLLATE COLLATION 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
***************
*** 401,416 ****
  
  	HANDLER HAVING HEADER_P HOLD HOUR_P
  
! 	IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
! 	INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
! 	INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
! 	INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
  
  	JOIN
  
  	KEY
  
! 	LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
  	LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
  	LOCK_P LOGIN_P
  
--- 403,418 ----
  
  	HANDLER HAVING HEADER_P HOLD HOUR_P
  
! 	IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
! 	INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
! 	INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
! 	INTERVAL INTO INVOKER IS ISNULL ISOLATION
  
  	JOIN
  
  	KEY
  
! 	LANCOMPILER LANGUAGE LARGE_P LAST_P LCCOLLATE LCCTYPE LEADING LEAST LEFT LEVEL
  	LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
  	LOCK_P LOGIN_P
  
***************
*** 423,429 ****
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
  	ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
  
! 	PARSER PARTIAL PASSWORD PLACING PLANS POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
--- 425,431 ----
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
  	ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
  
! 	PAD PARSER PARTIAL PASSWORD PLACING PLANS POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
***************
*** 433,443 ****
  	REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
  	RIGHT ROLE ROLLBACK ROW ROWS RULE
  
! 	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
! 	SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! 	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
! 	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
  	TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
--- 435,445 ----
  	REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
  	RIGHT ROLE ROLLBACK ROW ROWS RULE
  
! 	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SENSITIVE
! 	SEQUENCE SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! 	SHOW SIMILAR SIMPLE SMALLINT SOME SPACE STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STRCOLFN STRICT_P STRIP_P SUBSTRING 
! 	SUPERUSER_P	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
  	TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
***************
*** 559,564 ****
--- 561,567 ----
  			| CreateAsStmt
  			| CreateAssertStmt
  			| CreateCastStmt
+ 			| CreateCollationStmt
  			| CreateConversionStmt
  			| CreateDomainStmt
  			| CreateFunctionStmt
***************
*** 582,587 ****
--- 585,591 ----
  			| DiscardStmt
  			| DropAssertStmt
  			| DropCastStmt
+ 			| DropCollationStmt
  			| DropGroupStmt
  			| DropOpClassStmt
  			| DropOpFamilyStmt
***************
*** 2421,2426 ****
--- 2425,2508 ----
  				}
  		;
  
+ /*****************************************************************************
+  *
+  *		QUERY :
+  *
+  * CREATE COLLATION <collation name> FOR <character set specification> 
+  * 		FROM <existing collation name> [STRCOLFN <fn name>] 
+  *		[ <pad characteristic> ] [ <case sensitive> ] [ <accent sensitive> ] 
+  *		[ LCCOLLATE <lc_collate> ] [ LCCTYPE <lc_ctype> ]
+  *
+  * DROP COLLATION <collation name>
+  *
+  *****************************************************************************/
+ 
+ CreateCollationStmt:
+ 			CREATE COLLATION name FOR name FROM name OptCollationList
+ 				{
+ 					CreateCollationStmt *n = makeNode(CreateCollationStmt);
+ 					n->name = $3;
+ 					n->for_charset = $5;
+ 					n->parent_collation = $7;
+ 					n->options = $8;
+ 					$$ = (Node *)n;
+ 				}
+ 		;
+ 
+ OptCollationList: 
+ 			OptCollationList OptCollationElem		{ $$ = lappend($1, $2); }
+ 			| /*EMPTY*/								{ $$ = NIL; }
+ 		;
+ 
+ OptCollationElem:
+ 			NO PAD
+ 				{
+ 					$$ = makeDefElem("pad_characteristic", (Node *)makeInteger(FALSE));				
+ 				}
+ 			| PAD SPACE
+ 				{
+ 					$$ = makeDefElem("pad_characteristic", (Node *)makeInteger(TRUE));				
+ 				}
+ 			| CASE SENSITIVE
+ 				{
+ 					$$ = makeDefElem("case_sensitive", (Node *)makeInteger(TRUE));				
+ 				}
+ 			| CASE INSENSITIVE
+ 				{
+ 					$$ = makeDefElem("case_sensitive", (Node *)makeInteger(FALSE));								
+ 				}
+ 			| ACCENT SENSITIVE
+ 				{
+ 					$$ = makeDefElem("accent_sensitive", (Node *)makeInteger(TRUE));								
+ 				}
+ 			| ACCENT INSENSITIVE
+ 				{
+ 					$$ = makeDefElem("accent_sensitive", (Node *)makeInteger(FALSE));								
+ 				}
+ 			| LCCOLLATE name
+ 				{
+ 					$$ = makeDefElem("lc_collate_name", (Node *)makeString($2));				
+ 				}
+ 			| LCCTYPE name
+ 				{
+ 					$$ = makeDefElem("lc_ctype_name", (Node *)makeString($2));				
+ 				}
+ 			| STRCOLFN name
+ 				{
+ 					$$ = makeDefElem("str_col_function", (Node *)makeInteger(1));				
+ 				}
+ 		;
+ 
+ DropCollationStmt:
+ 			DROP COLLATION name
+ 				{
+ 					DropCollationStmt *n = makeNode(DropCollationStmt);
+ 					n->name = $3;
+ 					$$ = (Node *)n;
+ 				}
+ 		;
+ 
  
  /*****************************************************************************
   *
***************
*** 5432,5437 ****
--- 5514,5527 ----
  				{
  					$$ = makeDefElem("encoding", NULL);
  				}
+ 			| COLLATE opt_equal name
+ 				{
+ 					$$ = makeDefElem("collate", (Node *)makeString($3));
+ 				}
+ 			| COLLATE opt_equal DEFAULT
+ 				{
+ 					$$ = makeDefElem("collate", NULL);
+ 				}
  			| CONNECTION LIMIT opt_equal SignedIconst
  				{
  					$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
***************
*** 9044,9049 ****
--- 9134,9140 ----
  unreserved_keyword:
  			  ABORT_P
  			| ABSOLUTE_P
+ 			| ACCENT
  			| ACCESS
  			| ACTION
  			| ADD_P
***************
*** 9070,9075 ****
--- 9161,9167 ----
  			| CLASS
  			| CLOSE
  			| CLUSTER
+ 			| COLLATION
  			| COMMENT
  			| COMMIT
  			| COMMITTED
***************
*** 9151,9156 ****
--- 9243,9250 ----
  			| LANGUAGE
  			| LARGE_P
  			| LAST_P
+ 			| LCCOLLATE
+ 			| LCCTYPE
  			| LEVEL
  			| LISTEN
  			| LOAD
***************
*** 9187,9192 ****
--- 9281,9287 ----
  			| OPTION
  			| OWNED
  			| OWNER
+ 			| PAD
  			| PARSER
  			| PARTIAL
  			| PASSWORD
***************
*** 9224,9229 ****
--- 9319,9325 ----
  			| SEARCH
  			| SECOND_P
  			| SECURITY
+ 			| SENSITIVE
  			| SEQUENCE
  			| SERIALIZABLE
  			| SESSION
***************
*** 9231,9236 ****
--- 9327,9333 ----
  			| SHARE
  			| SHOW
  			| SIMPLE
+ 			| SPACE
  			| STABLE
  			| STANDALONE_P
  			| START
***************
*** 9239,9244 ****
--- 9336,9342 ----
  			| STDIN
  			| STDOUT
  			| STORAGE
+ 			| STRCOLFN
  			| STRICT_P
  			| STRIP_P
  			| SUPERUSER_P
Index: backend/utils/cache/syscache.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/syscache.c,v
retrieving revision 1.117
diff -c -r1.117 syscache.c
*** backend/utils/cache/syscache.c	19 Jun 2008 00:46:05 -0000	1.117
--- backend/utils/cache/syscache.c	31 Aug 2008 19:21:08 -0000
***************
*** 28,33 ****
--- 28,35 ----
  #include "catalog/pg_auth_members.h"
  #include "catalog/pg_authid.h"
  #include "catalog/pg_cast.h"
+ #include "catalog/pg_charset.h"
+ #include "catalog/pg_collation.h"
  #include "catalog/pg_constraint.h"
  #include "catalog/pg_conversion.h"
  #include "catalog/pg_database.h"
***************
*** 257,262 ****
--- 259,288 ----
  		},
  		256
  	},
+ 	{CharsetRelationId,	/* CHARSETNAME */
+ 		CharsetNameIndexId,
+ 		0,
+ 		1,
+ 		{
+ 			Anum_pg_charset_charsetname,
+ 			0,
+ 			0,
+ 			0
+ 		},
+ 		64
+ 	},
+ 	{CharsetRelationId,	/* CHARSETOID */
+ 		CharsetOidIndexId,
+ 		0,
+ 		1,
+ 		{
+ 			ObjectIdAttributeNumber,
+ 			0,
+ 			0,
+ 			0
+ 		},
+ 		64
+ 	},
  	{OperatorClassRelationId,	/* CLAAMNAMENSP */
  		OpclassAmNameNspIndexId,
  		0,
***************
*** 281,286 ****
--- 307,336 ----
  		},
  		64
  	},
+ 	{CollationRelationId,			/* COLLNAME */
+ 		CollationNameIndexId,
+ 		0,
+ 		1,
+ 		{
+ 			Anum_pg_collation_colname,
+ 			0,
+ 			0,
+ 			0
+ 		},
+ 		64
+ 	},
+ 	{CollationRelationId,			/* COLLOID */
+ 		CollationOidIndexId,
+ 		0,
+ 		1,
+ 		{
+ 			ObjectIdAttributeNumber,
+ 			0,
+ 			0,
+ 			0
+ 		},
+ 		64
+ 	},
  	{ConversionRelationId,		/* CONDEFAULT */
  		ConversionDefaultIndexId,
  		0,
Index: include/utils/pg_locale.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/pg_locale.h,v
retrieving revision 1.25
diff -c -r1.25 pg_locale.h
*** include/utils/pg_locale.h	19 May 2008 18:08:16 -0000	1.25
--- include/utils/pg_locale.h	31 Aug 2008 19:21:10 -0000
***************
*** 30,35 ****
--- 30,39 ----
  extern char *localized_full_months[];
  
  
+ 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,
Index: include/utils/syscache.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/syscache.h,v
retrieving revision 1.72
diff -c -r1.72 syscache.h
*** include/utils/syscache.h	7 May 2008 01:04:49 -0000	1.72
--- include/utils/syscache.h	31 Aug 2008 19:21:10 -0000
***************
*** 42,49 ****
--- 42,53 ----
  	AUTHNAME,
  	AUTHOID,
  	CASTSOURCETARGET,
+ 	CHARSETNAME,
+ 	CHARSETOID,
  	CLAAMNAMENSP,
  	CLAOID,
+ 	COLLNAME,
+ 	COLLOID,
  	CONDEFAULT,
  	CONNAMENSP,
  	CONSTROID,
Index: interfaces/ecpg/preproc/preproc.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/ecpg/preproc/preproc.y,v
retrieving revision 1.371
diff -c -r1.371 preproc.y
*** interfaces/ecpg/preproc/preproc.y	20 Aug 2008 14:09:16 -0000	1.371
--- interfaces/ecpg/preproc/preproc.y	31 Aug 2008 19:21:10 -0000
***************
*** 416,422 ****
  %token	TYPECAST
  
  /* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
  	AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
  	ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
  
--- 416,422 ----
  %token	TYPECAST
  
  /* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCENT ACCESS ACTION ADD_P ADMIN AFTER
  	AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
  	ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
  
***************
*** 425,431 ****
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	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
--- 425,431 ----
  
  	CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
  	CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! 	CLUSTER COALESCE COLLATE COLLATION 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
***************
*** 454,462 ****
  
  	KEY
  
! 	LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
! 	LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
! 	LOCK_P LOGIN_P
  
  	MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
--- 454,462 ----
  
  	KEY
  
! 	LANCOMPILER LANGUAGE LARGE_P LAST_P LCCOLLATE LCCTYPE LEADING LEAST 
! 	LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP 
! 	LOCATION LOCK_P LOGIN_P
  
  	MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
  
***************
*** 467,473 ****
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
  	OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
  
! 	PARSER PARTIAL PASSWORD PLACING PLANS POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
--- 467,473 ----
  	OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
  	OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
  
! 	PAD PARSER PARTIAL PASSWORD PLACING PLANS POSITION
  	PRECISION PRESERVE PREPARE PREPARED PRIMARY
  	PRIOR PRIVILEGES PROCEDURAL PROCEDURE
  
***************
*** 477,487 ****
  	REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
  	RIGHT ROLE ROLLBACK ROW ROWS RULE
  
! 	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
  	SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! 	SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
! 	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO 
  	TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
--- 477,487 ----
  	REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
  	RIGHT ROLE ROLLBACK ROW ROWS RULE
  
! 	SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SENSITIVE SEQUENCE
  	SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! 	SHOW SIMILAR SIMPLE SMALLINT SOME SPACE STABLE STANDALONE_P START STATEMENT
! 	STATISTICS STDIN STDOUT STORAGE STRCOLFN STRICT_P STRIP_P SUBSTRING 
! 	SUPERUSER_P	SYMMETRIC SYSID SYSTEM_P
  
  	TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO 
  	TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
Index: bin/psql/tab-complete.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.171
diff -c -r1.171 tab-complete.c
*** bin/psql/tab-complete.c	16 Aug 2008 01:36:35 -0000	1.171
--- bin/psql/tab-complete.c	31 Aug 2008 19:21:09 -0000
***************
*** 514,520 ****
  	{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
  	{"CAST", NULL, NULL},		/* Casts have complex structures for names, so
  								 * skip it */
! 
  	/*
  	 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
  	 * to be used only by pg_dump.
--- 514,520 ----
  	{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
  	{"CAST", NULL, NULL},		/* Casts have complex structures for names, so
  								 * skip it */
! 	{"COLLATION", NULL, NULL},	/* TODO eventually change */
  	/*
  	 * CREATE CONSTRAINT TRIGGER is not supported here because it is designed
  	 * to be used only by pg_dump.
***************
*** 1199,1205 ****
  			 pg_strcasecmp(prev2_wd, "DATABASE") == 0)
  	{
  		static const char *const list_DATABASE[] =
! 		{"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT",
  		NULL};
  
  		COMPLETE_WITH_LIST(list_DATABASE);
--- 1199,1205 ----
  			 pg_strcasecmp(prev2_wd, "DATABASE") == 0)
  	{
  		static const char *const list_DATABASE[] =
! 		{"OWNER", "TEMPLATE", "ENCODING", "LCCOLLATE", "LCCTYPE", "TABLESPACE", "CONNECTION LIMIT",
  		NULL};
  
  		COMPLETE_WITH_LIST(list_DATABASE);
***************
*** 1462,1468 ****
  
  	/* DROP object with CASCADE / RESTRICT */
  	else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 &&
! 			  (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
  			   pg_strcasecmp(prev2_wd, "DOMAIN") == 0 ||
  			   pg_strcasecmp(prev2_wd, "FUNCTION") == 0 ||
  			   pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
--- 1462,1469 ----
  
  	/* DROP object with CASCADE / RESTRICT */
  	else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 &&
! 			  (pg_strcasecmp(prev2_wd, "COLLATION") == 0 ||
! 			   pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
  			   pg_strcasecmp(prev2_wd, "DOMAIN") == 0 ||
  			   pg_strcasecmp(prev2_wd, "FUNCTION") == 0 ||
  			   pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
Index: bin/psql/describe.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.184
diff -c -r1.184 describe.c
*** bin/psql/describe.c	18 Jul 2008 04:20:24 -0000	1.184
--- bin/psql/describe.c	31 Aug 2008 19:21:09 -0000
***************
*** 462,467 ****
--- 462,476 ----
  					  gettext_noop("Access Privileges"));
  	if (verbose && pset.sversion >= 80200)
  		appendPQExpBuffer(&buf,
+ 			",\n       d.datcollate as \"%s\"",
+ 						 _("LC_COLLATE"));
+ 	if (verbose && pset.sversion >= 80200)
+ 		appendPQExpBuffer(&buf,
+ 			",\n       d.datctype as \"%s\"",
+ 						 _("LC_CTYPE"));
+ 	
+ 	if (verbose && pset.sversion >= 80200)
+ 		appendPQExpBuffer(&buf,
  						  ",\n       CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
  						  "            THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
  						  "            ELSE 'No Access'\n"
Index: backend/commands/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/Makefile,v
retrieving revision 1.38
diff -c -r1.38 Makefile
*** backend/commands/Makefile	19 Feb 2008 10:30:07 -0000	1.38
--- backend/commands/Makefile	31 Aug 2008 19:21:07 -0000
***************
*** 13,19 ****
  include $(top_builddir)/src/Makefile.global
  
  OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
! 	conversioncmds.o copy.o \
  	dbcommands.o define.o discard.o explain.o functioncmds.o \
  	indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
  	portalcmds.o prepare.o proclang.o \
--- 13,19 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o  \
! 	collation.o conversioncmds.o copy.o \
  	dbcommands.o define.o discard.o explain.o functioncmds.o \
  	indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
  	portalcmds.o prepare.o proclang.o \
Index: backend/commands/dbcommands.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.210
diff -c -r1.210 dbcommands.c
*** backend/commands/dbcommands.c	4 Aug 2008 18:03:46 -0000	1.210
--- backend/commands/dbcommands.c	31 Aug 2008 19:21:07 -0000
***************
*** 19,24 ****
--- 19,28 ----
   */
  #include "postgres.h"
  
+ #ifdef HAVE_LANGINFO_H
+ #include <langinfo.h>
+ #endif
+ 
  #include <fcntl.h>
  #include <locale.h>
  #include <unistd.h>
***************
*** 32,37 ****
--- 36,42 ----
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/pg_authid.h"
+ #include "catalog/pg_collation.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_tablespace.h"
  #include "commands/comment.h"
***************
*** 53,58 ****
--- 58,64 ----
  #include "utils/fmgroids.h"
  #include "utils/guc.h"
  #include "utils/lsyscache.h"
+ #include "utils/pg_locale.h"
  #include "utils/syscache.h"
  #include "utils/tqual.h"
  
***************
*** 69,75 ****
  			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);
--- 75,81 ----
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace, Oid *dbCollation);
  static bool have_createdb_privilege(void);
  static void remove_dbtablespaces(Oid db_id);
  static bool check_db_file_conflict(Oid db_id);
***************
*** 86,92 ****
--- 92,101 ----
  	Relation	rel;
  	Oid			src_dboid;
  	Oid			src_owner;
+ 	Oid			src_collationoid;
  	int			src_encoding;
+ 	char	   *src_collate;
+ 	char	   *src_ctype;
  	bool		src_istemplate;
  	bool		src_allowconn;
  	Oid			src_lastsysoid;
***************
*** 95,113 ****
--- 104,127 ----
  	volatile Oid dst_deftablespace;
  	Relation	pg_database_rel;
  	HeapTuple	tuple;
+ 	HeapTuple	coltuple;
  	Datum		new_record[Natts_pg_database];
  	char		new_record_nulls[Natts_pg_database];
  	Oid			dboid;
  	Oid			datdba;
+ 	Oid			datcollationoid;
  	ListCell   *option;
  	DefElem    *dtablespacename = NULL;
  	DefElem    *downer = NULL;
  	DefElem    *dtemplate = NULL;
  	DefElem    *dencoding = NULL;
+ 	DefElem	   *dcollation = 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 ****
--- 166,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, "connectionlimit") == 0)
  		{
  			if (dconnlimit)
***************
*** 205,210 ****
--- 227,256 ----
  			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) {
+ 		coltuple = SearchSysCache(COLLNAME,
+ 								CStringGetDatum(strVal(dcollation->arg)),
+ 								0, 0, 0);
+ 		if (!HeapTupleIsValid(coltuple))
+ 			ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 				errmsg("%s is not a valid COLLATION name",
+ 					strVal(dcollation->arg))));
+ 		datcollationoid = HeapTupleGetOid(coltuple);
+ 		ReleaseSysCache(coltuple);
+ 	}
+ 	
  	if (dconnlimit && dconnlimit->arg)
  		dbconnlimit = intVal(dconnlimit->arg);
  
***************
*** 243,249 ****
  	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",
--- 289,295 ----
  	if (!get_db_info(dbtemplate, ShareLock,
  					 &src_dboid, &src_owner, &src_encoding,
  					 &src_istemplate, &src_allowconn, &src_lastsysoid,
! 					 &src_frozenxid, &src_deftablespace, &src_collationoid))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("template database \"%s\" does not exist",
***************
*** 369,374 ****
--- 415,427 ----
  		/* Note there is no additional permission check in this path */
  	}
  
+ 	/*	
+ 	 * If collation is specified for database, use it, otherwise inherit database
+ 	 * cluster's collation.
+ 	 */
+ 	 datcollationoid = OidIsValid(datcollationoid) ? datcollationoid : src_collationoid;
+ 
+ 
  	/*
  	 * 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
***************
*** 414,419 ****
--- 467,473 ----
  	 */
  
  	/* Form tuple */
+ 
  	MemSet(new_record, 0, sizeof(new_record));
  	MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));
  
***************
*** 421,426 ****
--- 475,481 ----
  		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_datcollation - 1] = ObjectIdGetDatum(datcollationoid);
  	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);
***************
*** 583,588 ****
--- 638,659 ----
  		 * space but is not in pg_database, which is not good.
  		 */
  		database_file_update_needed();
+ 		
+ 		/*
+ 		 * Message about reindexing new database
+ 		 */
+ 		if (lc_collate != src_collate || lc_ctype != src_ctype)
+ 			ereport(NOTICE,
+ 					(errmsg("database \"%s\" need to be reindexed manually (REINDEX DATABASE)",
+ 							dbname)));		
+ 		
+ 		/* {
+ 		*	ereport(NOTICE,
+ 		*			(errmsg("database \"%s\" is reindexed automaticly",
+ 		*					dbname)));
+ 		*	ReindexDatabase(dbname, true, true);
+ 		*}
+ 		*/
  	}
  	PG_END_ENSURE_ERROR_CLEANUP(createdb_failure_callback,
  								PointerGetDatum(&fparms));
***************
*** 629,635 ****
  	pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 &db_istemplate, NULL, NULL, NULL, NULL))
  	{
  		if (!missing_ok)
  		{
--- 700,706 ----
  	pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 &db_istemplate, NULL, NULL, NULL, NULL, NULL))
  	{
  		if (!missing_ok)
  		{
***************
*** 781,787 ****
  	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)));
--- 852,858 ----
  	rel = heap_open(DatabaseRelationId, RowExclusiveLock);
  
  	if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
! 					 NULL, NULL, NULL, NULL, NULL, NULL))
  		ereport(ERROR,
  				(errcode(ERRCODE_UNDEFINED_DATABASE),
  				 errmsg("database \"%s\" does not exist", oldname)));
***************
*** 1168,1174 ****
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace)
  {
  	bool		result = false;
  	Relation	relation;
--- 1239,1245 ----
  			Oid *dbIdP, Oid *ownerIdP,
  			int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
  			Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! 			Oid *dbTablespace, Oid *dbCollation)
  {
  	bool		result = false;
  	Relation	relation;
***************
*** 1259,1264 ****
--- 1330,1338 ----
  				/* default tablespace for this database */
  				if (dbTablespace)
  					*dbTablespace = dbform->dattablespace;
+  				/* default locale settings for this database */
+  				if (dbCollation)
+  					*dbCollation = dbform->datcollation;
  				ReleaseSysCache(tuple);
  				result = true;
  				break;
Index: include/nodes/parsenodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.371
diff -c -r1.371 parsenodes.h
*** include/nodes/parsenodes.h	7 Aug 2008 01:11:51 -0000	1.371
--- include/nodes/parsenodes.h	31 Aug 2008 19:21:10 -0000
***************
*** 1224,1229 ****
--- 1224,1249 ----
  	bool		skip_validation;	/* skip validation of existing rows? */
  } FkConstraint;
  
+ /* ----------------------
+  *		Create/Drop Collation Statements
+  * ----------------------
+  */
+  
+ typedef struct CreateCollationStmt
+ {
+ 	NodeTag		type;	
+ 	char	   *name;
+ 	char	   *for_charset;
+ 	char	   *parent_collation;
+ 	List	   *options;
+ } CreateCollationStmt;
+ 
+ typedef struct DropCollationStmt
+ {
+ 	NodeTag		type;	
+ 	char	   *name;
+ 	
+ } DropCollationStmt;
  
  /* ----------------------
   *		Create/Drop Table Space Statements
Index: include/nodes/nodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/nodes.h,v
retrieving revision 1.209
diff -c -r1.209 nodes.h
*** include/nodes/nodes.h	22 Aug 2008 00:16:04 -0000	1.209
--- include/nodes/nodes.h	31 Aug 2008 19:21:09 -0000
***************
*** 315,320 ****
--- 315,322 ----
  	T_CreateEnumStmt,
  	T_AlterTSDictionaryStmt,
  	T_AlterTSConfigurationStmt,
+ 	T_CreateCollationStmt,
+ 	T_DropCollationStmt,
  
  	/*
  	 * TAGS FOR PARSE TREE NODES (parsenodes.h)
Index: backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.317
diff -c -r1.317 xlog.c
*** backend/access/transam/xlog.c	11 Aug 2008 11:05:10 -0000	1.317
--- backend/access/transam/xlog.c	31 Aug 2008 19:21:07 -0000
***************
*** 3832,3850 ****
  #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,
--- 3832,3838 ----
  #endif
  	ControlFile->float4ByVal = FLOAT4PASSBYVAL;
  	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
! 	
  	/* Contents are protected with a CRC */
  	INIT_CRC32(ControlFile->crc);
  	COMP_CRC32(ControlFile->crc,
***************
*** 4083,4116 ****
  						   " 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
--- 4071,4076 ----
Index: backend/catalog/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v
retrieving revision 1.66
diff -c -r1.66 Makefile
*** backend/catalog/Makefile	19 Feb 2008 10:30:07 -0000	1.66
--- backend/catalog/Makefile	31 Aug 2008 19:21:07 -0000
***************
*** 11,18 ****
  include $(top_builddir)/src/Makefile.global
  
  OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
!        pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o pg_enum.o \
!        pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
         pg_type.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
--- 11,18 ----
  include $(top_builddir)/src/Makefile.global
  
  OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
!        pg_aggregate.o pg_collation.o pg_charset.o pg_constraint.o pg_conversion.o pg_depend.o \
!        pg_enum.o pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
         pg_type.o toasting.o
  
  BKIFILES = postgres.bki postgres.description postgres.shdescription
***************
*** 27,34 ****
  
  POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
  	pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
! 	pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
! 	pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
  	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
--- 27,34 ----
  
  POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
  	pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
! 	pg_attrdef.h pg_charset.h pg_collation.h pg_constraint.h pg_inherits.h pg_index.h \
! 	pg_operator.h pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
  	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
  	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
  	pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
Index: backend/utils/adt/pg_locale.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
retrieving revision 1.41
diff -c -r1.41 pg_locale.c
*** backend/utils/adt/pg_locale.c	19 May 2008 18:08:16 -0000	1.41
--- backend/utils/adt/pg_locale.c	31 Aug 2008 19:21:08 -0000
***************
*** 228,233 ****
--- 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)
Index: include/catalog/pg_control.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_control.h,v
retrieving revision 1.41
diff -c -r1.41 pg_control.h
*** include/catalog/pg_control.h	21 Apr 2008 00:26:47 -0000	1.41
--- include/catalog/pg_control.h	31 Aug 2008 19:21:09 -0000
***************
*** 144,154 ****
  	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 ----
Index: include/catalog/pg_database.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_database.h,v
retrieving revision 1.47
diff -c -r1.47 pg_database.h
*** include/catalog/pg_database.h	27 Mar 2008 03:57:34 -0000	1.47
--- include/catalog/pg_database.h	31 Aug 2008 19:21:09 -0000
***************
*** 33,38 ****
--- 33,39 ----
  	NameData	datname;		/* database name */
  	Oid			datdba;			/* owner of database */
  	int4		encoding;		/* character encoding */
+ 	Oid			datcollation;	/* collation */
  	bool		datistemplate;	/* allowed as CREATE DATABASE template? */
  	bool		datallowconn;	/* new connections allowed? */
  	int4		datconnlimit;	/* max connections allowed (-1=no limit) */
***************
*** 54,73 ****
   *		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
  
--- 55,75 ----
   *		compiler constants for pg_database
   * ----------------
   */
! #define Natts_pg_database				12
  #define Anum_pg_database_datname		1
  #define Anum_pg_database_datdba			2
  #define Anum_pg_database_encoding		3
! #define Anum_pg_database_datcollation	4
! #define Anum_pg_database_datistemplate	5
! #define Anum_pg_database_datallowconn	6
! #define Anum_pg_database_datconnlimit	7
! #define Anum_pg_database_datlastsysoid	8
! #define Anum_pg_database_datfrozenxid	9
! #define Anum_pg_database_dattablespace	10
! #define Anum_pg_database_datconfig		11
! #define Anum_pg_database_datacl			12
  
! DATA(insert OID = 1 (  template1 PGUID ENCODING 2988 t t -1 0 0 1663 _null_ _null_ ));
  SHDESCR("default template database");
  #define TemplateDbOid			1
  
Index: include/catalog/indexing.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/indexing.h,v
retrieving revision 1.103
diff -c -r1.103 indexing.h
*** include/catalog/indexing.h	19 Jun 2008 00:46:06 -0000	1.103
--- include/catalog/indexing.h	31 Aug 2008 19:21:09 -0000
***************
*** 105,115 ****
--- 105,125 ----
  DECLARE_UNIQUE_INDEX(pg_cast_source_target_index, 2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops));
  #define CastSourceTargetIndexId  2661
  
+ DECLARE_UNIQUE_INDEX(pg_charset_name_index, 2179, on pg_charset using btree(charsetname name_ops));
+ #define	CharsetNameIndexId 2179
+ DECLARE_UNIQUE_INDEX(pg_charset_oid_index, 2316, on pg_charset using btree(oid oid_ops));
+ #define CharsetOidIndexId 2316
+ 
  DECLARE_UNIQUE_INDEX(pg_class_oid_index, 2662, on pg_class using btree(oid oid_ops));
  #define ClassOidIndexId  2662
  DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index, 2663, on pg_class using btree(relname name_ops, relnamespace oid_ops));
  #define ClassNameNspIndexId  2663
  
+ DECLARE_UNIQUE_INDEX(pg_collation_name_index, 2181, on pg_collation using btree(colname name_ops)); 
+ #define	CollationNameIndexId 2181
+ DECLARE_UNIQUE_INDEX(pg_collation_oid_index, 2232, on pg_collation using btree(oid oid_ops));
+ #define CollationOidIndexId 2232
+ 
  /* This following index is not used for a cache and is not unique */
  DECLARE_INDEX(pg_constraint_conname_nsp_index, 2664, on pg_constraint using btree(conname name_ops, connamespace oid_ops));
  #define ConstraintNameNspIndexId  2664
Index: backend/utils/init/postinit.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/init/postinit.c,v
retrieving revision 1.184
diff -c -r1.184 postinit.c
*** backend/utils/init/postinit.c	12 May 2008 00:00:52 -0000	1.184
--- backend/utils/init/postinit.c	31 Aug 2008 19:21:08 -0000
***************
*** 23,28 ****
--- 23,30 ----
  #include "catalog/catalog.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_authid.h"
+ #include "catalog/pg_collation.h"
+ #include "catalog/pg_charset.h"
  #include "catalog/pg_database.h"
  #include "catalog/pg_tablespace.h"
  #include "libpq/hba.h"
***************
*** 156,164 ****
  static void
  CheckMyDatabase(const char *name, bool am_superuser)
  {
! 	HeapTuple	tup;
! 	Form_pg_database dbform;
! 
  	/* Fetch our real pg_database row */
  	tup = SearchSysCache(DATABASEOID,
  						 ObjectIdGetDatum(MyDatabaseId),
--- 158,173 ----
  static void
  CheckMyDatabase(const char *name, bool am_superuser)
  {
! 	HeapTuple			tup;
! 	HeapTuple			localetup;
! 	Form_pg_database 	dbform;
! 	Form_pg_charset 	dbcharset;
! 	Form_pg_collation 	dbcollation;
! 	Oid					collationoid;
! 	Oid					charsetoid;
! 	char 	   		   *collate;
! 	char 	   		   *ctype;
! 	
  	/* Fetch our real pg_database row */
  	tup = SearchSysCache(DATABASEOID,
  						 ObjectIdGetDatum(MyDatabaseId),
***************
*** 239,244 ****
--- 248,295 ----
  	/* If we have no other source of client_encoding, use server encoding */
  	SetConfigOption("client_encoding", GetDatabaseEncodingName(),
  					PGC_BACKEND, PGC_S_DEFAULT);
+ 	/* Get database collation oid */
+ 	collationoid = dbform->datcollation;
+ 	/* Fetch pg_collation record */
+ 	localetup = SearchSysCache(COLLOID,
+ 						 ObjectIdGetDatum(collationoid),
+ 						 0, 0, 0);
+ 	if (!HeapTupleIsValid(localetup))
+ 		elog(ERROR, "cache lookup failed for collation %u", collationoid);
+ 	dbcollation = (Form_pg_collation) GETSTRUCT(localetup);
+ 	ReleaseSysCache(localetup);	
+ 	/* Fetch pg_charset record */
+ 	charsetoid = dbcollation->colcharset;
+ 	localetup = SearchSysCache(CHARSETOID,
+ 						 ObjectIdGetDatum(charsetoid),
+ 						 0, 0, 0);
+ 	if (!HeapTupleIsValid(tup))
+ 		elog(ERROR, "cache lookup failed for charset %u", charsetoid);
+ 	dbcharset = (Form_pg_charset) GETSTRUCT(localetup);
+ 	ReleaseSysCache(localetup);	
+ 	
+ 	/* assign locale variables */ 
+ 	collate = NameStr(dbcollation->colcollate);
+ 	ctype = NameStr(dbcharset->charsettype);
+ 					
+ 	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.
Index: bin/initdb/initdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.159
diff -c -r1.159 initdb.c
*** bin/initdb/initdb.c	5 Aug 2008 12:09:30 -0000	1.159
--- bin/initdb/initdb.c	31 Aug 2008 19:21:08 -0000
***************
*** 1171,1176 ****
--- 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 ****
--- 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 ****
  		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"
Index: bin/scripts/createdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/createdb.c,v
retrieving revision 1.26
diff -c -r1.26 createdb.c
*** bin/scripts/createdb.c	1 Jan 2008 19:45:56 -0000	1.26
--- bin/scripts/createdb.c	31 Aug 2008 19:21:09 -0000
***************
*** 32,37 ****
--- 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 ****
--- 52,59 ----
  	char	   *tablespace = NULL;
  	char	   *template = NULL;
  	char	   *encoding = NULL;
+ 	char	   *lc_collate = NULL;
+ 	char	   *lc_ctype = NULL;
  
  	PQExpBufferData sql;
  
***************
*** 95,100 ****
--- 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 ****
  		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 ****
  	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"));
  }
Index: bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.39
diff -c -r1.39 pg_controldata.c
*** bin/pg_controldata/pg_controldata.c	21 Apr 2008 00:26:46 -0000	1.39
--- bin/pg_controldata/pg_controldata.c	31 Aug 2008 19:21:08 -0000
***************
*** 220,231 ****
  		   (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 ----
Index: backend/tcop/utility.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.296
diff -c -r1.296 utility.c
*** backend/tcop/utility.c	13 Aug 2008 00:07:50 -0000	1.296
--- backend/tcop/utility.c	31 Aug 2008 19:21:08 -0000
***************
*** 24,29 ****
--- 24,30 ----
  #include "commands/alter.h"
  #include "commands/async.h"
  #include "commands/cluster.h"
+ #include "commands/collation.h"
  #include "commands/comment.h"
  #include "commands/conversioncmds.h"
  #include "commands/copy.h"
***************
*** 166,171 ****
--- 167,173 ----
  		case T_CommentStmt:
  		case T_DefineStmt:
  		case T_CreateCastStmt:
+ 		case T_CreateCollationStmt:
  		case T_CreateConversionStmt:
  		case T_CreatedbStmt:
  		case T_CreateDomainStmt:
***************
*** 1023,1028 ****
--- 1025,1038 ----
  			AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
  			break;
  
+ 		case T_CreateCollationStmt:
+ 			DefineCollation((CreateCollationStmt *) parsetree);
+ 			break;
+ 	
+ 		case T_DropCollationStmt:
+ 			DropCollation((DropCollationStmt *) parsetree);
+ 			break;
+ 	
  		default:
  			elog(ERROR, "unrecognized node type: %d",
  				 (int) nodeTag(parsetree));
Index: bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.65
diff -c -r1.65 pg_resetxlog.c
*** bin/pg_resetxlog/pg_resetxlog.c	21 Apr 2008 00:26:46 -0000	1.65
--- bin/pg_resetxlog/pg_resetxlog.c	31 Aug 2008 19:21:08 -0000
***************
*** 493,514 ****
  #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 ****
  		   (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 ----
Index: src/include/catalog/pg_collation.h
===================================================================
RCS file: src/include/catalog/pg_collation.h
diff -N src/include/catalog/pg_collation.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/include/catalog/pg_collation.h	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,115 ----
+ /*-------------------------------------------------------------------------
+  *
+  * pg_collation.h
+  *	  definition of the system "collation" relation (pg_collation)
+  *	  along with the relation's initial contents.
+  *
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $PostgreSQL:
+  *
+  * NOTES
+  *	  the genbki.sh script reads this file and generates .bki
+  *	  information from the DATA() statements.
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef PG_COLLATION_H
+ #define PG_COLLATION_H
+ 
+ #include "catalog/genbki.h"
+ 
+ /* ----------------------------------------------------------------
+  *		pg_collation definition.
+  *
+  *		cpp turns this into typedef struct FormData_pg_collation
+  *
+  * 	colname        			collation name
+  * 	colschema        		collation schema
+  *  colencoding    			encoding name
+  *  colpadattribute			pad attribute
+  * 	colcasesensitive    	case sensitive
+  * 	colcollate    			lc_collate
+  * 	colcharset 				collation charset
+  *  colfunc        			used collation function	
+  * 
+  * ----------------------------------------------------------------
+  */
+  
+ #define CollationRelationId  2328
+ 
+ 
+ enum {
+ 	PAD_CHARACTERISTIC_NO_PAD = 0,
+ 	PAD_CHARACTERISTIC_PAD_SPACE = 1
+ 	
+ }	CollationPadCharacteristic;
+ 
+ enum {
+ 	CASE_INSENSITIVE = 0,
+ 	CASE_SENSITIVE = 1
+ }	CollationCaseSensitive;
+ 
+ enum {
+ 	FUNCTION_BUILTIN = 0,
+ 	FUNCTION_SYSTEM = 1
+ }	CollationFunction;
+ 
+ CATALOG(pg_collation,2328)
+ {
+   NameData    					colname;
+   Oid        					colschema;
+   bool						    colpadattribute;
+   bool        					colcasesensitive;
+   NameData    					colcollate;
+   Oid    						colcharset;
+   int2				       		colfunc;	
+ } FormData_pg_collation;
+ 
+ /* ----------------
+  *		Form_pg_collation corresponds to a pointer to a tuple with
+  *		the format of pg_collation relation.
+  * ----------------
+  */
+ typedef FormData_pg_collation *Form_pg_collation;
+ 
+ /* ----------------
+  *		compiler constants for pg_collation
+  * ----------------
+  */
+ #define Natts_pg_collation						7
+ #define Anum_pg_collation_colname				1
+ #define Anum_pg_collation_colschema				2
+ #define	Anum_pg_collation_colpadattribute		3
+ #define	Anum_pg_collation_colcasesensitive		4
+ #define	Anum_pg_collation_colcollate			5
+ #define	Anum_pg_collation_colcharset			6
+ #define	Anum_pg_collation_colfunc				7
+ 
+ /* ----------------
+  *		initial contents of pg_collation
+  * ----------------
+  */
+ 
+ DATA(insert OID = 2982 ( "LATIN1" 	PGNSP	t t "C"				2182 	1));
+ DATA(insert OID = 2983 ( "ISO8BIT" 	PGNSP	t t "C" 			2183 	1));
+ DATA(insert OID = 2984 ( "UNICODE" 	PGNSP	t t "C" 			2184 	1));
+ DATA(insert OID = 2988 ( "DEFAULT"	PGNSP	t t "LC_COLLATE"	2185	1));
+ 
+ /* ----------------
+  * 		prototypes for functions in pg_collation.c
+  * ----------------
+  */
+ extern Oid CollationCreateEntry(const char *collationName,
+ 				Oid 						collationSchema,
+   				bool  						padAttribute,
+   				bool					    caseSensitive,
+ 			 	const char 		   		   *collate,
+ 			 	Oid 						charset,
+ 			 	int8						collationFunction);
+ 
+ extern void CollationDeleteEntry(const char *collationName);
+  
+ #endif   /* PG_COLLATION_H */
Index: src/interfaces/ecpg/include/ecpg_config.h
===================================================================
RCS file: src/interfaces/ecpg/include/ecpg_config.h
diff -N src/interfaces/ecpg/include/ecpg_config.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/interfaces/ecpg/include/ecpg_config.h	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,18 ----
+ /* src/interfaces/ecpg/include/ecpg_config.h.  Generated by configure.  */
+ /* Define to 1 if the system has the type `int64'. */
+ /* #undef HAVE_INT64 */
+ 
+ /* Define to 1 if `long int' works and is 64 bits. */
+ /* #undef HAVE_LONG_INT_64 */
+ 
+ /* Define to 1 if `long long int' works and is 64 bits. */
+ #define HAVE_LONG_LONG_INT_64 
+ 
+ /* Define to 1 if you want 64-bit integer timestamp and interval support.
+    (--enable-integer-datetimes) */
+ /* #undef USE_INTEGER_DATETIMES */
+ 
+ /* Define to 1 to build client libraries as thread-safe code.
+  *    (--enable-thread-safety) */
+ /* #undef ENABLE_THREAD_SAFETY */
+ 
Index: src/backend/catalog/pg_collation.c
===================================================================
RCS file: src/backend/catalog/pg_collation.c
diff -N src/backend/catalog/pg_collation.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/backend/catalog/pg_collation.c	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,138 ----
+ /*-------------------------------------------------------------------------
+  *
+  * pg_collation.c
+  *	  routines to support manipulation of the pg_collation relation
+  *
+  * Copyright (c) 2006-2008, PostgreSQL Global Development Group
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL:
+  *
+  *-------------------------------------------------------------------------
+  */
+ #include "postgres.h"
+ 
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "access/htup.h"
+ #include "access/relscan.h"
+ #include "access/skey.h"
+ #include "catalog/catalog.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_collation.h"
+ #include "utils/acl.h"
+ #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
+ #include "utils/rel.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+ 
+ 
+ Oid 
+ CollationCreateEntry(const char *collationName,
+ 			Oid 						collationSchema,
+   			bool						padAttribute,
+   			bool      					caseSensitive,
+ 			const char 		   		   *collate,
+ 			Oid 						charset,
+ 			int8				   		collationFunction)
+ {
+ 
+ 	Relation	pg_collation;
+ 	HeapTuple	tup;
+ 	TupleDesc	tupDesc;
+ 	Datum		values[Natts_pg_collation];
+ 	char		nulls[Natts_pg_collation];
+ 	Oid			oid;
+ 	Oid			collOid;
+ 	NameData	cname;
+ 	NameData	ccollate;
+ 	
+ 	
+ /*	ereport(WARNING, (errcode(ERRCODE_WARNING), 
+ *			errmsg("DEBUG (create collation): collation name - '%s', collate - '%s', padattribute - '%d', coll fn - '%d'",
+ *				collationName, 
+ *				collate,
+ *				padAttribute,
+ *				collationFunction
+ *				)));
+ *	
+ *	ereport(WARNING, (errcode(ERRCODE_WARNING),
+ *			errmsg("TEST")));
+ */	
+ 	Assert(collationName);
+   	namestrcpy(&cname, collationName);
+ 	
+ 	Assert(collate); 
+ 	namestrcpy(&ccollate, collate);
+ 
+ 	pg_collation = heap_open(CollationRelationId, RowExclusiveLock);
+ 
+ 	/* check uniqueness */	
+ 	if (HeapTupleIsValid(SearchSysCache(COLLNAME,
+ 									CStringGetDatum(collationName),
+ 									0, 0, 0)))
+ 	ereport(ERROR,
+ 			(errcode(ERRCODE_DUPLICATE_OBJECT),
+ 			 errmsg("collation \"%s\" already exists",
+ 			 		collationName)));	
+ 	
+ 	/* allocate new oid */
+ 	oid = GetNewOid(pg_collation);
+ 	if (!OidIsValid(oid))
+ 		ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ 				errmsg("Can't allocate new pg_collation oid.")));
+ 		
+ 	tupDesc = RelationGetDescr(pg_collation);
+ 	
+ 	/* prepare entries */
+ 	memset(nulls, ' ', sizeof(nulls));
+ 
+ 	values[Anum_pg_collation_colname - 1] = NameGetDatum(&cname);
+ 	values[Anum_pg_collation_colschema - 1] = ObjectIdGetDatum(collationSchema);
+ 	values[Anum_pg_collation_colpadattribute - 1] = BoolGetDatum(padAttribute);
+ 	values[Anum_pg_collation_colcasesensitive - 1] = BoolGetDatum(caseSensitive);
+ 	values[Anum_pg_collation_colcollate - 1] = NameGetDatum(&ccollate);
+ 	values[Anum_pg_collation_colcharset - 1] = ObjectIdGetDatum(charset);
+ 	values[Anum_pg_collation_colfunc - 1] = Int8GetDatum(collationFunction); 
+ 	
+ 	tup = heap_formtuple(tupDesc, values, nulls);
+ 	/* HeapTupleSetOid(tup, oid); */
+ 
+ 	collOid = simple_heap_insert(pg_collation, tup);
+ 	
+ 	CatalogUpdateIndexes(pg_collation, tup); 
+ 	
+ 	heap_freetuple(tup);
+ 	
+ 	heap_close(pg_collation, RowExclusiveLock);
+ 	
+ 	return collOid;
+ }	
+ 
+ void
+ CollationDeleteEntry(const char *collationName)
+ {
+ 	Relation pg_collation;
+ 	HeapTuple tup;
+ 	
+ 	Assert(collationName);
+ 
+ 	pg_collation = heap_open(CollationRelationId, RowExclusiveLock);
+ 
+ 	tup = SearchSysCache(COLLNAME, CStringGetDatum(collationName), 0, 0, 0);
+ 
+ 	if (HeapTupleIsValid(tup))
+ 		simple_heap_delete(pg_collation, &tup->t_self);
+ 	else
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 			 errmsg("collation \"%s\" does not exist",
+ 			 		collationName)));	
+ 		
+ 	ReleaseSysCache(tup);
+ 	
+ 	heap_close(pg_collation, RowExclusiveLock);		
+ }
+ 
Index: src/include/commands/collation.h
===================================================================
RCS file: src/include/commands/collation.h
diff -N src/include/commands/collation.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/include/commands/collation.h	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,21 ----
+ /*-------------------------------------------------------------------------
+  *
+  * collation.h
+  *	  prototypes for commands/collation.c
+  *
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $PostgreSQL: pgsql/src/include/commands/collation.h,v 1.1 2008/01/01 19:45:57 momjian Exp $
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef COLLATION_H
+ #define COLLATION_H
+ 
+ #include "nodes/parsenodes.h"
+ 
+ extern void DefineCollation(CreateCollationStmt *stmt);
+ 
+ #endif   /* COLLATION_H */
Index: src/backend/commands/collation.c
===================================================================
RCS file: src/backend/commands/collation.c
diff -N src/backend/commands/collation.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/backend/commands/collation.c	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,195 ----
+ /*-------------------------------------------------------------------------
+  *
+  * collation.c
+  *	  the Postgres collation support
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL: 
+  *
+  *-------------------------------------------------------------------------
+  */ 
+ #include "postgres.h"
+ #include "c.h"
+ 
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "access/htup.h"
+ #include "access/skey.h"
+ #include "access/xact.h"
+ #include "access/xlogutils.h"
+ #include "catalog/catalog.h"
+ #include "catalog/dependency.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_charset.h"
+ #include "catalog/pg_collation.h"
+ #include "catalog/pg_namespace.h"
+ #include "commands/defrem.h"
+ #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
+ #include "utils/pg_locale.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+ 
+ /*
+  * CREATE COLLATION
+  */
+ void
+ DefineCollation(CreateCollationStmt *stmt)
+ {
+ 	const char 		   *collationname = stmt->name;
+ 	const char 		   *charsetname = stmt->for_charset;
+ 	const char 		   *parentcollationname = stmt->parent_collation;
+ 	char			   *charsetctype = NULL;
+ 	char			   *collationcollate = NULL;
+ 	Oid					schemaid;
+ 	Oid					charsetid;
+ 	HeapTuple			coltuple;
+ 	HeapTuple			chartuple;
+ 	Form_pg_collation 	parentcollation;
+ 	ListCell		   *option;
+ 	
+ 	/* debug stuff */
+ 	
+ 	/* ereport(WARNING, (errcode(ERRCODE_WARNING), 
+ 			errmsg("DEBUG: collation name - '%s', parent collation - '%s', charset for - '%s'",
+ 				collationname, parentcollationname, charsetname))); */
+ 	
+ 	/* retrieve parent collation and copy parameters */
+ 	
+ 	/* colrel = heap_open(CollationRelationId, RowShareLock);
+ 	*
+ 	* ScanKeyInit(&colkey[0],
+ 	* 			Anum_pg_collation_colname,
+ 	* 			BTEqualStrategyNumber, F_NAMEEQ, 
+ 	* 			NameGetDatum(parentcollationname));
+ 	* 
+ 	* scan = systable_beginscan(colrel, CollationRelationId, true,
+ 	* 						  SnapshotNow, 1, colkey);
+ 	* 						  
+ 	* coltuple = systable_getnext(scan);
+ 	* 
+ 	*/ 
+ 	
+ 	coltuple = SearchSysCache(COLLNAME,
+ 							CStringGetDatum(parentcollationname),
+ 							0, 0, 0);
+ 
+ 	if (!HeapTupleIsValid(coltuple))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 				 errmsg("parent collation \"%s\" does not exist",
+ 				 		parentcollationname)));	
+ 							
+ 	parentcollation = (Form_pg_collation) GETSTRUCT(coltuple);
+ 	
+ 	ReleaseSysCache(coltuple);
+ 	
+ 	/* TODO sanity checks (duplicate options values etc.) */
+ 	
+ 	/* override parent collation with new option values */
+ 	
+ 	foreach(option, stmt->options)
+ 	{
+ 		DefElem    *defel = (DefElem *) lfirst(option);
+ 		
+ 		if (strcmp(defel->defname, "pad_characteristic") == 0)
+ 		{
+ 			if (defGetNumeric(defel) == FALSE) 
+ 				parentcollation->colpadattribute = PAD_CHARACTERISTIC_NO_PAD;
+ 			else 
+ 			  	parentcollation->colpadattribute = PAD_CHARACTERISTIC_PAD_SPACE;
+ 		}	
+ 		else if (strcmp(defel->defname, "case_sensitive") == 0)
+ 		{
+ 			if (defGetNumeric(defel) == FALSE)
+ 				parentcollation->colcasesensitive = CASE_INSENSITIVE;
+ 			else
+ 				parentcollation->colcasesensitive = CASE_SENSITIVE;
+ 		}
+ 		else if (strcmp(defel->defname, "lc_collate_name") == 0)
+ 		{
+ 			if (defel->arg != NULL)
+ 			{
+ 				collationcollate = (char *)palloc((strlen(defGetString(defel)) + 1) * sizeof(char));
+ 				strcpy(collationcollate, defGetString(defel));
+ 			}
+ 		}
+ 		else if (strcmp(defel->defname, "lc_ctype_name") == 0)
+ 		{
+ 			if (defel->arg != NULL)
+ 			{
+ 				charsetctype = (char *)palloc((strlen(defGetString(defel)) + 1) * sizeof(char));
+ 				strcpy(charsetctype, defGetString(defel));
+ 			}
+ 		}
+ 		else if (strcmp(defel->defname, "str_col_function") == 0)
+ 		{
+ 			parentcollation->colfunc = defGetNumeric(defel);
+ 		}
+ 		
+ 	}
+ 	
+ 	if (collationcollate == NULL)
+ 	{
+ 		collationcollate = (char *)palloc((strlen((char *)parentcollation->colcollate.data) + 1) * sizeof(char));
+ 		strcpy(collationcollate, (char *)parentcollation->colcollate.data);
+ 	}	
+ 
+ 	/* get character OID */ 	
+ 	chartuple = SearchSysCache(CHARSETNAME,
+ 						CStringGetDatum(charsetname),
+ 						0, 0, 0);
+ 		
+ 	if (!HeapTupleIsValid(chartuple))
+ 	{
+ 
+ 		/* create record in pg_charset */ 
+ 		if (charsetctype != NULL)
+ 		{
+ 			charsetid = CharsetCreateEntry(charsetname, PG_PUBLIC_NAMESPACE, charsetctype);  
+ 			ereport(WARNING, (errcode(ERRCODE_WARNING), 
+ 					errmsg("DEBUG (create charset): charset name - '%s', charset namespace - '%d', LC_CTYPE - '%s'",
+ 						charsetname, 
+ 						PG_PUBLIC_NAMESPACE,
+ 						charsetctype
+ 						)));
+ 		}
+ 		else
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 					 errmsg("LCCTYPE not specified")));	
+ 		
+ 		/* TODO check duplicite names */		
+ 	}
+ 	else
+ 	{
+  
+ 		/* all good */ 
+ 		charsetid = HeapTupleGetOid(chartuple);
+ 		ReleaseSysCache(chartuple);
+ 	}
+ 	
+ 	/* create catalog record */
+ 	CollationCreateEntry(collationname,
+ 						PG_PUBLIC_NAMESPACE,
+ 						parentcollation->colpadattribute,	
+ 						parentcollation->colcasesensitive,
+ 						collationcollate,
+ 						charsetid,
+ 						1);
+ 
+ 
+ 	if (collationcollate != NULL) pfree(collationcollate);
+ 	if (charsetctype != NULL) pfree(charsetctype);
+ 
+ }
+ 
+ void
+ DropCollation(DropCollationStmt *stmt)
+ {
+ 	CollationDeleteEntry(stmt->name);
+ }
Index: src/backend/catalog/pg_charset.c
===================================================================
RCS file: src/backend/catalog/pg_charset.c
diff -N src/backend/catalog/pg_charset.c
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/backend/catalog/pg_charset.c	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,83 ----
+ /*-------------------------------------------------------------------------
+  *
+  * pg_charset.c
+  *	  routines to support manipulation of the pg_collation relation
+  *
+  * Copyright (c) 2006-2008, PostgreSQL Global Development Group
+  *
+  *
+  * IDENTIFICATION
+  *	  $PostgreSQL:
+  *
+  *-------------------------------------------------------------------------
+  */
+  
+ #include "postgres.h"
+ 
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "catalog/catalog.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_charset.h"
+ #include "utils/builtins.h"
+ #include "utils/rel.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+ 
+ Oid CharsetCreateEntry(const char *charsetName,
+ 				Oid 		charsetSchema,
+ 				const char *charsetType)
+ {
+ 	Relation	pg_charset;
+ 	HeapTuple	tup;
+ 	TupleDesc	tupDesc;
+ 	Datum		values[Natts_pg_charset];
+ 	char		nulls[Natts_pg_charset];
+ 	Oid			oid;
+ 	Oid			charOid;
+ 	NameData	chName;
+ 	NameData	chType;
+ 	
+ 	Assert(charsetName);
+ 	namestrcpy(&chName, charsetName);
+ 	
+ 	Assert(charsetType);	
+ 	namestrcpy(&chType, charsetType);
+ 	
+ 	pg_charset = heap_open(CharsetRelationId, RowExclusiveLock);
+ 	
+ 	/* check uniqueness */	
+ 	if (HeapTupleIsValid(SearchSysCache(CHARSETNAME,
+ 									CStringGetDatum(charsetName),
+ 									0, 0, 0)))
+ 	ereport(ERROR,
+ 			(errcode(ERRCODE_DUPLICATE_OBJECT),
+ 			 errmsg("charset \"%s\" already exists",
+ 			 		charsetName)));	
+ 	
+ 	/* allocate new oid */
+ 	oid = GetNewOid(pg_charset);
+ 	if (!OidIsValid(oid))
+ 		ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ 				errmsg("Can't allocate new pg_charset oid.")));
+ 
+ 	tupDesc = RelationGetDescr(pg_charset);
+ 	 	
+ 	/* prepare entries */
+ 	memset(nulls, ' ', sizeof(nulls));
+ 
+ 	values[Anum_pg_charset_charsetname - 1] = NameGetDatum(&chName);
+ 	values[Anum_pg_charset_charsetschema - 1] = ObjectIdGetDatum(charsetSchema);
+ 	values[Anum_pg_charset_charsettype - 1] = NameGetDatum(&chType);
+ 	
+ 	tup = heap_formtuple(tupDesc, values, nulls);
+ 	/* HeapTupleSetOid(tup, oid); */
+ 
+ 	charOid = simple_heap_insert(pg_charset, tup);
+ 	CatalogUpdateIndexes(pg_charset, tup);
+ 	heap_freetuple(tup);
+ 	
+ 	heap_close(pg_charset, RowExclusiveLock);
+ 	
+ 	return charOid;		
+ }
Index: src/include/catalog/pg_charset.h
===================================================================
RCS file: src/include/catalog/pg_charset.h
diff -N src/include/catalog/pg_charset.h
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- src/include/catalog/pg_charset.h	1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,82 ----
+ /*-------------------------------------------------------------------------
+  *
+  * pg_charset.h
+  *	  definition of the system "pg_charset" relation (pg_charset)
+  *	  along with the relation's initial contents.
+  *
+  *
+  * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * $PostgreSQL:
+  *
+  * NOTES
+  *	  the genbki.sh script reads this file and generates .bki
+  *	  information from the DATA() statements.
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef PG_CHARSET_H
+ #define PG_CHARSET_H
+ 
+ #include "catalog/genbki.h"
+ 
+  /* ----------------------------------------------------------------
+  *		pg_charset definition.
+  *
+  *		cpp turns this into typedef struct FormData_pg_charset
+  *
+  * 	charsetname        			character set name
+  * 	charsetschema        		character set schema
+  *  charsettype    				character set type
+  *  charsetfunc					character set function
+  * 								(sets the charset)
+  * 
+  * ----------------------------------------------------------------
+  */
+  
+ #define CharsetRelationId  2981
+ 
+ CATALOG(pg_charset,2981)
+ {
+   NameData    	charsetname;
+   Oid        	charsetschema;
+   NameData    	charsettype;
+ } FormData_pg_charset;
+ 
+ /* ----------------
+  *		Form_pg_charset corresponds to a pointer to a tuple with
+  *		the format of pg_collation relation.
+  * ----------------
+  */
+ typedef FormData_pg_charset *Form_pg_charset;
+ 
+ /* ----------------
+  *		compiler constants for pg_collation
+  * ----------------
+  */
+ #define Natts_pg_charset					3
+ #define Anum_pg_charset_charsetname			1
+ #define Anum_pg_charset_charsetschema		2
+ #define	Anum_pg_charset_charsettype			3
+ 
+ /* ----------------
+  *		initial contents of pg_charset
+  * ----------------
+  */
+  
+ DATA(insert OID = 2182 ( "LATIN1" 	PGNSP 	"C" ));
+ DATA(insert OID = 2183 ( "ISO8BIT" 	PGNSP 	"C" ));
+ DATA(insert OID = 2184 ( "UTF-8" 	PGNSP 	"C" ));
+ DATA(insert OID = 2185 ( "DEFAULT"	PGNSP	"LC_CTYPE" ));
+ 
+ /* ----------------
+  * 		prototypes for functions in pg_charset.c
+  * ----------------
+  */
+  
+ extern Oid CharsetCreateEntry(const char *charsetName,
+ 				Oid 		charsetSchema,
+ 				const char *charsetType);
+  
+ #endif   /* PG_CHARSET_H */
