*** a/src/backend/commands/alter.c
--- b/src/backend/commands/alter.c
***************
*** 19,27 ****
--- 19,29 ----
  #include "catalog/dependency.h"
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
+ #include "catalog/pg_collation.h"
  #include "catalog/pg_largeobject.h"
  #include "catalog/pg_largeobject_metadata.h"
  #include "catalog/pg_namespace.h"
+ #include "catalog/pg_proc.h"
  #include "commands/alter.h"
  #include "commands/collationcmds.h"
  #include "commands/conversioncmds.h"
***************
*** 146,185 **** ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
  {
  	switch (stmt->objectType)
  	{
- 		case OBJECT_AGGREGATE:
- 			return AlterFunctionNamespace(stmt->object, stmt->objarg, true,
- 										  stmt->newschema);
- 
- 		case OBJECT_COLLATION:
- 			return AlterCollationNamespace(stmt->object, stmt->newschema);
- 
  		case OBJECT_EXTENSION:
  			return AlterExtensionNamespace(stmt->object, stmt->newschema);
  
! 		case OBJECT_FUNCTION:
! 			return AlterFunctionNamespace(stmt->object, stmt->objarg, false,
! 										  stmt->newschema);
! 
  		case OBJECT_SEQUENCE:
  		case OBJECT_TABLE:
  		case OBJECT_VIEW:
- 		case OBJECT_FOREIGN_TABLE:
  			return AlterTableNamespace(stmt);
  
- 		case OBJECT_TYPE:
  		case OBJECT_DOMAIN:
  			return AlterTypeNamespace(stmt->object, stmt->newschema,
  									  stmt->objectType);
  
  			/* generic code path */
  		case OBJECT_CONVERSION:
  		case OBJECT_OPERATOR:
  		case OBJECT_OPCLASS:
  		case OBJECT_OPFAMILY:
! 		case OBJECT_TSPARSER:
  		case OBJECT_TSDICTIONARY:
  		case OBJECT_TSTEMPLATE:
- 		case OBJECT_TSCONFIGURATION:
  			{
  				Relation	catalog;
  				Relation	relation;
--- 148,179 ----
  {
  	switch (stmt->objectType)
  	{
  		case OBJECT_EXTENSION:
  			return AlterExtensionNamespace(stmt->object, stmt->newschema);
  
! 		case OBJECT_FOREIGN_TABLE:
  		case OBJECT_SEQUENCE:
  		case OBJECT_TABLE:
  		case OBJECT_VIEW:
  			return AlterTableNamespace(stmt);
  
  		case OBJECT_DOMAIN:
+ 		case OBJECT_TYPE:
  			return AlterTypeNamespace(stmt->object, stmt->newschema,
  									  stmt->objectType);
  
  			/* generic code path */
+ 		case OBJECT_AGGREGATE:
+ 		case OBJECT_COLLATION:
  		case OBJECT_CONVERSION:
+ 		case OBJECT_FUNCTION:
  		case OBJECT_OPERATOR:
  		case OBJECT_OPCLASS:
  		case OBJECT_OPFAMILY:
! 		case OBJECT_TSCONFIGURATION:
  		case OBJECT_TSDICTIONARY:
+ 		case OBJECT_TSPARSER:
  		case OBJECT_TSTEMPLATE:
  			{
  				Relation	catalog;
  				Relation	relation;
***************
*** 253,270 **** AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
  				break;
  			}
  
- 		case OCLASS_PROC:
- 			oldNspOid = AlterFunctionNamespace_oid(objid, nspOid);
- 			break;
- 
  		case OCLASS_TYPE:
  			oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
  			break;
  
  		case OCLASS_COLLATION:
- 			oldNspOid = AlterCollationNamespace_oid(objid, nspOid);
- 			break;
- 
  		case OCLASS_CONVERSION:
  		case OCLASS_OPERATOR:
  		case OCLASS_OPCLASS:
--- 247,258 ----
  				break;
  			}
  
  		case OCLASS_TYPE:
  			oldNspOid = AlterTypeNamespace_oid(objid, nspOid, objsMoved);
  			break;
  
+ 		case OCLASS_PROC:
  		case OCLASS_COLLATION:
  		case OCLASS_CONVERSION:
  		case OCLASS_OPERATOR:
  		case OCLASS_OPCLASS:
***************
*** 380,385 **** AlterObjectNamespace_internal(Relation rel, Oid objid, Oid nspOid)
--- 368,385 ----
  				 errmsg("%s already exists in schema \"%s\"",
  						getObjectDescriptionOids(classId, objid),
  						get_namespace_name(nspOid))));
+ 	else if (classId == ProcedureRelationId)
+ 		IsThereFunctionInNamespace(objid, nspOid);
+ 	else if (classId == CollationRelationId)
+ 	{
+ 		char *collname;
+ 
+ 		collname = get_collation_name(objid);
+ 		if (!collname)
+ 			elog(ERROR, "cache lookup failed for collation %u", objid);
+ 		IsThereCollationInNamespace(collname, nspOid);
+ 		pfree(collname);
+ 	}
  
  	/* Build modified tuple */
  	values = palloc0(RelationGetNumberOfAttributes(rel) * sizeof(Datum));
*** a/src/backend/commands/collationcmds.c
--- b/src/backend/commands/collationcmds.c
***************
*** 167,193 **** RenameCollation(List *name, const char *newname)
  	namespaceOid = ((Form_pg_collation) GETSTRUCT(tup))->collnamespace;
  
  	/* make sure the new name doesn't exist */
! 	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(newname),
! 							  Int32GetDatum(GetDatabaseEncoding()),
! 							  ObjectIdGetDatum(namespaceOid)))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_DUPLICATE_OBJECT),
! 				 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
! 						newname,
! 						GetDatabaseEncodingName(),
! 						get_namespace_name(namespaceOid))));
! 
! 	/* mustn't match an any-encoding entry, either */
! 	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(newname),
! 							  Int32GetDatum(-1),
! 							  ObjectIdGetDatum(namespaceOid)))
! 		ereport(ERROR,
! 				(errcode(ERRCODE_DUPLICATE_OBJECT),
! 				 errmsg("collation \"%s\" already exists in schema \"%s\"",
! 						newname,
! 						get_namespace_name(namespaceOid))));
  
  	/* must be owner */
  	if (!pg_collation_ownercheck(collationOid, GetUserId()))
