@@ -4068,7 +4068,7 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
40684068 typename = makeTypeNameFromNameList (names );
40694069 typeOid = typenameTypeId (NULL , typename );
40704070
4071- /* Don't allow ALTER DOMAIN on a type */
4071+ /* Don't allow ALTER DOMAIN on a non-domain type */
40724072 if (objecttype == OBJECT_DOMAIN && get_typtype (typeOid ) != TYPTYPE_DOMAIN )
40734073 ereport (ERROR ,
40744074 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
@@ -4079,7 +4079,7 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
40794079 nspOid = LookupCreationNamespace (newschema );
40804080
40814081 objsMoved = new_object_addresses ();
4082- oldNspOid = AlterTypeNamespace_oid (typeOid , nspOid , objsMoved );
4082+ oldNspOid = AlterTypeNamespace_oid (typeOid , nspOid , false, objsMoved );
40834083 free_object_addresses (objsMoved );
40844084
40854085 if (oldschema )
@@ -4090,8 +4090,21 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
40904090 return myself ;
40914091}
40924092
4093+ /*
4094+ * ALTER TYPE SET SCHEMA, where the caller has already looked up the OIDs
4095+ * of the type and the target schema and checked the schema's privileges.
4096+ *
4097+ * If ignoreDependent is true, we silently ignore dependent types
4098+ * (array types and table rowtypes) rather than raising errors.
4099+ *
4100+ * This entry point is exported for use by AlterObjectNamespace_oid,
4101+ * which doesn't want errors when it passes OIDs of dependent types.
4102+ *
4103+ * Returns the type's old namespace OID, or InvalidOid if we did nothing.
4104+ */
40934105Oid
4094- AlterTypeNamespace_oid (Oid typeOid , Oid nspOid , ObjectAddresses * objsMoved )
4106+ AlterTypeNamespace_oid (Oid typeOid , Oid nspOid , bool ignoreDependent ,
4107+ ObjectAddresses * objsMoved )
40954108{
40964109 Oid elemOid ;
40974110
@@ -4102,15 +4115,23 @@ AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
41024115 /* don't allow direct alteration of array types */
41034116 elemOid = get_element_type (typeOid );
41044117 if (OidIsValid (elemOid ) && get_array_type (elemOid ) == typeOid )
4118+ {
4119+ if (ignoreDependent )
4120+ return InvalidOid ;
41054121 ereport (ERROR ,
41064122 (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
41074123 errmsg ("cannot alter array type %s" ,
41084124 format_type_be (typeOid )),
41094125 errhint ("You can alter type %s, which will alter the array type as well." ,
41104126 format_type_be (elemOid ))));
4127+ }
41114128
41124129 /* and do the work */
4113- return AlterTypeNamespaceInternal (typeOid , nspOid , false, true, objsMoved );
4130+ return AlterTypeNamespaceInternal (typeOid , nspOid ,
4131+ false, /* isImplicitArray */
4132+ ignoreDependent , /* ignoreDependent */
4133+ true, /* errorOnTableType */
4134+ objsMoved );
41144135}
41154136
41164137/*
@@ -4122,15 +4143,21 @@ AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
41224143 * if any. isImplicitArray should be true only when doing this internal
41234144 * recursion (outside callers must never try to move an array type directly).
41244145 *
4146+ * If ignoreDependent is true, we silently don't process table types.
4147+ *
41254148 * If errorOnTableType is true, the function errors out if the type is
41264149 * a table type. ALTER TABLE has to be used to move a table to a new
4127- * namespace.
4150+ * namespace. (This flag is ignored if ignoreDependent is true.)
4151+ *
4152+ * We also do nothing if the type is already listed in *objsMoved.
4153+ * After a successful move, we add the type to *objsMoved.
41284154 *
4129- * Returns the type's old namespace OID.
4155+ * Returns the type's old namespace OID, or InvalidOid if we did nothing .
41304156 */
41314157Oid
41324158AlterTypeNamespaceInternal (Oid typeOid , Oid nspOid ,
41334159 bool isImplicitArray ,
4160+ bool ignoreDependent ,
41344161 bool errorOnTableType ,
41354162 ObjectAddresses * objsMoved )
41364163{
@@ -4185,15 +4212,21 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
41854212 get_rel_relkind (typform -> typrelid ) == RELKIND_COMPOSITE_TYPE );
41864213
41874214 /* Enforce not-table-type if requested */
4188- if (typform -> typtype == TYPTYPE_COMPOSITE && !isCompositeType &&
4189- errorOnTableType )
4190- ereport (ERROR ,
4191- (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
4192- errmsg ("%s is a table's row type" ,
4193- format_type_be (typeOid )),
4194- /* translator: %s is an SQL ALTER command */
4195- errhint ("Use %s instead." ,
4196- "ALTER TABLE" )));
4215+ if (typform -> typtype == TYPTYPE_COMPOSITE && !isCompositeType )
4216+ {
4217+ if (ignoreDependent )
4218+ {
4219+ table_close (rel , RowExclusiveLock );
4220+ return InvalidOid ;
4221+ }
4222+ if (errorOnTableType )
4223+ ereport (ERROR ,
4224+ (errcode (ERRCODE_WRONG_OBJECT_TYPE ),
4225+ errmsg ("%s is a table's row type" ,
4226+ format_type_be (typeOid )),
4227+ /* translator: %s is an SQL ALTER command */
4228+ errhint ("Use %s instead." , "ALTER TABLE" )));
4229+ }
41974230
41984231 if (oldNspOid != nspOid )
41994232 {
@@ -4260,7 +4293,11 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
42604293
42614294 /* Recursively alter the associated array type, if any */
42624295 if (OidIsValid (arrayOid ))
4263- AlterTypeNamespaceInternal (arrayOid , nspOid , true, true, objsMoved );
4296+ AlterTypeNamespaceInternal (arrayOid , nspOid ,
4297+ true, /* isImplicitArray */
4298+ false, /* ignoreDependent */
4299+ true, /* errorOnTableType */
4300+ objsMoved );
42644301
42654302 return oldNspOid ;
42664303}
0 commit comments