src/backend/catalog/pg_largeobject.c | 102 ------------ src/backend/catalog/pg_shdepend.c | 71 +++++---- src/backend/commands/aggregatecmds.c | 15 -- src/backend/commands/alter.c | 281 +++++++++++++++++++++++++++------- src/backend/commands/collationcmds.c | 101 ------------ src/backend/commands/conversioncmds.c | 101 ------------ src/backend/commands/extension.c | 92 ----------- src/backend/commands/functioncmds.c | 137 ----------------- src/backend/commands/opclasscmds.c | 248 ------------------------------ src/backend/commands/operatorcmds.c | 93 ----------- src/backend/commands/proclang.c | 117 -------------- src/backend/commands/tablespace.c | 99 ------------ src/backend/commands/tsearchcmds.c | 120 --------------- src/backend/nodes/copyfuncs.c | 1 - src/backend/nodes/equalfuncs.c | 1 - src/backend/parser/gram.y | 4 +- src/include/catalog/pg_largeobject.h | 1 - src/include/commands/alter.h | 8 +- src/include/commands/collationcmds.h | 2 - src/include/commands/conversioncmds.h | 2 - src/include/commands/defrem.h | 12 -- src/include/commands/proclang.h | 2 - src/include/commands/tablespace.h | 1 - src/include/nodes/parsenodes.h | 1 - 24 files changed, 272 insertions(+), 1340 deletions(-) diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c index 3322034..b693fde 100644 --- a/src/backend/catalog/pg_largeobject.c +++ b/src/backend/catalog/pg_largeobject.c @@ -140,108 +140,6 @@ LargeObjectDrop(Oid loid) } /* - * LargeObjectAlterOwner - * - * Implementation of ALTER LARGE OBJECT statement - */ -void -LargeObjectAlterOwner(Oid loid, Oid newOwnerId) -{ - Form_pg_largeobject_metadata form_lo_meta; - Relation pg_lo_meta; - ScanKeyData skey[1]; - SysScanDesc scan; - HeapTuple oldtup; - HeapTuple newtup; - - pg_lo_meta = heap_open(LargeObjectMetadataRelationId, - RowExclusiveLock); - - ScanKeyInit(&skey[0], - ObjectIdAttributeNumber, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(loid)); - - scan = systable_beginscan(pg_lo_meta, - LargeObjectMetadataOidIndexId, true, - SnapshotNow, 1, skey); - - oldtup = systable_getnext(scan); - if (!HeapTupleIsValid(oldtup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("large object %u does not exist", loid))); - - form_lo_meta = (Form_pg_largeobject_metadata) GETSTRUCT(oldtup); - if (form_lo_meta->lomowner != newOwnerId) - { - Datum values[Natts_pg_largeobject_metadata]; - bool nulls[Natts_pg_largeobject_metadata]; - bool replaces[Natts_pg_largeobject_metadata]; - Acl *newAcl; - Datum aclDatum; - bool isnull; - - /* Superusers can always do it */ - if (!superuser()) - { - /* - * lo_compat_privileges is not checked here, because ALTER LARGE - * OBJECT ... OWNER did not exist at all prior to PostgreSQL 9.0. - * - * We must be the owner of the existing object. - */ - if (!pg_largeobject_ownercheck(loid, GetUserId())) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - errmsg("must be owner of large object %u", loid))); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - } - - memset(values, 0, sizeof(values)); - memset(nulls, false, sizeof(nulls)); - memset(replaces, false, sizeof(nulls)); - - values[Anum_pg_largeobject_metadata_lomowner - 1] - = ObjectIdGetDatum(newOwnerId); - replaces[Anum_pg_largeobject_metadata_lomowner - 1] = true; - - /* - * Determine the modified ACL for the new owner. This is only - * necessary when the ACL is non-null. - */ - aclDatum = heap_getattr(oldtup, - Anum_pg_largeobject_metadata_lomacl, - RelationGetDescr(pg_lo_meta), &isnull); - if (!isnull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - form_lo_meta->lomowner, newOwnerId); - values[Anum_pg_largeobject_metadata_lomacl - 1] - = PointerGetDatum(newAcl); - replaces[Anum_pg_largeobject_metadata_lomacl - 1] = true; - } - - newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_lo_meta), - values, nulls, replaces); - - simple_heap_update(pg_lo_meta, &newtup->t_self, newtup); - CatalogUpdateIndexes(pg_lo_meta, newtup); - - heap_freetuple(newtup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(LargeObjectRelationId, - loid, newOwnerId); - } - systable_endscan(scan); - - heap_close(pg_lo_meta, RowExclusiveLock); -} - -/* * LargeObjectExists * * We don't use the system cache for large object metadata, for fear of diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index 5a73b48..301812c 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -32,6 +32,7 @@ #include "catalog/pg_foreign_server.h" #include "catalog/pg_language.h" #include "catalog/pg_largeobject.h" +#include "catalog/pg_largeobject_metadata.h" #include "catalog/pg_namespace.h" #include "catalog/pg_operator.h" #include "catalog/pg_opclass.h" @@ -40,6 +41,7 @@ #include "catalog/pg_shdepend.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" +#include "commands/alter.h" #include "commands/dbcommands.h" #include "commands/collationcmds.h" #include "commands/conversioncmds.h" @@ -1331,22 +1333,10 @@ shdepReassignOwned(List *roleids, Oid newrole) /* Issue the appropriate ALTER OWNER call */ switch (sdepForm->classid) { - case CollationRelationId: - AlterCollationOwner_oid(sdepForm->objid, newrole); - break; - - case ConversionRelationId: - AlterConversionOwner_oid(sdepForm->objid, newrole); - break; - case TypeRelationId: AlterTypeOwnerInternal(sdepForm->objid, newrole, true); break; - case OperatorRelationId: - AlterOperatorOwner_oid(sdepForm->objid, newrole); - break; - case NamespaceRelationId: AlterSchemaOwner_oid(sdepForm->objid, newrole); break; @@ -1361,18 +1351,6 @@ shdepReassignOwned(List *roleids, Oid newrole) ATExecChangeOwner(sdepForm->objid, newrole, true, AccessExclusiveLock); break; - case ProcedureRelationId: - AlterFunctionOwner_oid(sdepForm->objid, newrole); - break; - - case LanguageRelationId: - AlterLanguageOwner_oid(sdepForm->objid, newrole); - break; - - case LargeObjectRelationId: - LargeObjectAlterOwner(sdepForm->objid, newrole); - break; - case DefaultAclRelationId: /* @@ -1381,14 +1359,6 @@ shdepReassignOwned(List *roleids, Oid newrole) */ break; - case OperatorClassRelationId: - AlterOpClassOwner_oid(sdepForm->objid, newrole); - break; - - case OperatorFamilyRelationId: - AlterOpFamilyOwner_oid(sdepForm->objid, newrole); - break; - case ForeignServerRelationId: AlterForeignServerOwner_oid(sdepForm->objid, newrole); break; @@ -1397,14 +1367,43 @@ shdepReassignOwned(List *roleids, Oid newrole) AlterForeignDataWrapperOwner_oid(sdepForm->objid, newrole); break; - case ExtensionRelationId: - AlterExtensionOwner_oid(sdepForm->objid, newrole); - break; - case EventTriggerRelationId: AlterEventTriggerOwner_oid(sdepForm->objid, newrole); break; + /* Generic alter owner cases */ + case CollationRelationId: + case ConversionRelationId: + case OperatorRelationId: + case ProcedureRelationId: + case LanguageRelationId: + case LargeObjectRelationId: + case OperatorFamilyRelationId: + case OperatorClassRelationId: + case ExtensionRelationId: + { + Oid classId = sdepForm->classid; + Relation catalog; + + if (classId == LargeObjectRelationId) + classId = LargeObjectMetadataRelationId; + + catalog = heap_open(classId, RowExclusiveLock); + + AlterObjectOwner(catalog, + get_object_oid_index(classId), + get_object_catcache_oid(classId), + sdepForm->objid, newrole, + get_object_attnum_owner(classId), + get_object_attnum_namespace(classId), + get_object_attnum_name(classId), + get_object_attnum_acl(classId), + get_object_aclkind(classId)); + + heap_close(catalog, NoLock); + } + break; + default: elog(ERROR, "unexpected classid %u", sdepForm->classid); break; diff --git a/src/backend/commands/aggregatecmds.c b/src/backend/commands/aggregatecmds.c index 57adfe8..c99c07c 100644 --- a/src/backend/commands/aggregatecmds.c +++ b/src/backend/commands/aggregatecmds.c @@ -267,18 +267,3 @@ RenameAggregate(List *name, List *args, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } - -/* - * Change aggregate owner - */ -void -AlterAggregateOwner(List *name, List *args, Oid newOwnerId) -{ - Oid procOid; - - /* Look up function and make sure it's an aggregate */ - procOid = LookupAggNameTypeNames(name, args, false); - - /* The rest is just like a function */ - AlterFunctionOwner_oid(procOid, newOwnerId); -} diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index 0d3c9ea..ca50e06 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -15,10 +15,12 @@ #include "postgres.h" #include "access/htup_details.h" +#include "access/sysattr.h" #include "catalog/dependency.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "catalog/pg_largeobject.h" +#include "catalog/pg_largeobject_metadata.h" #include "catalog/pg_namespace.h" #include "commands/alter.h" #include "commands/collationcmds.h" @@ -37,10 +39,11 @@ #include "miscadmin.h" #include "tcop/utility.h" #include "utils/builtins.h" +#include "utils/fmgroids.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/syscache.h" - +#include "utils/tqual.h" /* * Executes an ALTER OBJECT / RENAME TO statement. Based on the object @@ -467,71 +470,19 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) switch (stmt->objectType) { - case OBJECT_AGGREGATE: - AlterAggregateOwner(stmt->object, stmt->objarg, newowner); - break; - - case OBJECT_COLLATION: - AlterCollationOwner(stmt->object, newowner); - break; - - case OBJECT_CONVERSION: - AlterConversionOwner(stmt->object, newowner); - break; - case OBJECT_DATABASE: AlterDatabaseOwner(strVal(linitial(stmt->object)), newowner); break; - case OBJECT_FUNCTION: - AlterFunctionOwner(stmt->object, stmt->objarg, newowner); - break; - - case OBJECT_LANGUAGE: - AlterLanguageOwner(strVal(linitial(stmt->object)), newowner); - break; - - case OBJECT_LARGEOBJECT: - LargeObjectAlterOwner(oidparse(linitial(stmt->object)), newowner); - break; - - case OBJECT_OPERATOR: - Assert(list_length(stmt->objarg) == 2); - AlterOperatorOwner(stmt->object, - (TypeName *) linitial(stmt->objarg), - (TypeName *) lsecond(stmt->objarg), - newowner); - break; - - case OBJECT_OPCLASS: - AlterOpClassOwner(stmt->object, stmt->addname, newowner); - break; - - case OBJECT_OPFAMILY: - AlterOpFamilyOwner(stmt->object, stmt->addname, newowner); - break; - case OBJECT_SCHEMA: AlterSchemaOwner(strVal(linitial(stmt->object)), newowner); break; - case OBJECT_TABLESPACE: - AlterTableSpaceOwner(strVal(linitial(stmt->object)), newowner); - break; - case OBJECT_TYPE: case OBJECT_DOMAIN: /* same as TYPE */ AlterTypeOwner(stmt->object, newowner, stmt->objectType); break; - case OBJECT_TSDICTIONARY: - AlterTSDictionaryOwner(stmt->object, newowner); - break; - - case OBJECT_TSCONFIGURATION: - AlterTSConfigurationOwner(stmt->object, newowner); - break; - case OBJECT_FDW: AlterForeignDataWrapperOwner(strVal(linitial(stmt->object)), newowner); @@ -545,8 +496,232 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) AlterEventTriggerOwner(strVal(linitial(stmt->object)), newowner); break; + /* Generic cases */ + case OBJECT_AGGREGATE: + case OBJECT_COLLATION: + case OBJECT_CONVERSION: + case OBJECT_FUNCTION: + case OBJECT_LANGUAGE: + case OBJECT_LARGEOBJECT: + case OBJECT_OPERATOR: + case OBJECT_OPCLASS: + case OBJECT_OPFAMILY: + case OBJECT_TABLESPACE: + case OBJECT_TSDICTIONARY: + case OBJECT_TSCONFIGURATION: + { + Relation catalog; + Relation relation; + Oid classId; + ObjectAddress address; + + address = get_object_address(stmt->objectType, + stmt->object, + stmt->objarg, + &relation, + AccessExclusiveLock, + false); + classId = address.classId; + + /* + * XXX - get_object_address returns Oid of pg_largeobject + * catalog towards OBJECT_LARGEOBJECT because of historical + * reason. So, we will fix up it here. + */ + if (classId == LargeObjectRelationId) + classId = LargeObjectMetadataRelationId; + + catalog = heap_open(classId, RowExclusiveLock); + + AlterObjectOwner(catalog, + get_object_oid_index(classId), + get_object_catcache_oid(classId), + address.objectId, + newowner, + get_object_attnum_owner(classId), + get_object_attnum_namespace(classId), + get_object_attnum_name(classId), + get_object_attnum_acl(classId), + get_object_aclkind(classId)); + heap_close(catalog, RowExclusiveLock); + if (relation) + heap_close(relation, NoLock); + } + break; default: elog(ERROR, "unrecognized AlterOwnerStmt type: %d", (int) stmt->objectType); } } + +/* + * Generic function to change the ownership of a given object, for simple + * cases (won't tables, nor other cases where we need to do more than + * change the ownership column of a single catalog entry). + * + * catalog: catalog relation containing object (RowExclusiveLock'd by caller) + * oidCacheId: syscache that indexes this catalog by OID + * objectId: OID of object to change the ownership of + * new_ownerId: OID of new object owner + * Anum_owner: column number of catalog's owner column + * Anum_namespace: column number of catalog's namespace column, + * or InvalidAttrNumber if none. + * Anum_acl: column number of catalog's owner column, + * or InvalidAttrNumber if none. + * acl_kind: ACL type for object, or -1 if none assigned + * + * Returns the OID of the object's previous namespace + */ +Oid +AlterObjectOwner(Relation catalog, Oid oidIndexId, int oidCacheId, + Oid objectId, Oid new_ownerId, + AttrNumber Anum_owner, + AttrNumber Anum_namespace, + AttrNumber Anum_name, + AttrNumber Anum_acl, + AclObjectKind aclkind) +{ + HeapTuple oldtup; + HeapTuple newtup; + Datum datum; + bool isnull; + Oid classId; + Oid old_ownerId; + Oid namespaceId = InvalidOid; + + if (oidCacheId > 0) + { + oldtup = SearchSysCacheCopy1(oidCacheId, ObjectIdGetDatum(objectId)); + if (!HeapTupleIsValid(oldtup)) /* should not happen */ + elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", + objectId, RelationGetRelationName(catalog)); + } + else + { + SysScanDesc scan; + ScanKeyData skey; + + Assert(OidIsValid(oidIndexId)); + + ScanKeyInit(&skey, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(objectId)); + + scan = systable_beginscan(catalog, oidIndexId, true, + SnapshotNow, 1, &skey); + oldtup = systable_getnext(scan); + if (!HeapTupleIsValid(oldtup)) + elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", + objectId, RelationGetRelationName(catalog)); + oldtup = heap_copytuple(oldtup); + + systable_endscan(scan); + } + datum = heap_getattr(oldtup, Anum_owner, + RelationGetDescr(catalog), &isnull); + Assert(!isnull); + old_ownerId = DatumGetObjectId(datum); + + if (Anum_namespace != InvalidAttrNumber) + { + datum = heap_getattr(oldtup, Anum_namespace, + RelationGetDescr(catalog), &isnull); + Assert(!isnull); + namespaceId = DatumGetObjectId(datum); + } + + if (old_ownerId != new_ownerId) + { + AttrNumber nattrs; + Datum *values; + bool *nulls; + bool *replaces; + + /* Superusers can bypass permission checks */ + if (!superuser()) + { + /* must be owner */ + if (!has_privs_of_role(GetUserId(), old_ownerId)) + { + char *objname; + char namebuf[NAMEDATALEN]; + + if (Anum_name != InvalidAttrNumber) + { + datum = heap_getattr(oldtup, Anum_name, + RelationGetDescr(catalog), &isnull); + Assert(!isnull); + objname = NameStr(*DatumGetName(datum)); + } + else + { + snprintf(namebuf, sizeof(namebuf), "%u", + HeapTupleGetOid(oldtup)); + objname = namebuf; + } + aclcheck_error(ACLCHECK_NOT_OWNER, aclkind, objname); + } + /* Must be able to become new owner */ + check_is_member_of_role(GetUserId(), new_ownerId); + + /* New owner must have CREATE privilege on namespace */ + if (OidIsValid(namespaceId)) + { + AclResult aclresult; + + aclresult = pg_namespace_aclcheck(namespaceId, new_ownerId, + ACL_CREATE); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, aclkind, + get_namespace_name(namespaceId)); + } + } + + /* Build a modified tuple */ + nattrs = RelationGetNumberOfAttributes(catalog); + values = palloc0(nattrs * sizeof(Datum)); + nulls = palloc0(nattrs * sizeof(bool)); + replaces = palloc0(nattrs * sizeof(bool)); + values[Anum_owner - 1] = ObjectIdGetDatum(new_ownerId); + replaces[Anum_owner - 1] = true; + + /* + * Determine the modified ACL for the new owner. This is only + * necessary when the ACL is non-null. + */ + if (Anum_acl != InvalidAttrNumber) + { + datum = heap_getattr(oldtup, + Anum_acl, RelationGetDescr(catalog), &isnull); + if (!isnull) + { + Acl *newAcl; + + newAcl = aclnewowner(DatumGetAclP(datum), + old_ownerId, new_ownerId); + values[Anum_acl - 1] = PointerGetDatum(newAcl); + replaces[Anum_acl - 1] = true; + } + } + + newtup = heap_modify_tuple(oldtup, RelationGetDescr(catalog), + values, nulls, replaces); + + /* Perform actual update */ + simple_heap_update(catalog, &newtup->t_self, newtup); + CatalogUpdateIndexes(catalog, newtup); + + /* Update owner dependency reference */ + classId = RelationGetRelid(catalog); + if (classId == LargeObjectMetadataRelationId) + classId = LargeObjectRelationId; + changeDependencyOnOwner(classId, HeapTupleGetOid(newtup), new_ownerId); + + /* Release memory */ + pfree(values); + pfree(nulls); + pfree(replaces); + } + return old_ownerId; +} diff --git a/src/backend/commands/collationcmds.c b/src/backend/commands/collationcmds.c index ad75288..fafe89e 100644 --- a/src/backend/commands/collationcmds.c +++ b/src/backend/commands/collationcmds.c @@ -34,9 +34,6 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void AlterCollationOwner_internal(Relation rel, Oid collationOid, - Oid newOwnerId); - /* * CREATE COLLATION */ @@ -212,104 +209,6 @@ RenameCollation(List *name, const char *newname) } /* - * Change collation owner, by name - */ -void -AlterCollationOwner(List *name, Oid newOwnerId) -{ - Oid collationOid; - Relation rel; - - rel = heap_open(CollationRelationId, RowExclusiveLock); - - collationOid = get_collation_oid(name, false); - - AlterCollationOwner_internal(rel, collationOid, newOwnerId); - - heap_close(rel, RowExclusiveLock); -} - -/* - * Change collation owner, by oid - */ -void -AlterCollationOwner_oid(Oid collationOid, Oid newOwnerId) -{ - Relation rel; - - rel = heap_open(CollationRelationId, RowExclusiveLock); - - AlterCollationOwner_internal(rel, collationOid, newOwnerId); - - heap_close(rel, RowExclusiveLock); -} - -/* - * AlterCollationOwner_internal - * - * Internal routine for changing the owner. rel must be pg_collation, already - * open and suitably locked; it will not be closed. - */ -static void -AlterCollationOwner_internal(Relation rel, Oid collationOid, Oid newOwnerId) -{ - Form_pg_collation collForm; - HeapTuple tup; - - Assert(RelationGetRelid(rel) == CollationRelationId); - - tup = SearchSysCacheCopy1(COLLOID, ObjectIdGetDatum(collationOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for collation %u", collationOid); - - collForm = (Form_pg_collation) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (collForm->collowner != newOwnerId) - { - AclResult aclresult; - - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_collation_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_COLLATION, - NameStr(collForm->collname)); - - /* 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(collForm->collnamespace, - newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(collForm->collnamespace)); - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - collForm->collowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(CollationRelationId, collationOid, - newOwnerId); - } - - heap_freetuple(tup); -} - -/* * Execute ALTER COLLATION SET SCHEMA */ void diff --git a/src/backend/commands/conversioncmds.c b/src/backend/commands/conversioncmds.c index af690b8..3a71e33 100644 --- a/src/backend/commands/conversioncmds.c +++ b/src/backend/commands/conversioncmds.c @@ -31,9 +31,6 @@ #include "utils/rel.h" #include "utils/syscache.h" -static void AlterConversionOwner_internal(Relation rel, Oid conversionOid, - Oid newOwnerId); - /* * CREATE CONVERSION */ @@ -168,101 +165,3 @@ RenameConversion(List *name, const char *newname) heap_close(rel, NoLock); heap_freetuple(tup); } - -/* - * Change conversion owner, by name - */ -void -AlterConversionOwner(List *name, Oid newOwnerId) -{ - Oid conversionOid; - Relation rel; - - rel = heap_open(ConversionRelationId, RowExclusiveLock); - - conversionOid = get_conversion_oid(name, false); - - AlterConversionOwner_internal(rel, conversionOid, newOwnerId); - - heap_close(rel, NoLock); -} - -/* - * Change conversion owner, by oid - */ -void -AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId) -{ - Relation rel; - - rel = heap_open(ConversionRelationId, RowExclusiveLock); - - AlterConversionOwner_internal(rel, conversionOid, newOwnerId); - - heap_close(rel, NoLock); -} - -/* - * AlterConversionOwner_internal - * - * Internal routine for changing the owner. rel must be pg_conversion, already - * open and suitably locked; it will not be closed. - */ -static void -AlterConversionOwner_internal(Relation rel, Oid conversionOid, Oid newOwnerId) -{ - Form_pg_conversion convForm; - HeapTuple tup; - - Assert(RelationGetRelid(rel) == ConversionRelationId); - - tup = SearchSysCacheCopy1(CONVOID, ObjectIdGetDatum(conversionOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for conversion %u", conversionOid); - - convForm = (Form_pg_conversion) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (convForm->conowner != newOwnerId) - { - AclResult aclresult; - - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_conversion_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CONVERSION, - NameStr(convForm->conname)); - - /* 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(convForm->connamespace, - newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(convForm->connamespace)); - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - convForm->conowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(ConversionRelationId, conversionOid, - newOwnerId); - } - - heap_freetuple(tup); -} diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index ec8aa17..5712fe1 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -2750,95 +2750,3 @@ ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt) if (relation != NULL) relation_close(relation, NoLock); } - -/* - * AlterExtensionOwner_internal - * - * Internal routine for changing the owner of an extension. rel must be - * pg_extension, already open and suitably locked; it will not be closed. - * - * Note that this only changes ownership of the extension itself; it doesn't - * change the ownership of objects it contains. Since this function is - * currently only called from REASSIGN OWNED, this restriction is okay because - * said objects would also be affected by our caller. But it's not enough for - * a full-fledged ALTER OWNER implementation, so beware. - */ -static void -AlterExtensionOwner_internal(Relation rel, Oid extensionOid, Oid newOwnerId) -{ - Form_pg_extension extForm; - HeapTuple tup; - SysScanDesc scandesc; - ScanKeyData entry[1]; - - Assert(RelationGetRelid(rel) == ExtensionRelationId); - - ScanKeyInit(&entry[0], - ObjectIdAttributeNumber, - BTEqualStrategyNumber, F_OIDEQ, - ObjectIdGetDatum(extensionOid)); - - scandesc = systable_beginscan(rel, ExtensionOidIndexId, true, - SnapshotNow, 1, entry); - - /* We assume that there can be at most one matching tuple */ - tup = systable_getnext(scandesc); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for extension %u", extensionOid); - - tup = heap_copytuple(tup); - systable_endscan(scandesc); - - extForm = (Form_pg_extension) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (extForm->extowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_extension_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_EXTENSION, - NameStr(extForm->extname)); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - /* no privilege checks on namespace are required */ - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - extForm->extowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(ExtensionRelationId, extensionOid, - newOwnerId); - } - - heap_freetuple(tup); -} - -/* - * Change extension owner, by OID - */ -void -AlterExtensionOwner_oid(Oid extensionOid, Oid newOwnerId) -{ - Relation rel; - - rel = heap_open(ExtensionRelationId, RowExclusiveLock); - - AlterExtensionOwner_internal(rel, extensionOid, newOwnerId); - - heap_close(rel, NoLock); -} diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c index bf04073..f685aad 100644 --- a/src/backend/commands/functioncmds.c +++ b/src/backend/commands/functioncmds.c @@ -65,11 +65,6 @@ #include "utils/syscache.h" #include "utils/tqual.h" - -static void AlterFunctionOwner_internal(Relation rel, HeapTuple tup, - Oid newOwnerId); - - /* * Examine the RETURNS clause of the CREATE FUNCTION statement * and return information about it as *prorettype_p and *returnsSet. @@ -1109,138 +1104,6 @@ RenameFunction(List *name, List *argtypes, const char *newname) } /* - * Change function owner by name and args - */ -void -AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId) -{ - Relation rel; - Oid procOid; - HeapTuple tup; - - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - - procOid = LookupFuncNameTypeNames(name, argtypes, false); - - tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for function %u", procOid); - - if (((Form_pg_proc) GETSTRUCT(tup))->proisagg) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("\"%s\" is an aggregate function", - NameListToString(name)), - errhint("Use ALTER AGGREGATE to change owner of aggregate functions."))); - - AlterFunctionOwner_internal(rel, tup, newOwnerId); - - heap_close(rel, NoLock); -} - -/* - * Change function owner by Oid - */ -void -AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId) -{ - Relation rel; - HeapTuple tup; - - rel = heap_open(ProcedureRelationId, RowExclusiveLock); - - tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(procOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for function %u", procOid); - AlterFunctionOwner_internal(rel, tup, newOwnerId); - - heap_close(rel, NoLock); -} - -static void -AlterFunctionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId) -{ - Form_pg_proc procForm; - AclResult aclresult; - Oid procOid; - - Assert(RelationGetRelid(rel) == ProcedureRelationId); - Assert(tup->t_tableOid == ProcedureRelationId); - - procForm = (Form_pg_proc) GETSTRUCT(tup); - procOid = HeapTupleGetOid(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (procForm->proowner != newOwnerId) - { - Datum repl_val[Natts_pg_proc]; - bool repl_null[Natts_pg_proc]; - bool repl_repl[Natts_pg_proc]; - Acl *newAcl; - Datum aclDatum; - bool isNull; - HeapTuple newtuple; - - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_proc_ownercheck(procOid, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_PROC, - NameStr(procForm->proname)); - - /* 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(procForm->pronamespace, - newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(procForm->pronamespace)); - } - - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - repl_repl[Anum_pg_proc_proowner - 1] = true; - repl_val[Anum_pg_proc_proowner - 1] = ObjectIdGetDatum(newOwnerId); - - /* - * Determine the modified ACL for the new owner. This is only - * necessary when the ACL is non-null. - */ - aclDatum = SysCacheGetAttr(PROCOID, tup, - Anum_pg_proc_proacl, - &isNull); - if (!isNull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - procForm->proowner, newOwnerId); - repl_repl[Anum_pg_proc_proacl - 1] = true; - repl_val[Anum_pg_proc_proacl - 1] = PointerGetDatum(newAcl); - } - - newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, - repl_null, repl_repl); - - simple_heap_update(rel, &newtuple->t_self, newtuple); - CatalogUpdateIndexes(rel, newtuple); - - heap_freetuple(newtuple); - - /* Update owner dependency reference */ - changeDependencyOnOwner(ProcedureRelationId, procOid, newOwnerId); - } - - ReleaseSysCache(tup); -} - -/* * Implements the ALTER FUNCTION utility command (except for the * RENAME and OWNER clauses, which are handled as part of the generic * ALTER framework). diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c index e26c947..099bb39 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 @@ -1810,249 +1805,6 @@ RenameOpFamily(List *name, const char *access_method, const char *newname) } /* - * 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 * * If missing_ok is false, throw an error if access method not found. If diff --git a/src/backend/commands/operatorcmds.c b/src/backend/commands/operatorcmds.c index 0d8dbe4..f31bf36 100644 --- a/src/backend/commands/operatorcmds.c +++ b/src/backend/commands/operatorcmds.c @@ -51,9 +51,6 @@ #include "utils/rel.h" #include "utils/syscache.h" - -static void AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid newOwnerId); - /* * DefineOperator * this function extracts all the information from the @@ -333,93 +330,3 @@ RemoveOperatorById(Oid operOid) heap_close(relation, RowExclusiveLock); } - -void -AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId) -{ - Relation rel; - - rel = heap_open(OperatorRelationId, RowExclusiveLock); - - AlterOperatorOwner_internal(rel, operOid, newOwnerId); - - heap_close(rel, NoLock); -} - -/* - * change operator owner - */ -void -AlterOperatorOwner(List *name, TypeName *typeName1, TypeName *typeName2, - Oid newOwnerId) -{ - Oid operOid; - Relation rel; - - rel = heap_open(OperatorRelationId, RowExclusiveLock); - - operOid = LookupOperNameTypeNames(NULL, name, - typeName1, typeName2, - false, -1); - - AlterOperatorOwner_internal(rel, operOid, newOwnerId); - - heap_close(rel, NoLock); -} - -static void -AlterOperatorOwner_internal(Relation rel, Oid operOid, Oid newOwnerId) -{ - HeapTuple tup; - AclResult aclresult; - Form_pg_operator oprForm; - - Assert(RelationGetRelid(rel) == OperatorRelationId); - - tup = SearchSysCacheCopy1(OPEROID, ObjectIdGetDatum(operOid)); - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for operator %u", operOid); - - oprForm = (Form_pg_operator) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (oprForm->oprowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* Otherwise, must be owner of the existing object */ - if (!pg_oper_ownercheck(operOid, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_OPER, - NameStr(oprForm->oprname)); - - /* 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(oprForm->oprnamespace, - newOwnerId, - ACL_CREATE); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_NAMESPACE, - get_namespace_name(oprForm->oprnamespace)); - } - - /* - * Modify the owner --- okay to scribble on tup because it's a copy - */ - oprForm->oprowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(OperatorRelationId, operOid, newOwnerId); - } - - heap_freetuple(tup); -} diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c index 31139bd..ee860c0 100644 --- a/src/backend/commands/proclang.c +++ b/src/backend/commands/proclang.c @@ -55,9 +55,6 @@ static void create_proc_lang(const char *languageName, bool replace, Oid languageOwner, Oid handlerOid, Oid inlineOid, Oid valOid, bool trusted); static PLTemplate *find_language_template(const char *languageName); -static void AlterLanguageOwner_internal(HeapTuple tup, Relation rel, - Oid newOwnerId); - /* --------------------------------------------------------------------- * CREATE PROCEDURAL LANGUAGE @@ -575,120 +572,6 @@ RenameLanguage(const char *oldname, const char *newname) } /* - * Change language owner - */ -void -AlterLanguageOwner(const char *name, Oid newOwnerId) -{ - HeapTuple tup; - Relation rel; - - rel = heap_open(LanguageRelationId, RowExclusiveLock); - - tup = SearchSysCache1(LANGNAME, CStringGetDatum(name)); - if (!HeapTupleIsValid(tup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("language \"%s\" does not exist", name))); - - AlterLanguageOwner_internal(tup, rel, newOwnerId); - - ReleaseSysCache(tup); - - heap_close(rel, RowExclusiveLock); - -} - -/* - * Change language owner, specified by OID - */ -void -AlterLanguageOwner_oid(Oid oid, Oid newOwnerId) -{ - HeapTuple tup; - Relation rel; - - rel = heap_open(LanguageRelationId, RowExclusiveLock); - - tup = SearchSysCache1(LANGOID, ObjectIdGetDatum(oid)); - if (!HeapTupleIsValid(tup)) - elog(ERROR, "cache lookup failed for language %u", oid); - - AlterLanguageOwner_internal(tup, rel, newOwnerId); - - ReleaseSysCache(tup); - - heap_close(rel, RowExclusiveLock); -} - -/* - * Workhorse for AlterLanguageOwner variants - */ -static void -AlterLanguageOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId) -{ - Form_pg_language lanForm; - - lanForm = (Form_pg_language) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (lanForm->lanowner != newOwnerId) - { - Datum repl_val[Natts_pg_language]; - bool repl_null[Natts_pg_language]; - bool repl_repl[Natts_pg_language]; - Acl *newAcl; - Datum aclDatum; - bool isNull; - HeapTuple newtuple; - - /* Otherwise, must be owner of the existing object */ - if (!pg_language_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_LANGUAGE, - NameStr(lanForm->lanname)); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - repl_repl[Anum_pg_language_lanowner - 1] = true; - repl_val[Anum_pg_language_lanowner - 1] = ObjectIdGetDatum(newOwnerId); - - /* - * Determine the modified ACL for the new owner. This is only - * necessary when the ACL is non-null. - */ - aclDatum = SysCacheGetAttr(LANGNAME, tup, - Anum_pg_language_lanacl, - &isNull); - if (!isNull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - lanForm->lanowner, newOwnerId); - repl_repl[Anum_pg_language_lanacl - 1] = true; - repl_val[Anum_pg_language_lanacl - 1] = PointerGetDatum(newAcl); - } - - newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), - repl_val, repl_null, repl_repl); - - simple_heap_update(rel, &newtuple->t_self, newtuple); - CatalogUpdateIndexes(rel, newtuple); - - heap_freetuple(newtuple); - - /* Update owner dependency reference */ - changeDependencyOnOwner(LanguageRelationId, HeapTupleGetOid(tup), - newOwnerId); - } -} - -/* * get_language_oid - given a language name, look up the OID * * If missing_ok is false, throw an error if language name not found. If diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index d1718c1..08899ae 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -884,105 +884,6 @@ RenameTableSpace(const char *oldname, const char *newname) } /* - * Change tablespace owner - */ -void -AlterTableSpaceOwner(const char *name, Oid newOwnerId) -{ - Relation rel; - ScanKeyData entry[1]; - HeapScanDesc scandesc; - Form_pg_tablespace spcForm; - HeapTuple tup; - - /* Search pg_tablespace */ - rel = heap_open(TableSpaceRelationId, RowExclusiveLock); - - ScanKeyInit(&entry[0], - Anum_pg_tablespace_spcname, - BTEqualStrategyNumber, F_NAMEEQ, - CStringGetDatum(name)); - scandesc = heap_beginscan(rel, SnapshotNow, 1, entry); - tup = heap_getnext(scandesc, ForwardScanDirection); - if (!HeapTupleIsValid(tup)) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_OBJECT), - errmsg("tablespace \"%s\" does not exist", name))); - - spcForm = (Form_pg_tablespace) GETSTRUCT(tup); - - /* - * If the new owner is the same as the existing owner, consider the - * command to have succeeded. This is for dump restoration purposes. - */ - if (spcForm->spcowner != newOwnerId) - { - Datum repl_val[Natts_pg_tablespace]; - bool repl_null[Natts_pg_tablespace]; - bool repl_repl[Natts_pg_tablespace]; - Acl *newAcl; - Datum aclDatum; - bool isNull; - HeapTuple newtuple; - - /* Otherwise, must be owner of the existing object */ - if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TABLESPACE, - name); - - /* Must be able to become new owner */ - check_is_member_of_role(GetUserId(), newOwnerId); - - /* - * Normally we would also check for create permissions here, but there - * are none for tablespaces so we follow what rename tablespace does - * and omit the create permissions check. - * - * NOTE: Only superusers may create tablespaces to begin with and so - * initially only a superuser would be able to change its ownership - * anyway. - */ - - memset(repl_null, false, sizeof(repl_null)); - memset(repl_repl, false, sizeof(repl_repl)); - - repl_repl[Anum_pg_tablespace_spcowner - 1] = true; - repl_val[Anum_pg_tablespace_spcowner - 1] = ObjectIdGetDatum(newOwnerId); - - /* - * Determine the modified ACL for the new owner. This is only - * necessary when the ACL is non-null. - */ - aclDatum = heap_getattr(tup, - Anum_pg_tablespace_spcacl, - RelationGetDescr(rel), - &isNull); - if (!isNull) - { - newAcl = aclnewowner(DatumGetAclP(aclDatum), - spcForm->spcowner, newOwnerId); - repl_repl[Anum_pg_tablespace_spcacl - 1] = true; - repl_val[Anum_pg_tablespace_spcacl - 1] = PointerGetDatum(newAcl); - } - - newtuple = heap_modify_tuple(tup, RelationGetDescr(rel), repl_val, repl_null, repl_repl); - - simple_heap_update(rel, &newtuple->t_self, newtuple); - CatalogUpdateIndexes(rel, newtuple); - - heap_freetuple(newtuple); - - /* Update owner dependency reference */ - changeDependencyOnOwner(TableSpaceRelationId, HeapTupleGetOid(tup), - newOwnerId); - } - - heap_endscan(scandesc); - heap_close(rel, NoLock); -} - - -/* * Alter table space options */ void diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index 8d2b4c0..e545e95 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -716,66 +716,6 @@ AlterTSDictionary(AlterTSDictionaryStmt *stmt) heap_close(rel, RowExclusiveLock); } -/* - * ALTER TEXT SEARCH DICTIONARY OWNER - */ -void -AlterTSDictionaryOwner(List *name, Oid newOwnerId) -{ - HeapTuple tup; - Relation rel; - Oid dictId; - Oid namespaceOid; - AclResult aclresult; - Form_pg_ts_dict form; - - rel = heap_open(TSDictionaryRelationId, RowExclusiveLock); - - dictId = get_ts_dict_oid(name, false); - - tup = SearchSysCacheCopy1(TSDICTOID, ObjectIdGetDatum(dictId)); - - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for text search dictionary %u", - dictId); - - form = (Form_pg_ts_dict) GETSTRUCT(tup); - namespaceOid = form->dictnamespace; - - if (form->dictowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* must be owner */ - if (!pg_ts_dict_ownercheck(dictId, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSDICTIONARY, - NameListToString(name)); - - /* 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)); - } - - form->dictowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(TSDictionaryRelationId, HeapTupleGetOid(tup), - newOwnerId); - } - - heap_close(rel, NoLock); - heap_freetuple(tup); -} - /* ---------------------- TS Template commands -----------------------*/ /* @@ -1391,66 +1331,6 @@ RemoveTSConfigurationById(Oid cfgId) } /* - * ALTER TEXT SEARCH CONFIGURATION OWNER - */ -void -AlterTSConfigurationOwner(List *name, Oid newOwnerId) -{ - HeapTuple tup; - Relation rel; - Oid cfgId; - AclResult aclresult; - Oid namespaceOid; - Form_pg_ts_config form; - - rel = heap_open(TSConfigRelationId, RowExclusiveLock); - - cfgId = get_ts_config_oid(name, false); - - tup = SearchSysCacheCopy1(TSCONFIGOID, ObjectIdGetDatum(cfgId)); - - if (!HeapTupleIsValid(tup)) /* should not happen */ - elog(ERROR, "cache lookup failed for text search configuration %u", - cfgId); - - form = (Form_pg_ts_config) GETSTRUCT(tup); - namespaceOid = form->cfgnamespace; - - if (form->cfgowner != newOwnerId) - { - /* Superusers can always do it */ - if (!superuser()) - { - /* must be owner */ - if (!pg_ts_config_ownercheck(cfgId, GetUserId())) - aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_TSCONFIGURATION, - NameListToString(name)); - - /* 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)); - } - - form->cfgowner = newOwnerId; - - simple_heap_update(rel, &tup->t_self, tup); - CatalogUpdateIndexes(rel, tup); - - /* Update owner dependency reference */ - changeDependencyOnOwner(TSConfigRelationId, HeapTupleGetOid(tup), - newOwnerId); - } - - heap_close(rel, NoLock); - heap_freetuple(tup); -} - -/* * ALTER TEXT SEARCH CONFIGURATION - main entry point */ void diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index f5a0aaf..9efc156 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2947,7 +2947,6 @@ _copyAlterOwnerStmt(const AlterOwnerStmt *from) COPY_NODE_FIELD(relation); COPY_NODE_FIELD(object); COPY_NODE_FIELD(objarg); - COPY_STRING_FIELD(addname); COPY_STRING_FIELD(newowner); return newnode; diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 3fad36e..afd0a96 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1349,7 +1349,6 @@ _equalAlterOwnerStmt(const AlterOwnerStmt *a, const AlterOwnerStmt *b) COMPARE_NODE_FIELD(relation); COMPARE_NODE_FIELD(object); COMPARE_NODE_FIELD(objarg); - COMPARE_STRING_FIELD(addname); COMPARE_STRING_FIELD(newowner); return true; diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 7d2ec84..3f23515 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -7359,7 +7359,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPCLASS; n->object = $4; - n->addname = $6; + n->objarg = list_make1(makeString($6)); n->newowner = $9; $$ = (Node *)n; } @@ -7368,7 +7368,7 @@ AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId AlterOwnerStmt *n = makeNode(AlterOwnerStmt); n->objectType = OBJECT_OPFAMILY; n->object = $4; - n->addname = $6; + n->objarg = list_make1(makeString($6)); n->newowner = $9; $$ = (Node *)n; } diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h index d0195ea..a5f0b00 100644 --- a/src/include/catalog/pg_largeobject.h +++ b/src/include/catalog/pg_largeobject.h @@ -55,7 +55,6 @@ typedef FormData_pg_largeobject *Form_pg_largeobject; extern Oid LargeObjectCreate(Oid loid); extern void LargeObjectDrop(Oid loid); -extern void LargeObjectAlterOwner(Oid loid, Oid newOwnerId); extern bool LargeObjectExists(Oid loid); #endif /* PG_LARGEOBJECT_H */ diff --git a/src/include/commands/alter.h b/src/include/commands/alter.h index 210cf4e..6665121 100644 --- a/src/include/commands/alter.h +++ b/src/include/commands/alter.h @@ -25,5 +25,11 @@ extern Oid AlterObjectNamespace(Relation rel, int oidCacheId, int nameCacheId, int Anum_name, int Anum_namespace, int Anum_owner, AclObjectKind acl_kind); extern void ExecAlterOwnerStmt(AlterOwnerStmt *stmt); - +extern Oid AlterObjectOwner(Relation catalog, Oid oidIndexId, int oidCacheId, + Oid objectId, Oid new_ownerId, + AttrNumber Anum_owner, + AttrNumber Anum_namespace, + AttrNumber Anum_name, + AttrNumber Anum_acl, + AclObjectKind aclkind); #endif /* ALTER_H */ diff --git a/src/include/commands/collationcmds.h b/src/include/commands/collationcmds.h index 0587c4f..6d9db09 100644 --- a/src/include/commands/collationcmds.h +++ b/src/include/commands/collationcmds.h @@ -19,8 +19,6 @@ extern void DefineCollation(List *names, List *parameters); extern void RenameCollation(List *name, const char *newname); -extern void AlterCollationOwner(List *name, Oid newOwnerId); -extern void AlterCollationOwner_oid(Oid collationOid, Oid newOwnerId); extern void AlterCollationNamespace(List *name, const char *newschema); extern Oid AlterCollationNamespace_oid(Oid collOid, Oid newNspOid); diff --git a/src/include/commands/conversioncmds.h b/src/include/commands/conversioncmds.h index 778161b..2f9abad 100644 --- a/src/include/commands/conversioncmds.h +++ b/src/include/commands/conversioncmds.h @@ -19,7 +19,5 @@ extern void CreateConversionCommand(CreateConversionStmt *parsetree); extern void RenameConversion(List *name, const char *newname); -extern void AlterConversionOwner(List *name, Oid newOwnerId); -extern void AlterConversionOwner_oid(Oid conversionOid, Oid newOwnerId); #endif /* CONVERSIONCMDS_H */ diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 300f7ea..2c81b78 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -47,8 +47,6 @@ extern void RemoveFunctionById(Oid funcOid); extern void SetFunctionReturnType(Oid funcOid, Oid newRetType); extern void SetFunctionArgType(Oid funcOid, int argIndex, Oid newArgType); extern void RenameFunction(List *name, List *argtypes, const char *newname); -extern void AlterFunctionOwner(List *name, List *argtypes, Oid newOwnerId); -extern void AlterFunctionOwner_oid(Oid procOid, Oid newOwnerId); extern void AlterFunction(AlterFunctionStmt *stmt); extern void CreateCast(CreateCastStmt *stmt); extern void DropCastById(Oid castOid); @@ -61,15 +59,11 @@ extern Oid get_cast_oid(Oid sourcetypeid, Oid targettypeid, bool missing_ok); /* commands/operatorcmds.c */ extern void DefineOperator(List *names, List *parameters); extern void RemoveOperatorById(Oid operOid); -extern void AlterOperatorOwner(List *name, TypeName *typeName1, - TypeName *typename2, Oid newOwnerId); -extern void AlterOperatorOwner_oid(Oid operOid, Oid newOwnerId); /* commands/aggregatecmds.c */ extern void DefineAggregate(List *name, List *args, bool oldstyle, List *parameters); extern void RenameAggregate(List *name, List *args, const char *newname); -extern void AlterAggregateOwner(List *name, List *args, Oid newOwnerId); /* commands/opclasscmds.c */ extern void DefineOpClass(CreateOpClassStmt *stmt); @@ -81,10 +75,6 @@ extern void RemoveAmOpEntryById(Oid entryOid); extern void RemoveAmProcEntryById(Oid entryOid); extern void RenameOpClass(List *name, const char *access_method, const char *newname); 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 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 Oid get_opclass_oid(Oid amID, List *opclassname, bool missing_ok); extern Oid get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok); @@ -98,7 +88,6 @@ extern void DefineTSDictionary(List *names, List *parameters); extern void RenameTSDictionary(List *oldname, const char *newname); extern void RemoveTSDictionaryById(Oid dictId); extern void AlterTSDictionary(AlterTSDictionaryStmt *stmt); -extern void AlterTSDictionaryOwner(List *name, Oid newOwnerId); extern void DefineTSTemplate(List *names, List *parameters); extern void RenameTSTemplate(List *oldname, const char *newname); @@ -108,7 +97,6 @@ extern void DefineTSConfiguration(List *names, List *parameters); extern void RenameTSConfiguration(List *oldname, const char *newname); extern void RemoveTSConfigurationById(Oid cfgId); extern void AlterTSConfiguration(AlterTSConfigurationStmt *stmt); -extern void AlterTSConfigurationOwner(List *name, Oid newOwnerId); extern text *serialize_deflist(List *deflist); extern List *deserialize_deflist(Datum txt); diff --git a/src/include/commands/proclang.h b/src/include/commands/proclang.h index 17d0972..faf1f1c 100644 --- a/src/include/commands/proclang.h +++ b/src/include/commands/proclang.h @@ -17,8 +17,6 @@ extern void CreateProceduralLanguage(CreatePLangStmt *stmt); extern void DropProceduralLanguageById(Oid langOid); extern void RenameLanguage(const char *oldname, const char *newname); -extern void AlterLanguageOwner(const char *name, Oid newOwnerId); -extern void AlterLanguageOwner_oid(Oid oid, Oid newOwnerId); extern bool PLTemplateExists(const char *languageName); extern Oid get_language_oid(const char *langname, bool missing_ok); diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index fe8b6a5..be45c87 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -42,7 +42,6 @@ typedef struct TableSpaceOpts extern void CreateTableSpace(CreateTableSpaceStmt *stmt); extern void DropTableSpace(DropTableSpaceStmt *stmt); extern void RenameTableSpace(const char *oldname, const char *newname); -extern void AlterTableSpaceOwner(const char *name, Oid newOwnerId); extern void AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt); extern void TablespaceCreateDbspace(Oid spcNode, Oid dbNode, bool isRedo); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 201d366..7a2fbde 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -2183,7 +2183,6 @@ typedef struct AlterOwnerStmt RangeVar *relation; /* in case it's a table */ List *object; /* in case it's some other object */ List *objarg; /* argument types, if applicable */ - char *addname; /* additional name if needed */ char *newowner; /* the new owner */ } AlterOwnerStmt;