@@ -4068,7 +4068,7 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
4068
4068
typename = makeTypeNameFromNameList (names );
4069
4069
typeOid = typenameTypeId (NULL , typename );
4070
4070
4071
- /* Don't allow ALTER DOMAIN on a type */
4071
+ /* Don't allow ALTER DOMAIN on a non-domain type */
4072
4072
if (objecttype == OBJECT_DOMAIN && get_typtype (typeOid ) != TYPTYPE_DOMAIN )
4073
4073
ereport (ERROR ,
4074
4074
(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
@@ -4079,7 +4079,7 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
4079
4079
nspOid = LookupCreationNamespace (newschema );
4080
4080
4081
4081
objsMoved = new_object_addresses ();
4082
- oldNspOid = AlterTypeNamespace_oid (typeOid , nspOid , objsMoved );
4082
+ oldNspOid = AlterTypeNamespace_oid (typeOid , nspOid , false, objsMoved );
4083
4083
free_object_addresses (objsMoved );
4084
4084
4085
4085
if (oldschema )
@@ -4090,8 +4090,21 @@ AlterTypeNamespace(List *names, const char *newschema, ObjectType objecttype,
4090
4090
return myself ;
4091
4091
}
4092
4092
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
+ */
4093
4105
Oid
4094
- AlterTypeNamespace_oid (Oid typeOid , Oid nspOid , ObjectAddresses * objsMoved )
4106
+ AlterTypeNamespace_oid (Oid typeOid , Oid nspOid , bool ignoreDependent ,
4107
+ ObjectAddresses * objsMoved )
4095
4108
{
4096
4109
Oid elemOid ;
4097
4110
@@ -4102,15 +4115,23 @@ AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
4102
4115
/* don't allow direct alteration of array types */
4103
4116
elemOid = get_element_type (typeOid );
4104
4117
if (OidIsValid (elemOid ) && get_array_type (elemOid ) == typeOid )
4118
+ {
4119
+ if (ignoreDependent )
4120
+ return InvalidOid ;
4105
4121
ereport (ERROR ,
4106
4122
(errcode (ERRCODE_WRONG_OBJECT_TYPE ),
4107
4123
errmsg ("cannot alter array type %s" ,
4108
4124
format_type_be (typeOid )),
4109
4125
errhint ("You can alter type %s, which will alter the array type as well." ,
4110
4126
format_type_be (elemOid ))));
4127
+ }
4111
4128
4112
4129
/* 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 );
4114
4135
}
4115
4136
4116
4137
/*
@@ -4122,15 +4143,21 @@ AlterTypeNamespace_oid(Oid typeOid, Oid nspOid, ObjectAddresses *objsMoved)
4122
4143
* if any. isImplicitArray should be true only when doing this internal
4123
4144
* recursion (outside callers must never try to move an array type directly).
4124
4145
*
4146
+ * If ignoreDependent is true, we silently don't process table types.
4147
+ *
4125
4148
* If errorOnTableType is true, the function errors out if the type is
4126
4149
* 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.
4128
4154
*
4129
- * Returns the type's old namespace OID.
4155
+ * Returns the type's old namespace OID, or InvalidOid if we did nothing .
4130
4156
*/
4131
4157
Oid
4132
4158
AlterTypeNamespaceInternal (Oid typeOid , Oid nspOid ,
4133
4159
bool isImplicitArray ,
4160
+ bool ignoreDependent ,
4134
4161
bool errorOnTableType ,
4135
4162
ObjectAddresses * objsMoved )
4136
4163
{
@@ -4185,15 +4212,21 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
4185
4212
get_rel_relkind (typform -> typrelid ) == RELKIND_COMPOSITE_TYPE );
4186
4213
4187
4214
/* 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
+ }
4197
4230
4198
4231
if (oldNspOid != nspOid )
4199
4232
{
@@ -4260,7 +4293,11 @@ AlterTypeNamespaceInternal(Oid typeOid, Oid nspOid,
4260
4293
4261
4294
/* Recursively alter the associated array type, if any */
4262
4295
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 );
4264
4301
4265
4302
return oldNspOid ;
4266
4303
}
0 commit comments