Robert Haas <robertmh...@gmail.com> writes:
> Please do.  Tab completion support should really be included in the
> patch - adding it as a separate patch is better than not having it, of
> course.

Please find attached version 9 of the patch, which includes psql
completion support of the "SET SCHEMA" variant of already supported
ALTER commands.

That means I didn't add ALTER OPERATOR [CLASS,FAMILY] completion
support, my guess being there's no demand here, or the existing syntax
variants would be there already. And if there's demand, I don't feel
like it should be implemented as part of this very patch.

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

*** a/doc/src/sgml/ref/alter_conversion.sgml
--- b/doc/src/sgml/ref/alter_conversion.sgml
***************
*** 23,28 **** PostgreSQL documentation
--- 23,29 ----
  <synopsis>
  ALTER CONVERSION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
  ALTER CONVERSION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+ ALTER CONVERSION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 75,80 **** ALTER CONVERSION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner
--- 76,90 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema of the conversion.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </refsect1>
  
*** a/doc/src/sgml/ref/alter_opclass.sgml
--- b/doc/src/sgml/ref/alter_opclass.sgml
***************
*** 23,28 **** PostgreSQL documentation
--- 23,29 ----
  <synopsis>
  ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable>
  ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+ ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 85,90 **** ALTER OPERATOR CLASS <replaceable>name</replaceable> USING <replaceable class="p
--- 86,100 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema for the operator class.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
   </refsect1>
  
*** a/doc/src/sgml/ref/alter_operator.sgml
--- b/doc/src/sgml/ref/alter_operator.sgml
***************
*** 22,27 **** PostgreSQL documentation
--- 22,28 ----
   <refsynopsisdiv>
  <synopsis>
  ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) OWNER TO <replaceable>new_owner</replaceable>
+ ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</replaceable> | NONE } , { <replaceable>right_type</replaceable> | NONE } ) SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 85,90 **** ALTER OPERATOR <replaceable>name</replaceable> ( { <replaceable>left_type</repla
--- 86,100 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema of the operator.
+      </para>
+     </listitem>
+    </varlistentry>
    </variablelist>
   </refsect1>
  
*** a/doc/src/sgml/ref/alter_opfamily.sgml
--- b/doc/src/sgml/ref/alter_opfamily.sgml
***************
*** 31,36 **** ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="
--- 31,37 ----
    } [, ... ]
  ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> RENAME TO <replaceable>new_name</replaceable>
  ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+ ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="parameter">index_method</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 216,221 **** ALTER OPERATOR FAMILY <replaceable>name</replaceable> USING <replaceable class="
--- 217,231 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema for the operator family.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
  
    <para>
*** a/doc/src/sgml/ref/alter_tsconfig.sgml
--- b/doc/src/sgml/ref/alter_tsconfig.sgml
***************
*** 33,38 **** ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable>
--- 33,39 ----
      DROP MAPPING [ IF EXISTS ] FOR <replaceable class="parameter">token_type</replaceable> [, ... ]
  ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
  ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+ ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 123,128 **** ALTER TEXT SEARCH CONFIGURATION <replaceable>name</replaceable> OWNER TO <replac
--- 124,138 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema for the text search configuration.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
  
    <para>
*** a/doc/src/sgml/ref/alter_tsdictionary.sgml
--- b/doc/src/sgml/ref/alter_tsdictionary.sgml
***************
*** 26,31 **** ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> (
--- 26,32 ----
  )
  ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
  ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO <replaceable>new_owner</replaceable>
+ ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 96,101 **** ALTER TEXT SEARCH DICTIONARY <replaceable>name</replaceable> OWNER TO <replaceab
--- 97,111 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema of the text search dictionary.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
  
    <para>
*** a/doc/src/sgml/ref/alter_tsparser.sgml
--- b/doc/src/sgml/ref/alter_tsparser.sgml
***************
*** 22,27 **** PostgreSQL documentation
--- 22,28 ----
   <refsynopsisdiv>
  <synopsis>
  ALTER TEXT SEARCH PARSER <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ ALTER TEXT SEARCH PARSER <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 60,65 **** ALTER TEXT SEARCH PARSER <replaceable>name</replaceable> RENAME TO <replaceable>
--- 61,75 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema of the text search parser.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
   </refsect1>
  
*** a/doc/src/sgml/ref/alter_tstemplate.sgml
--- b/doc/src/sgml/ref/alter_tstemplate.sgml
***************
*** 22,27 **** PostgreSQL documentation
--- 22,28 ----
   <refsynopsisdiv>
  <synopsis>
  ALTER TEXT SEARCH TEMPLATE <replaceable>name</replaceable> RENAME TO <replaceable>new_name</replaceable>
+ ALTER TEXT SEARCH TEMPLATE <replaceable>name</replaceable> SET SCHEMA <replaceable>new_schema</replaceable>
  </synopsis>
   </refsynopsisdiv>
  
***************
*** 60,65 **** ALTER TEXT SEARCH TEMPLATE <replaceable>name</replaceable> RENAME TO <replaceabl
--- 61,75 ----
       </para>
      </listitem>
     </varlistentry>
+ 
+    <varlistentry>
+     <term><replaceable class="parameter">new_schema</replaceable></term>
+     <listitem>
+      <para>
+       The new schema of the text search template.
+      </para>
+     </listitem>
+    </varlistentry>
   </variablelist>
   </refsect1>
  
*** a/src/backend/commands/alter.c
--- b/src/backend/commands/alter.c
***************
*** 14,21 ****
--- 14,23 ----
   */
  #include "postgres.h"
  
+ #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_largeobject.h"
+ #include "catalog/pg_namespace.h"
  #include "commands/alter.h"
  #include "commands/conversioncmds.h"
  #include "commands/dbcommands.h"
***************
*** 33,38 ****
--- 35,41 ----
  #include "utils/acl.h"
  #include "utils/builtins.h"
  #include "utils/lsyscache.h"
+ #include "utils/syscache.h"
  
  
  /*
***************
*** 178,188 **** ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
--- 181,207 ----
  								   stmt->newschema);
  			break;
  
+ 		case OBJECT_CONVERSION:
+ 			AlterConversionNamespace(stmt->object, stmt->newschema);
+ 			break;
+ 
  		case OBJECT_FUNCTION:
  			AlterFunctionNamespace(stmt->object, stmt->objarg, false,
  								   stmt->newschema);
  			break;
  
+ 		case OBJECT_OPERATOR:
+ 			AlterOperatorNamespace(stmt->object, stmt->objarg, stmt->newschema);
+ 			break;
+ 
+ 		case OBJECT_OPCLASS:
+ 			AlterOpClassNamespace(stmt->object, stmt->objarg, stmt->newschema);
+ 			break;
+ 
+ 		case OBJECT_OPFAMILY:
+ 			AlterOpFamilyNamespace(stmt->object, stmt->objarg, stmt->newschema);
+ 			break;
+ 
  		case OBJECT_SEQUENCE:
  		case OBJECT_TABLE:
  		case OBJECT_VIEW:
***************
*** 191,196 **** ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
--- 210,231 ----
  								stmt->objectType, AccessExclusiveLock);
  			break;
  
+ 		case OBJECT_TSPARSER:
+ 			AlterTSParserNamespace(stmt->object, stmt->newschema);
+ 			break;
+ 
+ 		case OBJECT_TSDICTIONARY:
+ 			AlterTSDictionaryNamespace(stmt->object, stmt->newschema);
+ 			break;
+ 
+ 		case OBJECT_TSTEMPLATE:
+ 			AlterTSTemplateNamespace(stmt->object, stmt->newschema);
+ 			break;
+ 
+ 		case OBJECT_TSCONFIGURATION:
+ 			AlterTSConfigurationNamespace(stmt->object, stmt->newschema);
+ 			break;
+ 
  		case OBJECT_TYPE:
  		case OBJECT_DOMAIN:
  			AlterTypeNamespace(stmt->object, stmt->newschema);
***************
*** 203,208 **** ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt)
--- 238,337 ----
  }
  
  /*
+  * Generic function to change the namespace of a given object, for simple
+  * cases (won't work for tables or functions, objects which have more than 2
+  * key-attributes to use when searching for their syscache entries --- we
+  * don't want nor need to get this generic here).
+  *
+  * The AlterFooNamespace() calls just above will call a function whose job
+  * is to lookup the arguments for the generic function here.
+  *
+  * Relation must already by open, it's the responsibility of the caller to
+  * close it.
+  */
+ void
+ AlterObjectNamespace(Relation rel, int cacheId,
+ 					 Oid classId, Oid objid, Oid nspOid,
+ 					 int Anum_name, int Anum_namespace, int Anum_owner,
+ 					 AclObjectKind acl_kind,
+ 					 bool superuser_only)
+ {
+ 	Oid			oldNspOid;
+ 	Datum       name, namespace;
+ 	bool        isnull;
+ 	HeapTuple	tup, newtup = NULL;
+ 	Datum		values[rel->rd_att->natts];
+ 	bool		nulls[rel->rd_att->natts];
+ 	bool		replaces[rel->rd_att->natts];
+ 	int			i;
+ 
+ 	tup = SearchSysCacheCopy1(cacheId, ObjectIdGetDatum(objid));
+ 	if (!HeapTupleIsValid(tup)) /* should not happen */
+ 		elog(ERROR, "cache lookup failed for object %u: %s",
+ 			 objid, getObjectDescriptionOids(classId, objid));
+ 
+ 	name = heap_getattr(tup, Anum_name, rel->rd_att, &isnull);
+ 	namespace = heap_getattr(tup, Anum_namespace, rel->rd_att, &isnull);
+ 	oldNspOid = DatumGetObjectId(namespace);
+ 
+ 	/* Check basic namespace related issues */
+ 	CheckSetNamespace(oldNspOid, nspOid, classId, objid);
+ 
+ 	/* check for duplicate name (more friendly than unique-index failure) */
+ 	if (SearchSysCacheExists2(cacheId, name, ObjectIdGetDatum(nspOid)))
+ 		ereport(ERROR,
+ 				(errcode(ERRCODE_DUPLICATE_OBJECT),
+ 				 errmsg("%s already exists in schema \"%s\"",
+ 						getObjectDescriptionOids(classId, objid),
+ 						get_namespace_name(nspOid))));
+ 
+ 	/* Superusers can always do it */
+ 	if (!superuser())
+ 	{
+ 		Datum       owner;
+ 		Oid			ownerId;
+ 		AclResult	aclresult;
+ 
+ 		if (superuser_only)
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+ 					 (errmsg("must be superuser to SET SCHEMA of %s",
+ 							 getObjectDescriptionOids(classId, objid)))));
+ 
+ 		/* Otherwise, must be owner of the existing object */
+ 		owner = heap_getattr(tup, Anum_owner, rel->rd_att, &isnull);
+ 		ownerId = DatumGetObjectId(owner);
+ 
+ 		if (!has_privs_of_role(GetUserId(), ownerId))
+ 			aclcheck_error(ACLCHECK_NOT_OWNER, acl_kind,
+ 						   NameStr(*(DatumGetName(name))));
+ 
+ 		/* owner must have CREATE privilege on namespace */
+ 		aclresult = pg_namespace_aclcheck(oldNspOid, GetUserId(), ACL_CREATE);
+ 		if (aclresult != ACLCHECK_OK)
+ 			aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
+ 						   get_namespace_name(oldNspOid));
+ 	}
+ 
+ 	/* prepare a new version of the tuple using nspId */
+ 	values[Anum_namespace - 1] = nspOid;
+ 	for (i = 0; i < rel->rd_att->natts; i++)
+ 	{
+ 		nulls[i]    = i != Anum_namespace - 1;
+ 		replaces[i] = i == Anum_namespace - 1;
+ 	}
+ 
+ 	newtup = heap_modify_tuple(tup, rel->rd_att, values, nulls, replaces);
+ 	simple_heap_update(rel, &tup->t_self, newtup);
+ 	CatalogUpdateIndexes(rel, newtup);
+ 
+ 	/* update dependencies to point to the new schema */
+ 	changeDependencyFor(classId, objid,
+ 						NamespaceRelationId, oldNspOid, nspOid);
+ }
+ 
+ 
+ /*
   * Executes an ALTER OBJECT / OWNER TO statement.  Based on the object
   * type, the function appropriate to that type is executed.
   */
