Tom Lane <t...@sss.pgh.pa.us> writes:
> I've been testing this patch with an extension having this definition
> file:

Side note: as soon as we have CREATE EXTENSION AS $$ script $$; we will
be able to add those cases as regression tests. That's not the main
usage of that feature, by far, but I can't resits the occasion :)

> -----
> create table t1(f1 serial primary key, f2 text);
>
> create table t2(f1 int primary key, f2 text);
>
> create sequence ss2;
>
> alter sequence ss2 owned by t2.f1;
>
> create sequence ss3;
>
> create table t3(f1 int primary key, f2 text);
>
> alter sequence ss3 owned by t3.f1;
> -----

This exact same script pass with the attached patch, a patch on top
Álvaro's version:

    dim=# create extension extseq;
    CREATE EXTENSION
    dim=# create schema foo;
    CREATE SCHEMA
    dim=# alter extension extseq set schema foo;
    ALTER EXTENSION
    dim=# \dx+ extseq
    Objects in extension "extseq"
       Object Description   
    ------------------------
     sequence foo.ss2
     sequence foo.ss3
     sequence foo.t1_f1_seq
     table foo.t1
     table foo.t2
     table foo.t3
    (6 rows)

I have some local failures in `make check` that I'm not sure originate
from that patch. Still wanted to have an opinion about the idea before
cleaning up.

> nothing if the sequence was already moved.  We could maybe refactor
> so that AlterRelationNamespaceInternal's test covers the type case too,
> but I don't think that is the way forward, because it won't cover any
> non-sequence cases where a type is reached through two different
> dependency paths.

I tried to care about that in the attached. Spent so much time rolling
it in my head in every possible angle that I really need another pair of
eyes on it though.

> So it appears to me that a real fix involves extending the check and
> add logic to at least relations and types, and perhaps eventually to
> everything that AlterObjectNamespace_oid can call.  That's fairly
> invasive, especially if we try to do the whole nine yards immediately.
> But perhaps for now we need only fix the relation and type cases.

I think INDEX and CONSTRAINTS (the only other things that can be called
from that point) are safe because there's no explicit support for them
in the AlterObjectNamespace_oid() function.

> BTW, I experimented with inserting CommandCounterIncrement calls
> into the AlterExtensionNamespace loop, and eventually decided that
> that's probably not the best path to a solution.  The killer problem is
> that it messes up the logic in AlterExtensionNamespace that tries to
> verify that all the objects had been in the same namespace.  If the
> subroutines report that the object is now in the target namespace,
> is that okay or not?  You can't tell.

Agreed.

> I think that the right way to proceed is to *not* do
> CommandCounterIncrement in the AlterExtensionNamespace loop, and also
> *not* have a test in AlterExtensionNamespace for an object already
> having been moved.  Rather, since we already know we need that test down
> in AlterRelationNamespaceInternal and AlterTypeNamespaceInternal, do it
> only at that level.  This combination of choices ensures that we'll get
> back valid reports of the old namespace for each object, and so the
> are-they-all-the-same logic in AlterExtensionNamespace still works.

See attached.

Regards,
-- 
Dimitri Fontaine
http://2ndQuadrant.fr     PostgreSQL : Expertise, Formation et Support

*** 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;
*** 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);
*** 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,9778 **** 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);
  
  	/* Fix other dependent stuff */
  	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);
  }
  
  /*
--- 9751,9801 ----
  	/* 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.
+  *
+  * That function can be part of implementing ALTER EXTENSION SET SCHEMA, and
+  * direct dependencies in an extension include both sequences and types:
+  * tracking needs to be passed down those.
+  *
+  * To list which objects need further tracking and check why indexes and
+  * constraint are ok here, see src/backend/commands/alter.c
+  * AlterObjectNamespace_oid() function and its switch.
+  */
+ 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, objsMoved);
  
  	/* Fix other dependent stuff */
  	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,9792 **** AlterTableNamespace(AlterObjectSchemaStmt *stmt)
  void
  AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry)
  {
  	HeapTuple	classTup;
  	Form_pg_class classForm;
  
  	classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
  	if (!HeapTupleIsValid(classTup))
--- 9806,9816 ----
  void
  AlterRelationNamespaceInternal(Relation classRel, Oid relOid,
  							   Oid oldNspOid, Oid newNspOid,
! 							   bool hasDependEntry, ObjectAddresses *objsMoved)
  {
  	HeapTuple	classTup;
  	Form_pg_class classForm;
+ 	ObjectAddress	thisobj;
  
  	classTup = SearchSysCacheCopy1(RELOID, ObjectIdGetDatum(relOid));
  	if (!HeapTupleIsValid(classTup))
***************
*** 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);
  }
--- 9819,9865 ----
  
  	Assert(classForm->relnamespace == oldNspOid);
  
