diff --git a/contrib/isn/isn--1.0.sql b/contrib/isn/isn--1.0.sql
index ce74c17..84aafcb 100644
diff --git a/src/backend/commanindex e5b813d..5901965 100644
*** a/src/backend/commands/alter.c
--- b/src/backend/commands/alter.c
***************
*** 247,253 **** ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
   * object doesn't have a schema.
   */
  Oid
! AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid)
  {
  	Oid			oldNspOid = InvalidOid;
  	ObjectAddress dep;
--- 247,254 ----
   * object doesn't have a schema.
   */
  Oid
! AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
! 						 ObjectAddresses *objsMoved)
  {
  	Oid			oldNspOid = InvalidOid;
  	ObjectAddress dep;
***************
*** 261,280 **** AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid)
  		case OCLASS_CLASS:
  			{
  				Relation	rel;
- 				Relation	classRel;
  
  				rel = relation_open(objid, AccessExclusiveLock);
  				oldNspOid = RelationGetNamespace(rel);
  
! 				classRel = heap_open(RelationRelationId, RowExclusiveLock);
! 
! 				AlterRelationNamespaceInternal(classRel,
! 											   objid,
! 											   oldNspOid,
! 											   nspOid,
! 											   true);
! 
! 				heap_close(classRel, RowExclusiveLock);
  
  				relation_close(rel, NoLock);
  				break;
--- 262,272 ----
  		case OCLASS_CLASS:
  			{
  				Relation	rel;
  
  				rel = relation_open(objid, AccessExclusiveLock);
  				oldNspOid = RelationGetNamespace(rel);
  
! 				AlterTableNamespaceInternal(rel, oldNspOid, nspOid, objsMoved);
  
  				relation_close(rel, NoLock);
  				break;
diff --git a/src/backend/commands/eindex ec8aa17..c195213 100644
*** a/src/backend/commands/extension.c
--- b/src/backend/commands/extension.c
***************
*** 2203,2208 **** AlterExtensionNamespace(List *names, const char *newschema)
--- 2203,2209 ----
  	Relation	depRel;
  	SysScanDesc depScan;
  	HeapTuple	depTup;
+ 	ObjectAddresses *objsMoved;
  
  	if (list_length(names) != 1)
  		ereport(ERROR,
***************
*** 2277,2282 **** AlterExtensionNamespace(List *names, const char *newschema)
--- 2278,2285 ----
  				 errmsg("extension \"%s\" does not support SET SCHEMA",
  						NameStr(extForm->extname))));
  
+ 	objsMoved = new_object_addresses();
+ 
  	/*
  	 * Scan pg_depend to find objects that depend directly on the extension,
  	 * and alter each one's schema.
***************
*** 2316,2343 **** AlterExtensionNamespace(List *names, const char *newschema)
  		if (dep.objectSubId != 0)		/* should not happen */
  			elog(ERROR, "extension should not have a sub-object dependency");
  
! 		dep_oldNspOid = AlterObjectNamespace_oid(dep.classId,
! 												 dep.objectId,
! 												 nspOid);
  
! 		/*
! 		 * Remember previous namespace of first object that has one
! 		 */
! 		if (oldNspOid == InvalidOid && dep_oldNspOid != InvalidOid)
! 			oldNspOid = dep_oldNspOid;
  
! 		/*
! 		 * If not all the objects had the same old namespace (ignoring any
! 		 * that are not in namespaces), complain.
! 		 */
! 		if (dep_oldNspOid != InvalidOid && dep_oldNspOid != oldNspOid)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! 					 errmsg("extension \"%s\" does not support SET SCHEMA",
! 							NameStr(extForm->extname)),
! 					 errdetail("%s is not in the extension's schema \"%s\"",
! 							   getObjectDescription(&dep),
! 							   get_namespace_name(oldNspOid))));
  	}
  
  	systable_endscan(depScan);
--- 2319,2351 ----
  		if (dep.objectSubId != 0)		/* should not happen */
  			elog(ERROR, "extension should not have a sub-object dependency");
  