*** a/src/backend/commands/conversioncmds.c
--- b/src/backend/commands/conversioncmds.c
***************
*** 19,25 ****
--- 19,27 ----
  #include "catalog/indexing.h"
  #include "catalog/pg_conversion.h"
  #include "catalog/pg_conversion_fn.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_type.h"
+ #include "commands/alter.h"
  #include "commands/conversioncmds.h"
  #include "mb/pg_wchar.h"
  #include "miscadmin.h"
***************
*** 30,36 ****
  #include "utils/rel.h"
  #include "utils/syscache.h"
  
! static void AlterConversionOwner_internal(Relation rel, Oid conversionOid,
  							  Oid newOwnerId);
  
  /*
--- 32,38 ----
  #include "utils/rel.h"
  #include "utils/syscache.h"
  
! static void AlterConversionOwner_internal(Relation rel, Oid convOid,
  							  Oid newOwnerId);
  
  /*
***************
*** 326,328 **** AlterConversionOwner_internal(Relation rel, Oid conversionOid, Oid newOwnerId)
--- 328,376 ----
  
  	heap_freetuple(tup);
  }
+ 
+ /*
+  * Execute ALTER CONVERSION SET SCHEMA
+  */
+ void
+ AlterConversionNamespace(List *name, const char *newschema)
+ {
+ 	Oid			convOid, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
+ 
+ 	convOid = get_conversion_oid(name, false);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, CONVOID, ConversionRelationId, convOid, nspOid,
+ 						 Anum_pg_conversion_conname,
+ 						 Anum_pg_conversion_connamespace,
+ 						 Anum_pg_conversion_conowner,
+ 						 ACL_KIND_CONVERSION,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ /*
+  * Change conversion schema, by oid
+  */
+ void
+ AlterConversionNamespace_oid(Oid convOid, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(ConversionRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, CONVOID, ConversionRelationId, convOid, newNspOid,
+ 						 Anum_pg_conversion_conname,
+ 						 Anum_pg_conversion_connamespace,
+ 						 Anum_pg_conversion_conowner,
+ 						 ACL_KIND_CONVERSION,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
*** a/src/backend/commands/functioncmds.c
--- b/src/backend/commands/functioncmds.c
***************
*** 1875,1887 **** AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
  					   const char *newschema)
  {
  	Oid			procOid;
- 	Oid			oldNspOid;
  	Oid			nspOid;
- 	HeapTuple	tup;
- 	Relation	procRel;
- 	Form_pg_proc proc;
- 
- 	procRel = heap_open(ProcedureRelationId, RowExclusiveLock);
  
  	/* get function OID */
  	if (isagg)
--- 1875,1881 ----
***************
*** 1894,1899 **** AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
--- 1888,1908 ----
  		aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC,
  					   NameListToString(name));
  
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterFunctionNamespace_oid(procOid, nspOid);
+ }
+ 
+ void
+ AlterFunctionNamespace_oid(Oid procOid, Oid nspOid)
+ {
+ 	Oid			oldNspOid;
+ 	HeapTuple	tup;
+ 	Relation	procRel;
+ 	Form_pg_proc proc;
+ 
+ 	procRel = heap_open(ProcedureRelationId, RowExclusiveLock);
+ 
  	tup = SearchSysCacheCopy1(PROCOID, ObjectIdGetDatum(procOid));
  	if (!HeapTupleIsValid(tup))
  		elog(ERROR, "cache lookup failed for function %u", procOid);
***************
*** 1901,1909 **** AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
  
  	oldNspOid = proc->pronamespace;
  
- 	/* get schema OID and check its permissions */
- 	nspOid = LookupCreationNamespace(newschema);
- 
  	/* common checks on switching namespaces */
  	CheckSetNamespace(oldNspOid, nspOid, ProcedureRelationId, procOid);
  
--- 1910,1915 ----
***************
*** 1916,1922 **** AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
  				(errcode(ERRCODE_DUPLICATE_FUNCTION),
  				 errmsg("function \"%s\" already exists in schema \"%s\"",
  						NameStr(proc->proname),
! 						newschema)));
  
  	/* OK, modify the pg_proc row */
  
--- 1922,1928 ----
  				(errcode(ERRCODE_DUPLICATE_FUNCTION),
  				 errmsg("function \"%s\" already exists in schema \"%s\"",
  						NameStr(proc->proname),
! 						get_namespace_name(nspOid))));
  
  	/* OK, modify the pg_proc row */
  
***************
*** 1930,1936 **** AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
  	if (changeDependencyFor(ProcedureRelationId, procOid,
  							NamespaceRelationId, oldNspOid, nspOid) != 1)
  		elog(ERROR, "failed to change schema dependency for function \"%s\"",
! 			 NameListToString(name));
  
  	heap_freetuple(tup);
  
--- 1936,1942 ----
  	if (changeDependencyFor(ProcedureRelationId, procOid,
  							NamespaceRelationId, oldNspOid, nspOid) != 1)
  		elog(ERROR, "failed to change schema dependency for function \"%s\"",
! 			 NameStr(proc->proname));
  
  	heap_freetuple(tup);
  
*** a/src/backend/commands/opclasscmds.c
--- b/src/backend/commands/opclasscmds.c
***************
*** 31,36 ****
--- 31,37 ----
  #include "catalog/pg_opfamily.h"
  #include "catalog/pg_proc.h"
  #include "catalog/pg_type.h"