--- 167,173 ----
  	namespaceOid = ((Form_pg_collation) GETSTRUCT(tup))->collnamespace;
  
  	/* make sure the new name doesn't exist */
! 	IsThereCollationInNamespace(newname, namespaceOid);
  
  	/* must be owner */
  	if (!pg_collation_ownercheck(collationOid, GetUserId()))
***************
*** 213,283 **** RenameCollation(List *name, const char *newname)
  }
  
  /*
!  * Execute ALTER COLLATION SET SCHEMA
!  */
! Oid
! AlterCollationNamespace(List *name, const char *newschema)
! {
! 	Oid			collOid,
! 				nspOid;
! 
! 	collOid = get_collation_oid(name, false);
! 
! 	nspOid = LookupCreationNamespace(newschema);
! 
! 	AlterCollationNamespace_oid(collOid, nspOid);
! 
! 	return collOid;
! }
! 
! /*
!  * Change collation schema, by oid
   */
! Oid
! AlterCollationNamespace_oid(Oid collOid, Oid newNspOid)
  {
- 	Oid			oldNspOid;
- 	Relation	rel;
- 	char	   *collation_name;
- 
- 	rel = heap_open(CollationRelationId, RowExclusiveLock);
- 
- 	/*
- 	 * We have to check for name collision ourselves, because
- 	 * AlterObjectNamespace_internal doesn't know how to deal with the encoding
- 	 * considerations.
- 	 */
- 	collation_name = get_collation_name(collOid);
- 	if (!collation_name)
- 		elog(ERROR, "cache lookup failed for collation %u", collOid);
- 
  	/* make sure the name doesn't already exist in new schema */
  	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(collation_name),
  							  Int32GetDatum(GetDatabaseEncoding()),
! 							  ObjectIdGetDatum(newNspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_OBJECT),
  				 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
! 						collation_name,
! 						GetDatabaseEncodingName(),
! 						get_namespace_name(newNspOid))));
  
  	/* mustn't match an any-encoding entry, either */
  	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(collation_name),
  							  Int32GetDatum(-1),
! 							  ObjectIdGetDatum(newNspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_OBJECT),
  				 errmsg("collation \"%s\" already exists in schema \"%s\"",
! 						collation_name,
! 						get_namespace_name(newNspOid))));
! 
! 	/* OK, do the work */
! 	oldNspOid = AlterObjectNamespace_internal(rel, collOid, newNspOid);
! 
! 	heap_close(rel, RowExclusiveLock);
! 
! 	return oldNspOid;
  }