! 		/* Relocate the object, if it hasn't been already relocated */
! 		if (!object_address_present(&dep, objsMoved))
! 		{
! 			dep_oldNspOid = AlterObjectNamespace_oid(dep.classId,
! 													 dep.objectId,
! 													 nspOid,
! 													 objsMoved);
  
! 			/*
! 			 * Remember previous namespace of first object that has one
! 			 */
! 			if (oldNspOid == InvalidOid && dep_oldNspOid != InvalidOid)
! 				oldNspOid = dep_oldNspOid;
  
! 			/*
! 			 * If not all the objects had the same old namespace (ignoring any
! 			 * that are not in namespaces), complain.
! 			 */
! 			if (dep_oldNspOid != InvalidOid && dep_oldNspOid != oldNspOid)
! 				ereport(ERROR,
! 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
! 						 errmsg("extension \"%s\" does not support SET SCHEMA",
! 								NameStr(extForm->extname)),
! 						 errdetail("%s is not in the extension's schema \"%s\"",
! 								   getObjectDescription(&dep),
! 								   get_namespace_name(oldNspOid))));
! 		}
  	}
  
  	systable_endscan(depScan);
diff --git a/src/backend/commands/tableindex 359d478..defe3c2 100644
*** a/src/backend/commands/tablecmds.c
--- b/src/backend/commands/tablecmds.c
***************
*** 263,270 **** static int	findAttrByName(const char *attributeName, List *schema);
  static void AlterIndexNamespaces(Relation classRel, Relation rel,
  					 Oid oldNspOid, Oid newNspOid);
  static void AlterSeqNamespaces(Relation classRel, Relation rel,
! 				   Oid oldNspOid, Oid newNspOid,
! 				   const char *newNspName, LOCKMODE lockmode);
  static void ATExecValidateConstraint(Relation rel, char *constrName,
  						 bool recurse, bool recursing, LOCKMODE lockmode);
  static int transformColumnNameList(Oid relId, List *colList,
--- 263,270 ----
  static void AlterIndexNamespaces(Relation classRel, Relation rel,
  					 Oid oldNspOid, Oid newNspOid);
  static void AlterSeqNamespaces(Relation classRel, Relation rel,
! 				   Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
! 				   LOCKMODE lockmode);
  static void ATExecValidateConstraint(Relation rel, char *constrName,
  						 bool recurse, bool recursing, LOCKMODE lockmode);
  static int transformColumnNameList(Oid relId, List *colList,
***************
*** 9710,9716 **** AlterTableNamespace(AlterObjectSchemaStmt *stmt)
  	Oid			relid;
  	Oid			oldNspOid;
  	Oid			nspOid;
- 	Relation	classRel;
  	RangeVar   *newrv;
  
  	relid = RangeVarGetRelidExtended(stmt->relation, AccessExclusiveLock,
--- 9710,9715 ----
***************
*** 9752,9761 **** AlterTableNamespace(AlterObjectSchemaStmt *stmt)
  	/* common checks on switching namespaces */
  	CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
  
  	/* OK, modify the pg_class row and pg_depend entry */
  	classRel = heap_open(RelationRelationId, RowExclusiveLock);
  
! 	AlterRelationNamespaceInternal(classRel, relid, oldNspOid, nspOid, true);
  
  	/* Fix the table's row type too */
  	AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false);
--- 9751,9777 ----
  	/* common checks on switching namespaces */
  	CheckSetNamespace(oldNspOid, nspOid, RelationRelationId, relid);
  
+ 	AlterTableNamespaceInternal(rel, oldNspOid, nspOid, NULL);
+ 
+ 	/* close rel, but keep lock until commit */
+ 	relation_close(rel, NoLock);
+ }
+ 
+ /*
+  * The guts of relocating a table to another namespace: besides moving
+  * the table itself, its dependent objects are relocated to the new schema.
+  */
+ void
+ AlterTableNamespaceInternal(Relation rel, Oid oldNspOid, Oid nspOid,
+ 							ObjectAddresses *objsMoved)
+ {
+ 	Relation	classRel;
+ 
  	/* OK, modify the pg_class row and pg_depend entry */
  	classRel = heap_open(RelationRelationId, RowExclusiveLock);
  
! 	AlterRelationNamespaceInternal(classRel, RelationGetRelid(rel), oldNspOid,
! 								   nspOid, true, objsMoved);
  
  	/* Fix the table's row type too */
  	AlterTypeNamespaceInternal(rel->rd_rel->reltype, nspOid, false, false);
***************
*** 9764,9778 **** AlterTableNamespace(AlterObjectSchemaStmt *stmt)
  	if (rel->rd_rel->relkind == RELKIND_RELATION)
  	{
  		AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid);
! 		AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid, stmt->newschema,
! 						   AccessExclusiveLock);
! 		AlterConstraintNamespaces(relid, oldNspOid, nspOid, false);
  	}
  
  	heap_close(classRel, RowExclusiveLock);