+ #include "commands/alter.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_func.h"
***************
*** 1989,1994 **** AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
--- 1990,2057 ----
  }
  
  /*
+  * ALTER OPERATOR CLASS any_name USING access_method SET SCHEMA name
+  */
+ void
+ AlterOpClassNamespace(List *name, List *argam, const char *newschema)
+ {
+ 	Oid			amOid;
+ 	char       *access_method = linitial(argam);
+ 	Relation	rel;
+ 	HeapTuple	tup, origtup;
+ 	Oid			nspOid;
+ 
+ 	Assert(list_length(argam) == 1);
+ 
+ 	amOid = get_am_oid(access_method, false);
+ 
+ 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
+ 
+ 	/* Look up the opclass. */
+ 	origtup = OpClassCacheLookup(amOid, name, false);
+ 	tup = heap_copytuple(origtup);
+ 	ReleaseSysCache(origtup);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, CLAOID, OperatorClassRelationId,
+ 						 HeapTupleGetOid(tup), nspOid,
+ 						 Anum_pg_opfamily_opfname,
+ 						 Anum_pg_opfamily_opfnamespace,
+ 						 Anum_pg_opfamily_opfowner,
+ 						 ACL_KIND_OPCLASS,
+ 						 false);
+ 
+ 	heap_freetuple(tup);
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid)
+ {
+ 	HeapTuple	tup;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(OperatorClassRelationId, RowExclusiveLock);
+ 
+ 	tup = SearchSysCacheCopy1(CLAOID, ObjectIdGetDatum(opclassOid));
+ 	if (!HeapTupleIsValid(tup))
+ 		elog(ERROR, "cache lookup failed for opclass %u", opclassOid);
+ 
+ 	AlterObjectNamespace(rel, CLAOID, OperatorClassRelationId,
+ 						 HeapTupleGetOid(tup), newNspOid,
+ 						 Anum_pg_opfamily_opfname,
+ 						 Anum_pg_opfamily_opfnamespace,
+ 						 Anum_pg_opfamily_opfowner,
+ 						 ACL_KIND_OPCLASS,
+ 						 false);
+ 
+ 	heap_freetuple(tup);
+ 	heap_close(rel, NoLock);
+ }
+ 
+ /*
   * Change opfamily owner by name
   */
  void
***************
*** 2144,2146 **** get_am_oid(const char *amname, bool missing_ok)
--- 2207,2303 ----
  				 errmsg("access method \"%s\" does not exist", amname)));
  	return oid;
  }
+ 
+ /*
+  * ALTER OPERATOR FAMILY any_name USING access_method SET SCHEMA name
+  */
+ void
+ AlterOpFamilyNamespace(List *name, List *argam, const char *newschema)
+ {
+ 	Oid			amOid;
+ 	char       *access_method = linitial(argam);
+ 	Relation	rel;
+ 	HeapTuple	tup;
+ 	char	   *opfname, *schemaname;
+ 	Oid			nspOid;
+ 
+ 	Assert(list_length(argam) == 1);
+ 	amOid = get_am_oid(access_method, false);
+ 
+ 	rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
+ 
+ 	/*
+ 	 * Look up the opfamily
+ 	 */
+ 	DeconstructQualifiedName(name, &schemaname, &opfname);
+ 
+ 	if (schemaname)
+ 	{
+ 		Oid			namespaceOid;
+ 
+ 		namespaceOid = LookupExplicitNamespace(schemaname);
+ 
+ 		tup = SearchSysCacheCopy3(OPFAMILYAMNAMENSP,
+ 								  ObjectIdGetDatum(amOid),
+ 								  PointerGetDatum(opfname),
+ 								  ObjectIdGetDatum(namespaceOid));
+ 		if (!HeapTupleIsValid(tup))
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+ 							opfname, access_method)));
+ 	}
+ 	else
+ 	{
+ 		Oid			opfOid;
+ 
+ 		opfOid = OpfamilynameGetOpfid(amOid, opfname);
+ 		if (!OidIsValid(opfOid))
+ 			ereport(ERROR,
+ 					(errcode(ERRCODE_UNDEFINED_OBJECT),
+ 					 errmsg("operator family \"%s\" does not exist for access method \"%s\"",
+ 							opfname, access_method)));
+ 
+ 		tup = SearchSysCacheCopy1(OPFAMILYOID, ObjectIdGetDatum(opfOid));
+ 		if (!HeapTupleIsValid(tup))		/* should not happen */
+ 			elog(ERROR, "cache lookup failed for opfamily %u", opfOid);
+ 	}
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, OPFAMILYOID, OperatorFamilyRelationId,
+ 						 HeapTupleGetOid(tup), nspOid,
+ 						 Anum_pg_opfamily_opfname,
+ 						 Anum_pg_opfamily_opfnamespace,
+ 						 Anum_pg_opfamily_opfowner,
+ 						 ACL_KIND_OPFAMILY,
+ 						 false);
+ 
+ 	heap_freetuple(tup);
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid)
+ {
+ 	HeapTuple	tup;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(OperatorFamilyRelationId, RowExclusiveLock);
+ 
+ 	tup = SearchSysCacheCopy1(OPFAMILYOID, ObjectIdGetDatum(opfamilyOid));
+ 	if (!HeapTupleIsValid(tup))
+ 		elog(ERROR, "cache lookup failed for opfamily %u", opfamilyOid);
+ 
+ 	AlterObjectNamespace(rel, OPFAMILYOID, OperatorFamilyRelationId,
+ 						 opfamilyOid, newNspOid,
+ 						 Anum_pg_opfamily_opfname,
+ 						 Anum_pg_opfamily_opfnamespace,
+ 						 Anum_pg_opfamily_opfowner,
+ 						 ACL_KIND_OPFAMILY,
+ 						 false);
+ 
+ 	heap_freetuple(tup);
+ 	heap_close(rel, NoLock);
+ }
*** a/src/backend/commands/operatorcmds.c
--- b/src/backend/commands/operatorcmds.c
***************
*** 39,45 ****
--- 39,47 ----
  #include "catalog/indexing.h"
  #include "catalog/namespace.h"
  #include "catalog/pg_operator.h"
+ #include "catalog/pg_namespace.h"
  #include "catalog/pg_type.h"
+ #include "commands/alter.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "parser/parse_func.h"
***************
*** 452,454 **** AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid newOwnerId)
--- 454,505 ----
  
  	heap_freetuple(tup);
  }