--- 193,224 ----
  }
  
  /*
!  * Subroutine for ALTER COLLATION SET SCHEMA and RENAME
!  *
!  * Is there a collation with the same name of the given collation already in
!  * the given namespace?  If so, raise an appropriate error message.
   */
! void
! IsThereCollationInNamespace(const char *collname, Oid nspOid)
  {
  	/* make sure the name doesn't already exist in new schema */
  	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(collname),
  							  Int32GetDatum(GetDatabaseEncoding()),
! 							  ObjectIdGetDatum(nspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_OBJECT),
  				 errmsg("collation \"%s\" for encoding \"%s\" already exists in schema \"%s\"",
! 						collname, GetDatabaseEncodingName(),
! 						get_namespace_name(nspOid))));
  
  	/* mustn't match an any-encoding entry, either */
  	if (SearchSysCacheExists3(COLLNAMEENCNSP,
! 							  CStringGetDatum(collname),
  							  Int32GetDatum(-1),
! 							  ObjectIdGetDatum(nspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_OBJECT),
  				 errmsg("collation \"%s\" already exists in schema \"%s\"",
! 						collname, get_namespace_name(nspOid))));
  }
*** a/src/backend/commands/functioncmds.c
--- b/src/backend/commands/functioncmds.c
***************
*** 1688,1733 **** DropCastById(Oid castOid)
  }
  
  /*
!  * Execute ALTER FUNCTION/AGGREGATE SET SCHEMA
   *
!  * These commands are identical except for the lookup procedure, so share code.
   */
! Oid
! AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
! 					   const char *newschema)
! {
! 	Oid			procOid;
! 	Oid			nspOid;
! 
! 	/* get function OID */
! 	if (isagg)
! 		procOid = LookupAggNameTypeNames(name, argtypes, false);
! 	else
! 		procOid = LookupFuncNameTypeNames(name, argtypes, false);
! 
! 	/* get schema OID and check its permissions */
! 	nspOid = LookupCreationNamespace(newschema);
! 
! 	AlterFunctionNamespace_oid(procOid, nspOid);
! 
! 	return procOid;
! }
! 
! Oid
! AlterFunctionNamespace_oid(Oid procOid, Oid nspOid)
  {
- 	Oid			oldNspOid;
  	HeapTuple	tup;
- 	Relation	procRel;
  	Form_pg_proc proc;
  
- 	procRel = heap_open(ProcedureRelationId, RowExclusiveLock);
- 
- 	/*
- 	 * We have to check for name collisions ourselves, because
- 	 * AlterObjectNamespace_internal doesn't know how to deal with the
- 	 * argument types.
- 	 */
  	tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
  	if (!HeapTupleIsValid(tup))
  		elog(ERROR, "cache lookup failed for function %u", procOid);
--- 1688,1706 ----
  }
  
  /*
!  * Subroutine for ALTER FUNCTION/AGGREGATE SET SCHEMA
   *
!  * Is there a function with the same name and signature of the given function
!  * already in the given namespace?  If so, raise an appropriate error message.
!  *
!  * XXX share code with RenameFunction?
   */
! void
! IsThereFunctionInNamespace(Oid procOid, Oid nspOid)
  {
  	HeapTuple	tup;
  	Form_pg_proc proc;
  
  	tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
  	if (!HeapTupleIsValid(tup))
  		elog(ERROR, "cache lookup failed for function %u", procOid);
***************
*** 1740,1758 **** AlterFunctionNamespace_oid(Oid procOid, Oid nspOid)
  							  ObjectIdGetDatum(nspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_FUNCTION),
! 				 errmsg("function \"%s\" already exists in schema \"%s\"",
! 						NameStr(proc->proname),
  						get_namespace_name(nspOid))));
- 
- 	/* OK, do the work */
- 	oldNspOid = AlterObjectNamespace_internal(procRel, procOid, nspOid);
- 
- 	heap_close(procRel, RowExclusiveLock);
- 
- 	return oldNspOid;
  }
  
