Thread: aclitem binary encoding

aclitem binary encoding

From
Joseph Koshakow
Date:
Hi all,

I was using a PostgreSQL driver that used binary input/output to query
some ACL data and was surprised to see the following error:

    no binary output function available for type aclitem

In fact, aclitem has no binary input or output functions

    postgres=# SELECT typinput, typoutput, typreceive, typsend FROM pg_type WHERE typname = 'aclitem';
     typinput  | typoutput  | typreceive | typsend
    -----------+------------+------------+---------
     aclitemin | aclitemout | -          | -
    (1 row)

Is this an intentional decision to not support a binary encoding for
aclitem types? Or is it just a lack of a feature?

Thanks,
Joe Koshakow

Re: aclitem binary encoding

From
Tom Lane
Date:
Joseph Koshakow <koshy44@gmail.com> writes:
> Is this an intentional decision to not support a binary encoding for
> aclitem types? Or is it just a lack of a feature?

I think it's at least somewhat intentional, to have a core type
that has no binary I/O so that that case can be tested.  In any
event, a binary representation probably wouldn't be terribly
useful, as it'd contain role OIDs that wouldn't reliably transport
from one system to the next, and also privilege bitmasks that
we sometimes redefine.

            regards, tom lane



Re: aclitem binary encoding

From
Dominique Devienne
Date:
On Fri, Jul 21, 2023 at 4:58 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:
Joseph Koshakow <koshy44@gmail.com> writes:
> Is this an intentional decision to not support a binary encoding for
> aclitem types? Or is it just a lack of a feature?

I'm also using binary input/output, and for ACLs, when not using the usual ACL related functions,
I parse them myself, using code inspired from the official sources. Something like below (for DBs in this case).
Assumes you can deal with text arrays in your code of course. I hope that helps. --DD

select ..., coalesce(datacl, acldefault('d', datdba))::text[] as acls,
  from pg_database

// See getid() from https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/acl.c
std::string_view parseAclName(std::string_view sv, std::string& name) { ... }

// See aclparse() from https://github.com/postgres/postgres/blob/master/src/backend/utils/adt/acl.c
// And also https://www.postgresql.org/docs/current/ddl-priv.html
std::string_view parseAclPrivs(std::string_view sv, AclFlags& privs, AclFlags& grantable) { ... }

// Of the form: grantee=privs/grantor
// Where empty grantee means "public"
void parseAclItem(const std::string& s, AclItem& acl) { ... }
    std::string_view sv(s);
...
    sv = parseAclName(sv, acl.grantee_);
...
    sv = parseAclPrivs(sv, acl.privs_, acl.grantable_);
...
    sv = parseAclName(sv, acl.grantor_);
...
}

void parseAcls(const std::vector<std::string>& acls_in, std::vector<AclItem>& acls_out) {
...
    for (const std::string& acl : acls_in) {
        parseAclItem(acl, acls_out.emplace_back());
    }
}