+ 
+ /*
+  * Execute ALTER OPERATOR SET SCHEMA
+  */
+ void
+ AlterOperatorNamespace(List *names, List *argtypes, const char *newschema)
+ {
+ 	List	   *operatorName = names;
+ 	TypeName   *typeName1 = (TypeName *) linitial(argtypes);
+ 	TypeName   *typeName2 = (TypeName *) lsecond(argtypes);
+ 	Oid			operOid, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(OperatorRelationId, RowExclusiveLock);
+ 
+ 	Assert(list_length(argtypes) == 2);
+ 	operOid = LookupOperNameTypeNames(NULL, operatorName,
+ 									  typeName1, typeName2,
+ 									  false, -1);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, OPEROID, OperatorRelationId, operOid, nspOid,
+ 						 Anum_pg_operator_oprname,
+ 						 Anum_pg_operator_oprnamespace,
+ 						 Anum_pg_operator_oprowner,
+ 						 ACL_KIND_OPER,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(OperatorRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, OPEROID, OperatorRelationId, operOid, newNspOid,
+ 						 Anum_pg_operator_oprname,
+ 						 Anum_pg_operator_oprnamespace,
+ 						 Anum_pg_operator_oprowner,
+ 						 ACL_KIND_OPER,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
*** a/src/backend/commands/tsearchcmds.c
--- b/src/backend/commands/tsearchcmds.c
***************
*** 32,37 ****
--- 32,38 ----
  #include "catalog/pg_ts_parser.h"
  #include "catalog/pg_ts_template.h"
  #include "catalog/pg_type.h"
+ #include "commands/alter.h"
  #include "commands/defrem.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
***************
*** 397,402 **** RenameTSParser(List *oldname, const char *newname)
--- 398,442 ----
  	heap_freetuple(tup);
  }
  
+ /*
+  * ALTER TEXT SEARCH PARSER any_name SET SCHEMA name
+  */
+ void
+ AlterTSParserNamespace(List *name, const char *newschema)
+ {
+ 	Oid			prsId, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSParserRelationId, RowExclusiveLock);
+ 
+ 	prsId = get_ts_parser_oid(name, false);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, TSPARSEROID, TSParserRelationId, prsId, nspOid,
+ 						 Anum_pg_ts_parser_prsname,
+ 						 Anum_pg_ts_parser_prsnamespace,
+ 						 -1, -1, true);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSParserRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, TSPARSEROID, TSParserRelationId, prsId, newNspOid,
+ 						 Anum_pg_ts_parser_prsname,
+ 						 Anum_pg_ts_parser_prsnamespace,
+ 						 -1, -1, true);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
  /* ---------------------- TS Dictionary commands -----------------------*/
  
  /*
***************
*** 628,633 **** RenameTSDictionary(List *oldname, const char *newname)
--- 668,716 ----
  }
  
  /*
+  * ALTER TEXT SEARCH PARSER any_name SET SCHEMA name
+  */
+ void
+ AlterTSDictionaryNamespace(List *name, const char *newschema)
+ {
+ 	Oid			dictId, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+ 
+ 	dictId = get_ts_dict_oid(name, false);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, TSDICTOID, TSDictionaryRelationId, dictId, nspOid,
+ 						 Anum_pg_ts_dict_dictname,
+ 						 Anum_pg_ts_dict_dictnamespace,
+ 						 Anum_pg_ts_dict_dictowner,
+ 						 ACL_KIND_TSDICTIONARY,
+ 						 true);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, TSDICTOID, TSDictionaryRelationId, dictId, newNspOid,
+ 						 Anum_pg_ts_dict_dictname,
+ 						 Anum_pg_ts_dict_dictnamespace,
+ 						 Anum_pg_ts_dict_dictowner,
+ 						 ACL_KIND_TSDICTIONARY,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ /*
   * DROP TEXT SEARCH DICTIONARY
   */
  void
***************
*** 1111,1116 **** RenameTSTemplate(List *oldname, const char *newname)
--- 1194,1241 ----
  }
  
  /*
+  * ALTER TEXT SEARCH TEMPLATE any_name SET SCHEMA name
+  */
+ void
+ AlterTSTemplateNamespace(List *name, const char *newschema)
+ {
+ 	Oid			tmplId, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
+ 
+ 	tmplId = get_ts_template_oid(name, false);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, TSTEMPLATEOID, TSTemplateRelationId,
+ 						 tmplId, nspOid,
+ 						 Anum_pg_ts_template_tmplname,
+ 						 Anum_pg_ts_template_tmplnamespace,
+ 						 -1, -1, true);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSTemplateRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, TSTEMPLATEOID, TSTemplateRelationId,
+ 						 tmplId, newNspOid,
+ 						 Anum_pg_ts_template_tmplname,
+ 						 Anum_pg_ts_template_tmplnamespace,
+ 						 -1, -1, true);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ 
+ /*
   * DROP TEXT SEARCH TEMPLATE
   */
  void
***************
*** 1512,1517 **** RenameTSConfiguration(List *oldname, const char *newname)
--- 1637,1686 ----
  }
  
  /*
+  * ALTER TEXT SEARCH CONFIGURATION any_name SET SCHEMA name
+  */
+ void
+ AlterTSConfigurationNamespace(List *name, const char *newschema)
+ {
+ 	Oid			cfgId, nspOid;
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+ 
+ 	cfgId = get_ts_config_oid(name, false);
+ 
+ 	/* get schema OID */
+ 	nspOid = LookupCreationNamespace(newschema);
+ 
+ 	AlterObjectNamespace(rel, TSCONFIGOID, TSConfigRelationId, cfgId, nspOid,
+ 						 Anum_pg_ts_config_cfgname,
+ 						 Anum_pg_ts_config_cfgnamespace,
+ 						 Anum_pg_ts_config_cfgowner,
+ 						 ACL_KIND_TSCONFIGURATION,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ void
+ AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid)
+ {
+ 	Relation	rel;
+ 
+ 	rel = heap_open(TSConfigRelationId, RowExclusiveLock);
+ 
+ 	AlterObjectNamespace(rel, TSCONFIGOID, TSConfigRelationId, cfgId, newNspOid,
+ 						 Anum_pg_ts_config_cfgname,
+ 						 Anum_pg_ts_config_cfgnamespace,
+ 						 Anum_pg_ts_config_cfgowner,
+ 						 ACL_KIND_TSCONFIGURATION,
+ 						 false);
+ 
+ 	heap_close(rel, NoLock);
+ }
+ 
+ 
+ /*
   * DROP TEXT SEARCH CONFIGURATION
   */
  void
*** a/src/backend/parser/gram.y
--- b/src/backend/parser/gram.y
***************
*** 6051,6056 **** AlterObjectSchemaStmt:
--- 6051,6064 ----
  					n->newschema = $7;
  					$$ = (Node *)n;
  				}