! 	/* we need thisobj for tracking with objsMoved */
! 	if (objsMoved)
! 	{
! 		thisobj.classId = RelationRelationId;
! 		thisobj.objectId = relOid;
! 		thisobj.objectSubId = 0;
! 	}
! 
! 	/*
! 	  Do nothing when there's nothing to do. Note that currently the relation
! 	  shouldn't already be in objsMoved, as this function is only called for
! 	  plain relations and we have no dependency path leading to them.
! 	 */
! 	if (classForm->relnamespace != newNspOid
! 		&& (objsMoved && !object_address_present(&thisobj, objsMoved)))
! 	{
! 		/* 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)
! 			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);
--- 9890,9896 ----
  		 */
  		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;
--- 9905,9912 ----
   */
  static void
  AlterSeqNamespaces(Relation classRel, Relation rel,
! 				   Oid oldNspOid, Oid newNspOid, ObjectAddresses *objsMoved,
! 				   LOCKMODE lockmode)
  {
  	Relation	depRel;
  	SysScanDesc scan;
***************
*** 9913,9926 **** 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
  		 * them to the new namespace, too.
  		 */
  		AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
! 								   newNspOid, false, false);
  
  		/* Now we can close it.  Keep the lock till end of transaction. */
  		relation_close(seqRel, NoLock);
--- 9958,9971 ----
  		/* 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
  		 * them to the new namespace, too.
  		 */
  		AlterTypeNamespaceInternal(RelationGetForm(seqRel)->reltype,
! 								   newNspOid, false, false, objsMoved);
  
  		/* Now we can close it.  Keep the lock till end of transaction. */
  		relation_close(seqRel, NoLock);
*** a/src/backend/commands/typecmds.c
--- b/src/backend/commands/typecmds.c
***************
*** 3360,3366 **** AlterTypeNamespace_oid(Oid typeOid, Oid nspOid)
  						 format_type_be(elemOid))));
  
  	/* and do the work */
! 	return AlterTypeNamespaceInternal(typeOid, nspOid, false, true);
  }
  
  /*
--- 3360,3366 ----
  						 format_type_be(elemOid))));
  
  	/* and do the work */
! 	return AlterTypeNamespaceInternal(typeOid, nspOid, false, true, NULL);
  }
  
  /*
***************
*** 3381,3387 **** AlterTypeNamespace_oid(Oid typeOid, Oid nspOid)
  Oid
  AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
  						   bool isImplicitArray,
! 						   bool errorOnTableType)
  {
  	Relation	rel;
  	HeapTuple	tup;
--- 3381,3388 ----
  Oid
  AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
  						   bool isImplicitArray,
! 						   bool errorOnTableType,
! 						   ObjectAddresses *objsMoved)
  {
  	Relation	rel;
  	HeapTuple	tup;
***************
*** 3389,3394 **** AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
--- 3390,3416 ----
  	Oid			oldNspOid;
  	Oid			arrayOid;
  	bool		isCompositeType;
+ 	ObjectAddress	thisobj;
+ 
+ 	if (objsMoved)
+ 	{
+ 		/*
+ 		 * When doing ALTER EXTENSION SET SCHEMA, we follow dependencies, and
+ 		 * more than one path leads to types. Check that we didn't cross this
+ 		 * one previously.
+ 		 */
+ 		thisobj.classId = TypeRelationId;
+ 		thisobj.objectId = typeOid;
+ 		thisobj.objectSubId = 0;
+ 
+ 		if( object_address_present(&thisobj, objsMoved))
+ 			/*
+ 			 * We don't have the old namespace OID arround as soon as
+ 			 * CommandCounterIncrement() has been done, which we have no way to
+ 			 * know about from here.
+ 			 */
+ 			return InvalidOid;
+ 	}
  
  	rel = heap_open(TypeRelationId, RowExclusiveLock);
  
***************
*** 3449,3455 **** AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
  
  		AlterRelationNamespaceInternal(classRel, typform->typrelid,
  									   oldNspOid, nspOid,
! 									   false);
  
  		heap_close(classRel, RowExclusiveLock);
  
--- 3471,3477 ----
  
  		AlterRelationNamespaceInternal(classRel, typform->typrelid,
  									   oldNspOid, nspOid,
! 									   false, NULL);
  
  		heap_close(classRel, RowExclusiveLock);
  
***************
*** 3482,3490 **** AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
  
  	heap_close(rel, RowExclusiveLock);
  
  	/* Recursively alter the associated array type, if any */
  	if (OidIsValid(arrayOid))
! 		AlterTypeNamespaceInternal(arrayOid, nspOid, true, true);
  
  	return oldNspOid;
  }
--- 3504,3515 ----
  
  	heap_close(rel, RowExclusiveLock);
  
+ 	if (objsMoved)
+ 		add_exact_object_address(&thisobj, objsMoved);
+ 
  	/* Recursively alter the associated array type, if any */
  	if (OidIsValid(arrayOid))
! 		AlterTypeNamespaceInternal(arrayOid, nspOid, true, true, objsMoved);
  
  	return oldNspOid;
  }
*** 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,
*** 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);
  
*** a/src/include/commands/typecmds.h
--- b/src/include/commands/typecmds.h
***************
*** 47,53 **** extern void AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId,
  extern void AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype);
  extern Oid	AlterTypeNamespace_oid(Oid typeOid, Oid nspOid);
  extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
! 						   bool isImplicitArray,
! 						   bool errorOnTableType);
  
  #endif   /* TYPECMDS_H */
--- 47,54 ----
  extern void AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype);
  extern Oid	AlterTypeNamespace_oid(Oid typeOid, Oid nspOid);
  extern Oid AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
! 									  bool isImplicitArray,
! 									  bool errorOnTableType,
! 									  ObjectAddresses *objsMoved);
  
  #endif   /* TYPECMDS_H */
-- 
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Reply via email to