From 994c36e01d19dece2b0c76fb781e1d08a6e1c814 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Wed, 3 Oct 2012 18:02:38 -0300 Subject: refactor ALTER some-obj SET OWNER implementation Remove duplicate implementation of catalog munging and miscellaneous privilege and consistency checks. Instead rely on already existing data in objectaddress.c to do the work. Author: KaiGai Kohei Tweaked by me Reviewed by Robert Haas --- src/backend/commands/opclasscmds.c | 248 ------------------------------------- 1 file changed, 248 deletions(-) (limited to 'src/backend/commands/opclasscmds.c') diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index e26c9477bb1..099bb391396 100644 --- a/src/backend/commands/opclasscmds.c +++ b/src/backend/commands/opclasscmds.c @@ -81,11 +81,6 @@ static void dropOperators(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *operators); static void dropProcedures(List *opfamilyname, Oid amoid, Oid opfamilyoid, List *procedures); -static void AlterOpClassOwner_internal(Relation rel, HeapTuple tuple, - Oid newOwnerId); -static void AlterOpFamilyOwner_internal(Relation rel, HeapTuple tuple, - Oid newOwnerId); - /* * OpFamilyCacheLookup @@ -1809,249 +1804,6 @@ RenameOpFamily(List *name, const char *access_method, const char *newname) heap_freetuple(tup); } -/* - * Change opclass owner by name - */ -void -AlterOpClassOwner(List *name, const char *access_method, Oid newOwnerId) -{ - Oid amOid; - Relation rel; - HeapTuple tup; - HeapTuple origtup; - - 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); - - AlterOpClassOwner_internal(rel, tup, newOwnerId); - - heap_freetuple(tup); - heap_close(rel, NoLock); -} - -/* - * Change operator class owner, specified by OID - */ -void -AlterOpClassOwner_oid(Oid opclassOid, Oid newOwnerId) -{ - 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); - - AlterOpClassOwner_internal(rel, tup, newOwnerId); - - heap_freetuple(tup); - heap_close(rel, NoLock); -} - -/* - * The first parameter is pg_opclass, opened and suitably locked. The second - * parameter is a copy of the tuple from pg_opclass we want to modify. - */ -static void -AlterOpClassOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) -{ - Oid namespaceOid; - AclResult aclresult; - Form_pg_opclass opcForm; - - Assert(tup->t_tableOid == OperatorClassRelationId); - Assert(RelationGetRelid(rel) == OperatorClassRelationId); - - opcForm = (Form_pg_opclass) GETSTRUCT(tup); - - namespaceOid = opcForm->opcnamespace; - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (opcForm->opcowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_opclass_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPCLASS, - NameStr(opcForm->opcname)); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - /* New owner must have CREATE privilege on namespace */ - aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(namespaceOid)); - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - opcForm->opcowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(OperatorClassRelationId, HeapTupleGetOid(tup), - newOwnerId); - } -} - -/* - * Change opfamily owner by name - */ -void -AlterOpFamilyOwner(List *name, const char *access_method, Oid newOwnerId) -{ - Oid amOid; - Relation rel; - HeapTuple tup; - char *opfname; - char *schemaname; - - 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); - } - - AlterOpFamilyOwner_internal(rel, tup, newOwnerId); - - heap_freetuple(tup); - heap_close(rel, NoLock); -} - -/* - * Change operator family owner, specified by OID - */ -void -AlterOpFamilyOwner_oid(Oid opfamilyOid, Oid newOwnerId) -{ - 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); - - AlterOpFamilyOwner_internal(rel, tup, newOwnerId); - - heap_freetuple(tup); - heap_close(rel, NoLock); -} - -/* - * The first parameter is pg_opfamily, opened and suitably locked. The second - * parameter is a copy of the tuple from pg_opfamily we want to modify. - */ -static void -AlterOpFamilyOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) -{ - Oid namespaceOid; - AclResult aclresult; - Form_pg_opfamily opfForm; - - Assert(tup->t_tableOid == OperatorFamilyRelationId); - Assert(RelationGetRelid(rel) == OperatorFamilyRelationId); - - opfForm = (Form_pg_opfamily) GETSTRUCT(tup); - - namespaceOid = opfForm->opfnamespace; - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (opfForm->opfowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_opfamily_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPFAMILY, - NameStr(opfForm->opfname)); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - /* New owner must have CREATE privilege on namespace */ - aclresult = pg_namespace_aclcheck(namespaceOid, newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(namespaceOid)); - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - opfForm->opfowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(OperatorFamilyRelationId, HeapTupleGetOid(tup), - newOwnerId); - } -} - /* * get_am_oid - given an access method name, look up the OID * -- cgit v1.2.3