+ 			| ALTER CONVERSION_P any_name SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_CONVERSION;
+ 					n->object = $3;
+ 					n->newschema = $6;
+ 					$$ = (Node *)n;
+ 				}
  			| ALTER DOMAIN_P any_name SET SCHEMA name
  				{
  					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
***************
*** 6068,6073 **** AlterObjectSchemaStmt:
--- 6076,6108 ----
  					n->newschema = $6;
  					$$ = (Node *)n;
  				}
+ 			| ALTER OPERATOR any_operator oper_argtypes SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_OPERATOR;
+ 					n->object = $3;
+ 					n->objarg = $4;
+ 					n->newschema = $7;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER OPERATOR CLASS any_name USING access_method SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_OPCLASS;
+ 					n->object = $4;
+ 					n->objarg = list_make1($6);
+ 					n->newschema = $9;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER OPERATOR FAMILY any_name USING access_method SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_OPFAMILY;
+ 					n->object = $4;
+ 					n->objarg = list_make1($6);
+ 					n->newschema = $9;
+ 					$$ = (Node *)n;
+ 				}
  			| ALTER TABLE relation_expr SET SCHEMA name
  				{
  					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
***************
*** 6076,6081 **** AlterObjectSchemaStmt:
--- 6111,6148 ----
  					n->newschema = $6;
  					$$ = (Node *)n;
  				}
+ 			| ALTER TEXT_P SEARCH PARSER any_name SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_TSPARSER;
+ 					n->object = $5;
+ 					n->newschema = $8;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER TEXT_P SEARCH DICTIONARY any_name SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_TSDICTIONARY;
+ 					n->object = $5;
+ 					n->newschema = $8;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER TEXT_P SEARCH TEMPLATE any_name SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_TSTEMPLATE;
+ 					n->object = $5;
+ 					n->newschema = $8;
+ 					$$ = (Node *)n;
+ 				}
+ 			| ALTER TEXT_P SEARCH CONFIGURATION any_name SET SCHEMA name
+ 				{
+ 					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
+ 					n->objectType = OBJECT_TSCONFIGURATION;
+ 					n->object = $5;
+ 					n->newschema = $8;
+ 					$$ = (Node *)n;
+ 				}
  			| ALTER SEQUENCE qualified_name SET SCHEMA name
  				{
  					AlterObjectSchemaStmt *n = makeNode(AlterObjectSchemaStmt);
*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
***************
*** 1694,1702 **** CreateCommandTag(Node *parsetree)
--- 1694,1714 ----
  				case OBJECT_AGGREGATE:
  					tag = "ALTER AGGREGATE";
  					break;
+ 				case OBJECT_CONVERSION:
+ 					tag = "ALTER CONVERSION";
+ 					break;
  				case OBJECT_DOMAIN:
  					tag = "ALTER DOMAIN";
  					break;
+ 				case OBJECT_OPERATOR:
+ 					tag = "ALTER OPERATOR";
+ 					break;
+ 				case OBJECT_OPCLASS:
+ 					tag = "ALTER OPERATOR CLASS";
+ 					break;
+ 				case OBJECT_OPFAMILY:
+ 					tag = "ALTER OPERATOR FAMILY";
+ 					break;
  				case OBJECT_FUNCTION:
  					tag = "ALTER FUNCTION";
  					break;
*** a/src/bin/psql/tab-complete.c
--- b/src/bin/psql/tab-complete.c
***************
*** 741,750 **** psql_completion(char *text, int start, int end)
  		}
  	}
  
! 	/* ALTER CONVERSION,SCHEMA <name> */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
! 			 (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
! 			  pg_strcasecmp(prev2_wd, "SCHEMA") == 0))
  	{
  		static const char *const list_ALTERGEN[] =
  		{"OWNER TO", "RENAME TO", NULL};
--- 741,749 ----
  		}
  	}
  
! 	/* ALTER SCHEMA <name> */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
! 			  pg_strcasecmp(prev2_wd, "SCHEMA") == 0)
  	{
  		static const char *const list_ALTERGEN[] =
  		{"OWNER TO", "RENAME TO", NULL};
***************
*** 752,757 **** psql_completion(char *text, int start, int end)
--- 751,766 ----
  		COMPLETE_WITH_LIST(list_ALTERGEN);
  	}
  
+ 	/* ALTER CONVERSION <name> */
+ 	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
+ 			 pg_strcasecmp(prev2_wd, "CONVERSION") == 0)
+ 	{
+ 		static const char *const list_ALTERGEN[] =
+ 		{"OWNER TO", "RENAME TO", "SET SCHEMA", NULL};
+ 
+ 		COMPLETE_WITH_LIST(list_ALTERGEN);
+ 	}
+ 
  	/* ALTER DATABASE <name> */
  	else if (pg_strcasecmp(prev3_wd, "ALTER") == 0 &&
  			 pg_strcasecmp(prev2_wd, "DATABASE") == 0)
***************
*** 1237,1253 **** psql_completion(char *text, int start, int end)
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 (pg_strcasecmp(prev2_wd, "TEMPLATE") == 0 ||
  			  pg_strcasecmp(prev2_wd, "PARSER") == 0))
! 		COMPLETE_WITH_CONST("RENAME TO");
  
  	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
  			 pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 pg_strcasecmp(prev2_wd, "DICTIONARY") == 0)
  	{
! 		static const char *const list_ALTERTEXTSEARCH2[] =
! 		{"OWNER TO", "RENAME TO", NULL};
  
! 		COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH2);
  	}
  
  	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
--- 1246,1267 ----
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 (pg_strcasecmp(prev2_wd, "TEMPLATE") == 0 ||
  			  pg_strcasecmp(prev2_wd, "PARSER") == 0))
