diff options
Diffstat (limited to 'src/backend/catalog/objectaddress.c')
-rw-r--r-- | src/backend/catalog/objectaddress.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c index 7b536ac6fde..2983b9180fc 100644 --- a/src/backend/catalog/objectaddress.c +++ b/src/backend/catalog/objectaddress.c @@ -4363,6 +4363,54 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS) } /* + * SQL-level callable function to obtain the ACL of a specified object, given + * its catalog OID and object OID. + */ +Datum +pg_get_acl(PG_FUNCTION_ARGS) +{ + Oid classId = PG_GETARG_OID(0); + Oid objectId = PG_GETARG_OID(1); + Oid catalogId; + AttrNumber Anum_acl; + Relation rel; + HeapTuple tup; + Datum datum; + bool isnull; + + /* for "pinned" items in pg_depend, return null */ + if (!OidIsValid(classId) && !OidIsValid(objectId)) + PG_RETURN_NULL(); + + /* for large objects, the catalog to look at is pg_largeobject_metadata */ + catalogId = (classId == LargeObjectRelationId) ? + LargeObjectMetadataRelationId : classId; + Anum_acl = get_object_attnum_acl(catalogId); + + /* return NULL if no ACL field for this catalog */ + if (Anum_acl == InvalidAttrNumber) + PG_RETURN_NULL(); + + rel = table_open(catalogId, AccessShareLock); + + tup = get_catalog_object_by_oid(rel, get_object_attnum_oid(catalogId), + objectId); + if (!HeapTupleIsValid(tup)) + { + table_close(rel, AccessShareLock); + PG_RETURN_NULL(); + } + + datum = heap_getattr(tup, Anum_acl, RelationGetDescr(rel), &isnull); + table_close(rel, AccessShareLock); + + if (isnull) + PG_RETURN_NULL(); + + PG_RETURN_DATUM(datum); +} + +/* * Return a palloc'ed string that describes the type of object that the * passed address is for. * |