- 
- 	/* close rel, but keep lock until commit */
- 	relation_close(rel, NoLock);
  }
  
  /*
--- 9780,9792 ----
  	if (rel->rd_rel->relkind == RELKIND_RELATION)
  	{
  		AlterIndexNamespaces(classRel, rel, oldNspOid, nspOid);
! 		AlterSeqNamespaces(classRel, rel, oldNspOid, nspOid,
! 						   objsMoved, AccessExclusiveLock);
! 		AlterConstraintNamespaces(RelationGetRelid(rel), oldNspOid, nspOid,
! 								  false);
  	}
  
  	heap_close(classRel, RowExclusiveLock);
  }
  
  /*
***************
*** 9783,9789 **** AlterTableNamespace(AlterObjectSchemaStmt *stmt)
  void
  AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry)
  {
  	HeapTuple	classTup;
  	Form_pg_class classForm;
--- 9797,9803 ----
  void
  AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry, ObjectAddresses *objsMoved)
  {
  	HeapTuple	classTup;
  	Form_pg_class classForm;
***************
*** 9795,9821 **** AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  
  	Assert(classForm->relnamespace == oldNspOid);
  
! 	/* check for duplicate name (more friendly than unique-index failure) */
! 	if (get_relname_relid(NameStr(classForm->relname),
! 						  newNspOid) != InvalidOid)
! 		ereport(ERROR,
! 				(errcode(ERRCODE_DUPLICATE_TABLE),
! 				 errmsg("relation \"%s\" already exists in schema \"%s\"",
! 						NameStr(classForm->relname),
! 						get_namespace_name(newNspOid))));
  
! 	/* classTup is a copy, so OK to scribble on */
! 	classForm->relnamespace = newNspOid;
  
! 	simple_heap_update(classRel, &classTup->t_self, classTup);
! 	CatalogUpdateIndexes(classRel, classTup);
  
! 	/* Update dependency on schema if caller said so */
! 	if (hasDependEntry &&
! 		changeDependencyFor(RelationRelationId, relOid,
! 							NamespaceRelationId, oldNspOid, newNspOid) != 1)
! 		elog(ERROR, "failed to change schema dependency for relation \"%s\"",
! 			 NameStr(classForm->relname));
  
  	heap_freetuple(classTup);
  }
--- 9809,9849 ----
  
  	Assert(classForm->relnamespace == oldNspOid);
  
! 	/* Do nothing when there's nothing to do. */
! 	if (classForm->relnamespace != newNspOid)
! 	{
! 		/* check for duplicate name (more friendly than unique-index failure) */
! 		if (get_relname_relid(NameStr(classForm->relname),
! 							  newNspOid) != InvalidOid)
! 			ereport(ERROR,
! 					(errcode(ERRCODE_DUPLICATE_TABLE),
! 					 errmsg("relation \"%s\" already exists in schema \"%s\"",
! 							NameStr(classForm->relname),
! 							get_namespace_name(newNspOid))));
! 
! 		/* classTup is a copy, so OK to scribble on */
! 		classForm->relnamespace = newNspOid;
! 
! 		simple_heap_update(classRel, &classTup->t_self, classTup);
! 		CatalogUpdateIndexes(classRel, classTup);
  
! 		/* Update dependency on schema if caller said so */
! 		if (hasDependEntry &&
! 			changeDependencyFor(RelationRelationId, relOid,
! 								NamespaceRelationId, oldNspOid, newNspOid) != 1)
! 			elog(ERROR, "failed to change schema dependency for relation \"%s\"",
! 				 NameStr(classForm->relname));
  
! 		if (objsMoved)
! 		{
! 			ObjectAddress	thisobj;
  
! 			thisobj.classId = RelationRelationId;
! 			thisobj.objectId = relOid;
! 			thisobj.objectSubId = 0;
! 			add_exact_object_address(&thisobj, objsMoved);
! 		}
! 	}
  
  	heap_freetuple(classTup);
  }
***************
*** 9846,9852 **** AlterIndexNamespaces(Relation classRel, Relation rel,
  		 */
  		AlterRelationNamespaceInternal(classRel, indexOid,
  									   oldNspOid, newNspOid,
! 									   false);
  	}
  
  	list_free(indexList);