! 	{
! 		static const char *const list_ALTERTEXTSEARCH2[] =
! 		{"RENAME TO", "SET SCHEMA", NULL};
! 
! 		COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH2);
! 	}
  
  	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
  			 pg_strcasecmp(prev4_wd, "TEXT") == 0 &&
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 pg_strcasecmp(prev2_wd, "DICTIONARY") == 0)
  	{
! 		static const char *const list_ALTERTEXTSEARCH3[] =
! 		{"OWNER TO", "RENAME TO", "SET SCHEMA", NULL};
  
! 		COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH3);
  	}
  
  	else if (pg_strcasecmp(prev5_wd, "ALTER") == 0 &&
***************
*** 1255,1264 **** psql_completion(char *text, int start, int end)
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0)
  	{
! 		static const char *const list_ALTERTEXTSEARCH3[] =
! 		{"ADD MAPPING FOR", "ALTER MAPPING", "DROP MAPPING FOR", "OWNER TO", "RENAME TO", NULL};
  
! 		COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH3);
  	}
  
  	/* complete ALTER TYPE <foo> with actions */
--- 1269,1278 ----
  			 pg_strcasecmp(prev3_wd, "SEARCH") == 0 &&
  			 pg_strcasecmp(prev2_wd, "CONFIGURATION") == 0)
  	{
! 		static const char *const list_ALTERTEXTSEARCH4[] =
! 		{"ADD MAPPING FOR", "ALTER MAPPING", "DROP MAPPING FOR", "OWNER TO", "RENAME TO", "SET SCHEMA", NULL};
  
! 		COMPLETE_WITH_LIST(list_ALTERTEXTSEARCH4);
  	}
  
  	/* complete ALTER TYPE <foo> with actions */
*** a/src/include/catalog/dependency.h
--- b/src/include/catalog/dependency.h
***************
*** 167,172 **** extern ObjectClass getObjectClass(const ObjectAddress *object);
--- 167,174 ----
  extern char *getObjectDescription(const ObjectAddress *object);
  extern char *getObjectDescriptionOids(Oid classid, Oid objid);
  
+ extern char *getObjectDescriptionOids(Oid classid, Oid objid);
+ 
  extern ObjectAddresses *new_object_addresses(void);
  
  extern void add_exact_object_address(const ObjectAddress *object,
*** a/src/include/commands/alter.h
--- b/src/include/commands/alter.h
***************
*** 15,23 ****
--- 15,30 ----
  #define ALTER_H
  
  #include "nodes/parsenodes.h"
+ #include "utils/acl.h"
+ #include "utils/relcache.h"
  
  extern void ExecRenameStmt(RenameStmt *stmt);
  extern void ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt);
+ extern void AlterObjectNamespace(Relation rel, int cacheId,
+ 								 Oid classId, Oid objid, Oid nspId,
+ 								 int Anum_name, int Anum_namespace, int Anum_owner,
+ 								 AclObjectKind acl_kind,
+ 								 bool superuser_only);
  extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt);
  
  #endif   /* ALTER_H */
*** a/src/include/commands/conversioncmds.h
--- b/src/include/commands/conversioncmds.h
***************
*** 22,26 **** extern void DropConversionsCommand(DropStmt *drop);
--- 22,29 ----
  extern void RenameConversion(List *name, const char *newname);
  extern void AlterConversionOwner(List *name, Oid newOwnerId);
  extern void AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId);
+ extern void AlterConversionNamespace(List *name, const char *newschema);
+ extern void AlterConversionNamespace_oid(Oid convOid, Oid newNspOid);
+ 
  
  #endif   /* CONVERSIONCMDS_H */
*** a/src/include/commands/defrem.h
--- b/src/include/commands/defrem.h
***************
*** 66,71 **** extern void DropCast(DropCastStmt *stmt);
--- 66,72 ----
  extern void DropCastById(Oid castOid);
  extern void AlterFunctionNamespace(List *name, List *argtypes, bool isagg,
  					   const char *newschema);
+ extern void AlterFunctionNamespace_oid(Oid procOid, Oid nspOid);
  extern void ExecuteDoStmt(DoStmt *stmt);
  extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok);
  
***************
*** 78,83 **** extern void AlterOperatorOwner(List *name, TypeName *typeName1,
--- 79,86 ----
  extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId);
  extern Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok);
  extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok);
+ extern void AlterOperatorNamespace_oid(Oid operOid, Oid newNspOid);
+ extern void AlterOperatorNamespace(List *names, List *argtypes, const char *newschema);
  
  /* commands/aggregatecmds.c */
  extern void DefineAggregate(List *name, List *args, bool oldstyle,
***************
*** 100,114 **** extern void RenameOpClass(List *name, const char *access_method, const char *new
--- 103,123 ----
  extern void RenameOpFamily(List *name, const char *access_method, const char *newname);
  extern void AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId);
  extern void AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId);
+ extern void AlterOpClassNamespace(List *name, List *argam, const char *newschema);
+ extern void AlterOpClassNamespace_oid(Oid opclassOid, Oid newNspOid);
  extern void AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId);
  extern void AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId);
  extern Oid get_am_oid(const char *amname, bool missing_ok);
+ extern void AlterOpFamilyNamespace(List *name, List *argam, const char *newschema);
+ extern void AlterOpFamilyNamespace_oid(Oid opfamilyOid, Oid newNspOid);
  
  /* commands/tsearchcmds.c */
  extern void DefineTSParser(List *names, List *parameters);
  extern void RenameTSParser(List *oldname, const char *newname);
  extern void RemoveTSParsers(DropStmt *drop);
  extern void RemoveTSParserById(Oid prsId);
+ extern void AlterTSParserNamespace(List *name, const char *newschema);
+ extern void AlterTSParserNamespace_oid(Oid prsId, Oid newNspOid);
  
  extern void DefineTSDictionary(List *names, List *parameters);
  extern void RenameTSDictionary(List *oldname, const char *newname);
***************
*** 116,129 **** extern void RemoveTSDictionaries(DropStmt *drop);
--- 125,144 ----
  extern void RemoveTSDictionaryById(Oid dictId);
  extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt);
  extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId);
+ extern void AlterTSDictionaryNamespace(List *name, const char *newschema);
+ extern void AlterTSDictionaryNamespace_oid(Oid dictId, Oid newNspOid);
  
  extern void DefineTSTemplate(List *names, List *parameters);
  extern void RenameTSTemplate(List *oldname, const char *newname);
+ extern void AlterTSTemplateNamespace(List *name, const char *newschema);
+ extern void AlterTSTemplateNamespace_oid(Oid tmplId, Oid newNspOid);
  extern void RemoveTSTemplates(DropStmt *stmt);
  extern void RemoveTSTemplateById(Oid tmplId);
  
  extern void DefineTSConfiguration(List *names, List *parameters);
  extern void RenameTSConfiguration(List *oldname, const char *newname);