- 
  /*
   * ExecuteDoStmt
   *		Execute inline procedural-language code
--- 1713,1726 ----
  							  ObjectIdGetDatum(nspOid)))
  		ereport(ERROR,
  				(errcode(ERRCODE_DUPLICATE_FUNCTION),
! 				 errmsg("function %s already exists in schema \"%s\"",
! 						funcname_signature_string(NameStr(proc->proname),
! 												  proc->pronargs,
! 												  NIL,
! 												  proc->proargtypes.values),
  						get_namespace_name(nspOid))));
  }
  
  /*
   * ExecuteDoStmt
   *		Execute inline procedural-language code
*** a/src/include/commands/collationcmds.h
--- b/src/include/commands/collationcmds.h
***************
*** 19,25 ****
  
  extern Oid DefineCollation(List *names, List *parameters);
  extern Oid RenameCollation(List *name, const char *newname);
! extern Oid AlterCollationNamespace(List *name, const char *newschema);
! extern Oid	AlterCollationNamespace_oid(Oid collOid, Oid newNspOid);
  
  #endif   /* COLLATIONCMDS_H */
--- 19,24 ----
  
  extern Oid DefineCollation(List *names, List *parameters);
  extern Oid RenameCollation(List *name, const char *newname);
! extern void IsThereCollationInNamespace(const char *collname, Oid newNspOid);
  
  #endif   /* COLLATIONCMDS_H */
*** a/src/include/commands/defrem.h
--- b/src/include/commands/defrem.h
***************
*** 50,58 **** extern Oid RenameFunction(List *name, List *argtypes, const char *newname);
  extern Oid AlterFunction(AlterFunctionStmt *stmt);
  extern Oid CreateCast(CreateCastStmt *stmt);
  extern void DropCastById(Oid castOid);
! extern Oid AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
! 								  const char *newschema);
! extern Oid	AlterFunctionNamespace_oid(Oid procOid, Oid nspOid);
  extern void ExecuteDoStmt(DoStmt *stmt);
  extern Oid	get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
  
--- 50,56 ----
  extern Oid AlterFunction(AlterFunctionStmt *stmt);
  extern Oid CreateCast(CreateCastStmt *stmt);
  extern void DropCastById(Oid castOid);
! extern void IsThereFunctionInNamespace(Oid procOid, Oid nspOid);
  extern void ExecuteDoStmt(DoStmt *stmt);
  extern Oid	get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
  
*** a/src/test/regress/expected/alter_generic.out
--- b/src/test/regress/expected/alter_generic.out
***************
*** 69,75 **** ERROR:  must be member of role "regtest_alter_user3"
  ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2;      -- failed (not owner)
  ERROR:  must be owner of function alt_func3
  ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2;	-- failed (name conflicts)
! ERROR:  function "alt_func2" already exists in schema "alt_nsp2"
  ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4;   -- failed (not owner)
  ERROR:  must be owner of function alt_agg3
  ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4;   -- OK
--- 69,75 ----
  ALTER FUNCTION alt_func3(int) SET SCHEMA alt_nsp2;      -- failed (not owner)
  ERROR:  must be owner of function alt_func3
  ALTER FUNCTION alt_func2(int) SET SCHEMA alt_nsp2;	-- failed (name conflicts)
! ERROR:  function alt_func2(integer) already exists in schema "alt_nsp2"
  ALTER AGGREGATE alt_agg3(int) RENAME TO alt_agg4;   -- failed (not owner)
  ERROR:  must be owner of function alt_agg3
  ALTER AGGREGATE alt_agg1(int) RENAME TO alt_agg4;   -- OK
***************
*** 80,86 **** ERROR:  must be member of role "regtest_alter_user3"
  ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2;  -- failed (not owner)
  ERROR:  must be owner of function alt_agg3
  ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2;  -- failed (name conflict)
! ERROR:  function "alt_agg2" already exists in schema "alt_nsp2"
  RESET SESSION AUTHORIZATION;
  SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
    FROM pg_proc p, pg_namespace n, pg_authid a
--- 80,86 ----
  ALTER AGGREGATE alt_agg3(int) SET SCHEMA alt_nsp2;  -- failed (not owner)
  ERROR:  must be owner of function alt_agg3
  ALTER AGGREGATE alt_agg2(int) SET SCHEMA alt_nsp2;  -- failed (name conflict)
! ERROR:  function alt_agg2(integer) already exists in schema "alt_nsp2"
  RESET SESSION AUTHORIZATION;
  SELECT n.nspname, proname, prorettype::regtype, proisagg, a.rolname
    FROM pg_proc p, pg_namespace n, pg_authid a