--- 9874,9880 ----
  		 */
  		AlterRelationNamespaceInternal(classRel, indexOid,
  									   oldNspOid, newNspOid,
! 									   false, NULL);
  	}
  
  	list_free(indexList);
***************
*** 9861,9867 **** AlterIndexNamespaces(Relation classRel, Relation rel,
   */
  static void
  AlterSeqNamespaces(Relation classRel, Relation rel,
! 	 Oid oldNspOid, Oid newNspOid, const char *newNspName, LOCKMODE lockmode)
  {
  	Relation	depRel;
  	SysScanDesc scan;
--- 9889,9896 ----
   */
  static void
  AlterSeqNamespaces(Relation classRel, Relation rel,
! 				   Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
! 				   LOCKMODE lockmode)
  {
  	Relation	depRel;
  	SysScanDesc scan;
***************
*** 9913,9919 **** AlterSeqNamespaces(Relation classRel, Relation rel,
  		/* Fix the pg_class and pg_depend entries */
  		AlterRelationNamespaceInternal(classRel, depForm->objid,
  									   oldNspOid, newNspOid,
! 									   true);
  
  		/*
  		 * Sequences have entries in pg_type. We need to be careful to move
--- 9942,9948 ----
  		/* Fix the pg_class and pg_depend entries */
  		AlterRelationNamespaceInternal(classRel, depForm->objid,
  									   oldNspOid, newNspOid,
! 									   true, objsMoved);
  
  		/*
  		 * Sequences have entries in pg_type. We need to be careful to move
diff --git a/src/backend/commands/typecindex 88e4287..817384c 100644
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
***************
*** 3448,3454 **** AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
  
  		AlterRelationNamespaceInternal(classRel, typform->typrelid,
  									   oldNspOid, nspOid,
! 									   false);
  
  		heap_close(classRel, RowExclusiveLock);
  
--- 3448,3454 ----
  
  		AlterRelationNamespaceInternal(classRel, typform->typrelid,
  									   oldNspOid, nspOid,
! 									   false, NULL);
  
  		heap_close(classRel, RowExclusiveLock);
  
diff --git a/src/include/commands/alteindex 210cf4e..22ae167 100644
*** a/src/include/commands/alter.h
--- b/src/include/commands/alter.h
***************
*** 14,25 ****
  #ifndef ALTER_H
  #define ALTER_H
  
  #include "utils/acl.h"
  #include "utils/relcache.h"
  
  extern void ExecRenameStmt(RenameStmt *stmt);
  extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt);
! extern Oid	AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid);
  extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId,
  					 Oid objid, Oid nspOid,
  					 int Anum_name, int Anum_namespace, int Anum_owner,
--- 14,27 ----
  #ifndef ALTER_H
  #define ALTER_H
  
+ #include "catalog/dependency.h"
  #include "utils/acl.h"
  #include "utils/relcache.h"
  
  extern void ExecRenameStmt(RenameStmt *stmt);
  extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt);
! extern Oid	AlterObjectNamespace_oid(Oid classId, Oid objid, Oid nspOid,
! 									 ObjectAddresses *objsMoved);
  extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId,
  					 Oid objid, Oid nspOid,
  					 int Anum_name, int Anum_namespace, int Anum_owner,
diff --git a/src/include/commands/tindex 15d4713..4f32062 100644
*** a/src/include/commands/tablecmds.h
--- b/src/include/commands/tablecmds.h
***************
*** 15,20 ****
--- 15,21 ----
  #define TABLECMDS_H
  
  #include "access/htup.h"
+ #include "catalog/dependency.h"
  #include "nodes/parsenodes.h"
  #include "storage/lock.h"
  #include "utils/relcache.h"
***************
*** 36,44 **** extern void AlterTableInternal(Oid relid, List *cmds, bool recurse);
  
  extern void AlterTableNamespace(AlterObjectSchemaStmt *stmt);
  
  extern void AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry);
  
  extern void CheckTableNotInUse(Relation rel, const char *stmt);
  
--- 37,49 ----
  
  extern void AlterTableNamespace(AlterObjectSchemaStmt *stmt);
  
+ extern void AlterTableNamespaceInternal(Relation rel, Oid oldNspOid,
+ 							Oid nspOid, ObjectAddresses *objsMoved);
+ 
  extern void AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry,
! 							   ObjectAddresses *objsMoved);
  
  extern void CheckTableNotInUse(Relation rel, const char *stmt);
  