+ extern void AlterTSConfigurationNamespace(List *name, const char *newschema);
+ extern void AlterTSConfigurationNamespace_oid(Oid cfgId, Oid newNspOid);
  extern void RemoveTSConfigurations(DropStmt *stmt);
  extern void RemoveTSConfigurationById(Oid cfgId);
  extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt);
*** a/src/test/regress/expected/alter_table.out
--- b/src/test/regress/expected/alter_table.out
***************
*** 1645,1657 **** create view alter1.v1 as select * from alter1.t1;
--- 1645,1676 ----
  create function alter1.plus1(int) returns int as 'select $1+1' language sql;
  create domain alter1.posint integer check (value > 0);
  create type alter1.ctype as (f1 int, f2 text);
+ create function alter1.same(alter1.ctype, alter1.ctype) returns boolean language sql 
+ as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2';
+ create operator alter1.=(procedure = alter1.same, leftarg  = alter1.ctype, rightarg = alter1.ctype);
+ create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as
+   operator 1 alter1.=(alter1.ctype, alter1.ctype);
+ create conversion alter1.ascii_to_utf8 for 'sql_ascii' to 'utf8' from ascii_to_utf8;
+ create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ create text search configuration alter1.cfg(parser = alter1.prs);
+ create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize);
+ create text search dictionary alter1.dict(template = alter1.tmpl);
  insert into alter1.t1(f2) values(11);
  insert into alter1.t1(f2) values(12);
  alter table alter1.t1 set schema alter2;
  alter table alter1.v1 set schema alter2;
  alter function alter1.plus1(int) set schema alter2;
  alter domain alter1.posint set schema alter2;
+ alter operator class alter1.ctype_hash_ops using hash set schema alter2;
+ alter operator family alter1.ctype_hash_ops using hash set schema alter2;
+ alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2;
+ alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2;
  alter type alter1.ctype set schema alter2;
+ alter conversion alter1.ascii_to_utf8 set schema alter2;
+ alter text search parser alter1.prs set schema alter2;
+ alter text search configuration alter1.cfg set schema alter2;
+ alter text search template alter1.tmpl set schema alter2;
+ alter text search dictionary alter1.dict set schema alter2;
  -- this should succeed because nothing is left in alter1
  drop schema alter1;
  insert into alter2.t1(f2) values(13);
***************
*** 1682,1693 **** select alter2.plus1(41);
  
  -- clean up
  drop schema alter2 cascade;
! NOTICE:  drop cascades to 5 other objects
  DETAIL:  drop cascades to table alter2.t1
  drop cascades to view alter2.v1
  drop cascades to function alter2.plus1(integer)
  drop cascades to type alter2.posint
  drop cascades to type alter2.ctype
  --
  -- composite types
  --
--- 1701,1720 ----
  
  -- clean up
  drop schema alter2 cascade;
! NOTICE:  drop cascades to 13 other objects
  DETAIL:  drop cascades to table alter2.t1
  drop cascades to view alter2.v1
  drop cascades to function alter2.plus1(integer)
  drop cascades to type alter2.posint
+ drop cascades to operator family alter2.ctype_hash_ops for access method hash
  drop cascades to type alter2.ctype
+ drop cascades to function alter2.same(alter2.ctype,alter2.ctype)
+ drop cascades to operator alter2.=(alter2.ctype,alter2.ctype)
+ drop cascades to conversion ascii_to_utf8
+ drop cascades to text search parser prs
+ drop cascades to text search configuration cfg
+ drop cascades to text search template tmpl
+ drop cascades to text search dictionary dict
  --
  -- composite types
  --
*** a/src/test/regress/sql/alter_table.sql
--- b/src/test/regress/sql/alter_table.sql
***************
*** 1206,1211 **** create domain alter1.posint integer check (value > 0);
--- 1206,1226 ----
  
  create type alter1.ctype as (f1 int, f2 text);
  
+ create function alter1.same(alter1.ctype, alter1.ctype) returns boolean language sql 
+ as 'select $1.f1 is not distinct from $2.f1 and $1.f2 is not distinct from $2.f2';
+ 
+ create operator alter1.=(procedure = alter1.same, leftarg  = alter1.ctype, rightarg = alter1.ctype);
+ 
+ create operator class alter1.ctype_hash_ops default for type alter1.ctype using hash as
+   operator 1 alter1.=(alter1.ctype, alter1.ctype);
+ 
+ create conversion alter1.ascii_to_utf8 for 'sql_ascii' to 'utf8' from ascii_to_utf8;
+ 
+ create text search parser alter1.prs(start = prsd_start, gettoken = prsd_nexttoken, end = prsd_end, lextypes = prsd_lextype);
+ create text search configuration alter1.cfg(parser = alter1.prs);
+ create text search template alter1.tmpl(init = dsimple_init, lexize = dsimple_lexize);
+ create text search dictionary alter1.dict(template = alter1.tmpl);
+ 
  insert into alter1.t1(f2) values(11);
  insert into alter1.t1(f2) values(12);
  
***************
*** 1213,1219 **** alter table alter1.t1 set schema alter2;
--- 1228,1243 ----
  alter table alter1.v1 set schema alter2;
  alter function alter1.plus1(int) set schema alter2;
  alter domain alter1.posint set schema alter2;
+ alter operator class alter1.ctype_hash_ops using hash set schema alter2;
+ alter operator family alter1.ctype_hash_ops using hash set schema alter2;
+ alter operator alter1.=(alter1.ctype, alter1.ctype) set schema alter2;
+ alter function alter1.same(alter1.ctype, alter1.ctype) set schema alter2;
  alter type alter1.ctype set schema alter2;
+ alter conversion alter1.ascii_to_utf8 set schema alter2;
+ alter text search parser alter1.prs set schema alter2;
+ alter text search configuration alter1.cfg set schema alter2;
+ alter text search template alter1.tmpl set schema alter2;
+ alter text search dictionary alter1.dict set schema alter2;
  
  -- this should succeed because nothing is left in alter1
  drop schema alter1;
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to