diff options
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r-- | src/backend/commands/typecmds.c | 119 |
1 files changed, 50 insertions, 69 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index de913538910..f5e25ef4ee1 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -3272,57 +3272,7 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) get_namespace_name(typTup->typnamespace)); } - /* - * If it's a composite type, invoke ATExecChangeOwner so that we fix - * up the pg_class entry properly. That will call back to - * AlterTypeOwnerInternal to take care of the pg_type entry(s). - */ - if (typTup->typtype == TYPTYPE_COMPOSITE) - ATExecChangeOwner(typTup->typrelid, newOwnerId, true, AccessExclusiveLock); - else - { - Datum repl_val[Natts_pg_type]; - bool repl_null[Natts_pg_type]; - bool repl_repl[Natts_pg_type]; - Acl *newAcl; - Datum aclDatum; - bool isNull; - - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - repl_repl[Anum_pg_type_typowner - 1] = true; - repl_val[Anum_pg_type_typowner - 1] = ObjectIdGetDatum(newOwnerId); - - aclDatum = heap_getattr(tup, - Anum_pg_type_typacl, - RelationGetDescr(rel), - &isNull); - /* Null ACLs do not require changes */ - if (!isNull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - typTup->typowner, newOwnerId); - repl_repl[Anum_pg_type_typacl - 1] = true; - repl_val[Anum_pg_type_typacl - 1] = PointerGetDatum(newAcl); - } - - tup = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, - repl_repl); - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId); - - InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); - - /* If it has an array type, update that too */ - if (OidIsValid(typTup->typarray)) - AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false); - } + AlterTypeOwner_oid(typeOid, newOwnerId, true); } ObjectAddressSet(address, TypeRelationId, typeOid); @@ -3334,21 +3284,58 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype) } /* - * AlterTypeOwnerInternal - change type owner unconditionally + * AlterTypeOwner_oid - change type owner unconditionally + * + * This function recurses to handle a pg_class entry, if necessary. It + * invokes any necessary access object hooks. If hasDependEntry is TRUE, this + * function modifies the pg_shdepend entry appropriately (this should be + * passed as FALSE only for table rowtypes and array types). * - * This is currently only used to propagate ALTER TABLE/TYPE OWNER to a - * table's rowtype or an array type, and to implement REASSIGN OWNED BY. - * It assumes the caller has done all needed checks. The function will - * automatically recurse to an array type if the type has one. + * This is used by ALTER TABLE/TYPE OWNER commands, as well as by REASSIGN + * OWNED BY. It assumes the caller has done all needed check. + */ +void +AlterTypeOwner_oid(Oid typeOid, Oid newOwnerId, bool hasDependEntry) +{ + Relation rel; + HeapTuple tup; + Form_pg_type typTup; + + rel = heap_open(TypeRelationId, RowExclusiveLock); + + tup = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typeOid)); + if (!HeapTupleIsValid(tup)) + elog(ERROR, "cache lookup failed for type %u", typeOid); + typTup = (Form_pg_type) GETSTRUCT(tup); + + /* + * If it's a composite type, invoke ATExecChangeOwner so that we fix up the + * pg_class entry properly. That will call back to AlterTypeOwnerInternal + * to take care of the pg_type entry(s). + */ + if (typTup->typtype == TYPTYPE_COMPOSITE) + ATExecChangeOwner(typTup->typrelid, newOwnerId, true, AccessExclusiveLock); + else + AlterTypeOwnerInternal(typeOid, newOwnerId); + + /* Update owner dependency reference */ + if (hasDependEntry) + changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId); + + InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + + ReleaseSysCache(tup); + heap_close(rel, RowExclusiveLock); +} + +/* + * AlterTypeOwnerInternal - bare-bones type owner change. * - * hasDependEntry should be TRUE if type is expected to have a pg_shdepend - * entry (ie, it's not a table rowtype nor an array type). - * is_primary_ops should be TRUE if this function is invoked with user's - * direct operation (e.g, shdepReassignOwned). Elsewhere, + * This routine simply modifies the owner of a pg_type entry, and recurses + * to handle a possible array type. */ void -AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, - bool hasDependEntry) +AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId) { Relation rel; HeapTuple tup; @@ -3393,15 +3380,9 @@ AlterTypeOwnerInternal(Oid typeOid, Oid newOwnerId, CatalogUpdateIndexes(rel, tup); - /* Update owner dependency reference, if it has one */ - if (hasDependEntry) - changeDependencyOnOwner(TypeRelationId, typeOid, newOwnerId); - /* If it has an array type, update that too */ if (OidIsValid(typTup->typarray)) - AlterTypeOwnerInternal(typTup->typarray, newOwnerId, false); - - InvokeObjectPostAlterHook(TypeRelationId, typeOid, 0); + AlterTypeOwnerInternal(typTup->typarray, newOwnerId); /* Clean up */ heap_close(rel, RowExclusiveLock); |