diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/aclchk.c | 10 | ||||
-rw-r--r-- | src/backend/catalog/pg_shdepend.c | 17 | ||||
-rw-r--r-- | src/backend/commands/alter.c | 48 | ||||
-rw-r--r-- | src/backend/libpq/be-fsstubs.c | 4 | ||||
-rw-r--r-- | src/backend/storage/large_object/inv_api.c | 9 |
5 files changed, 38 insertions, 50 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index 3ce6c09b44d..17461a91890 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -4103,9 +4103,14 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid) if (superuser_arg(roleid)) return true; + /* For large objects, the catalog to consult is pg_largeobject_metadata */ + if (classid == LargeObjectRelationId) + classid = LargeObjectMetadataRelationId; + cacheid = get_object_catcache_oid(classid); if (cacheid != -1) { + /* we can get the object's tuple from the syscache */ HeapTuple tuple; tuple = SearchSysCache1(cacheid, ObjectIdGetDatum(objectid)); @@ -4122,7 +4127,6 @@ object_ownercheck(Oid classid, Oid objectid, Oid roleid) else { /* for catalogs without an appropriate syscache */ - Relation rel; ScanKeyData entry[1]; SysScanDesc scan; @@ -4442,9 +4446,9 @@ recordExtObjInitPriv(Oid objoid, Oid classoid) ReleaseSysCache(tuple); } - /* pg_largeobject_metadata */ - else if (classoid == LargeObjectMetadataRelationId) + else if (classoid == LargeObjectRelationId) { + /* For large objects, we must consult pg_largeobject_metadata */ Datum aclDatum; bool isNull; HeapTuple tuple; diff --git a/src/backend/catalog/pg_shdepend.c b/src/backend/catalog/pg_shdepend.c index 8f09c632f96..f9580fc8c4e 100644 --- a/src/backend/catalog/pg_shdepend.c +++ b/src/backend/catalog/pg_shdepend.c @@ -1614,20 +1614,9 @@ shdepReassignOwned(List *roleids, Oid newrole) case DatabaseRelationId: case TSConfigRelationId: case TSDictionaryRelationId: - { - Oid classId = sdepForm->classid; - Relation catalog; - - if (classId == LargeObjectRelationId) - classId = LargeObjectMetadataRelationId; - - catalog = table_open(classId, RowExclusiveLock); - - AlterObjectOwner_internal(catalog, sdepForm->objid, - newrole); - - table_close(catalog, NoLock); - } + AlterObjectOwner_internal(sdepForm->classid, + sdepForm->objid, + newrole); break; default: diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c index ff8d003876f..e9a344d03e3 100644 --- a/src/backend/commands/alter.c +++ b/src/backend/commands/alter.c @@ -918,9 +918,7 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) case OBJECT_TSDICTIONARY: case OBJECT_TSCONFIGURATION: { - Relation catalog; Relation relation; - Oid classId; ObjectAddress address; address = get_object_address(stmt->objectType, @@ -929,20 +927,9 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) AccessExclusiveLock, false); Assert(relation == NULL); - classId = address.classId; - /* - * XXX - get_object_address returns Oid of pg_largeobject - * catalog for OBJECT_LARGEOBJECT because of historical - * reasons. Fix up it here. - */ - if (classId == LargeObjectRelationId) - classId = LargeObjectMetadataRelationId; - - catalog = table_open(classId, RowExclusiveLock); - - AlterObjectOwner_internal(catalog, address.objectId, newowner); - table_close(catalog, RowExclusiveLock); + AlterObjectOwner_internal(address.classId, address.objectId, + newowner); return address; } @@ -960,25 +947,32 @@ ExecAlterOwnerStmt(AlterOwnerStmt *stmt) * cases (won't work for tables, nor other cases where we need to do more than * change the ownership column of a single catalog entry). * - * rel: catalog relation containing object (RowExclusiveLock'd by caller) + * classId: OID of catalog containing object * objectId: OID of object to change the ownership of * new_ownerId: OID of new object owner + * + * This will work on large objects, but we have to beware of the fact that + * classId isn't the OID of the catalog to modify in that case. */ void -AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) +AlterObjectOwner_internal(Oid classId, Oid objectId, Oid new_ownerId) { - Oid classId = RelationGetRelid(rel); - AttrNumber Anum_oid = get_object_attnum_oid(classId); - AttrNumber Anum_owner = get_object_attnum_owner(classId); - AttrNumber Anum_namespace = get_object_attnum_namespace(classId); - AttrNumber Anum_acl = get_object_attnum_acl(classId); - AttrNumber Anum_name = get_object_attnum_name(classId); + /* For large objects, the catalog to modify is pg_largeobject_metadata */ + Oid catalogId = (classId == LargeObjectRelationId) ? LargeObjectMetadataRelationId : classId; + AttrNumber Anum_oid = get_object_attnum_oid(catalogId); + AttrNumber Anum_owner = get_object_attnum_owner(catalogId); + AttrNumber Anum_namespace = get_object_attnum_namespace(catalogId); + AttrNumber Anum_acl = get_object_attnum_acl(catalogId); + AttrNumber Anum_name = get_object_attnum_name(catalogId); + Relation rel; HeapTuple oldtup; Datum datum; bool isnull; Oid old_ownerId; Oid namespaceId = InvalidOid; + rel = table_open(catalogId, RowExclusiveLock); + oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId); if (oldtup == NULL) elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"", @@ -1026,7 +1020,8 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) snprintf(namebuf, sizeof(namebuf), "%u", objectId); objname = namebuf; } - aclcheck_error(ACLCHECK_NOT_OWNER, get_object_type(classId, objectId), + aclcheck_error(ACLCHECK_NOT_OWNER, + get_object_type(catalogId, objectId), objname); } /* Must be able to become new owner */ @@ -1079,8 +1074,6 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) CatalogTupleUpdate(rel, &newtup->t_self, newtup); /* Update owner dependency reference */ - if (classId == LargeObjectMetadataRelationId) - classId = LargeObjectRelationId; changeDependencyOnOwner(classId, objectId, new_ownerId); /* Release memory */ @@ -1089,5 +1082,8 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId) pfree(replaces); } + /* Note the post-alter hook gets classId not catalogId */ InvokeObjectPostAlterHook(classId, objectId, 0); + + table_close(rel, RowExclusiveLock); } diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c index d189044a4fc..230c6575320 100644 --- a/src/backend/libpq/be-fsstubs.c +++ b/src/backend/libpq/be-fsstubs.c @@ -43,7 +43,7 @@ #include <unistd.h> #include "access/xact.h" -#include "catalog/pg_largeobject_metadata.h" +#include "catalog/pg_largeobject.h" #include "libpq/be-fsstubs.h" #include "libpq/libpq-fs.h" #include "miscadmin.h" @@ -323,7 +323,7 @@ be_lo_unlink(PG_FUNCTION_ARGS) * relevant FDs. */ if (!lo_compat_privileges && - !object_ownercheck(LargeObjectMetadataRelationId, lobjId, GetUserId())) + !object_ownercheck(LargeObjectRelationId, lobjId, GetUserId())) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be owner of large object %u", lobjId))); diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c index cc9c335a92d..a35f1dfeb9f 100644 --- a/src/backend/storage/large_object/inv_api.c +++ b/src/backend/storage/large_object/inv_api.c @@ -221,11 +221,10 @@ inv_create(Oid lobjId) /* * dependency on the owner of largeobject * - * The reason why we use LargeObjectRelationId instead of - * LargeObjectMetadataRelationId here is to provide backward compatibility - * to the applications which utilize a knowledge about internal layout of - * system catalogs. OID of pg_largeobject_metadata and loid of - * pg_largeobject are same value, so there are no actual differences here. + * Note that LO dependencies are recorded using classId + * LargeObjectRelationId for backwards-compatibility reasons. Using + * LargeObjectMetadataRelationId instead would simplify matters for the + * backend, but it'd complicate pg_dump and possibly break other clients. */ recordDependencyOnOwner(LargeObjectRelationId, lobjId_new, GetUserId()); |