pgrx icon indicating copy to clipboard operation
pgrx copied to clipboard

Mapping for catclist

Open icewind opened this issue 3 years ago • 3 comments
trafficstars

Hello, I'm trying to read a list of user roles from the sys cache using the following code

let user_oid = pg_sys::GetUserId();
let roles = pg_sys::SearchSysCacheList(
    SysCacheIdentifier_AUTHMEMMEMROLE as i32,
    1,
    user_oid.into_datum().unwrap(),
    0,
    0,
);

And SearchSysCacheList returns *mut catclist which is appears to be declared like this

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct catclist {
    _unused: [u8; 0],
}

Maybe I don't need this mapping and doing it wrong?

icewind avatar Jul 15 '22 15:07 icewind

Could you please show your error that you are experiencing and, if any, more context for your code (preferably the whole function or at least the lines related to the error)

Hoverbear avatar Jul 15 '22 20:07 Hoverbear

Hi @Hoverbear, thank you for the response. I have no errors. It is unclear how can I use it(the structure itself). Because in Postgres CatCList defined like this

typedef struct catclist
{
    int         cl_magic; 
#define CL_MAGIC   0x52765103
    uint32      hash_value;
    dlist_node  cache_elem;
    Datum       keys[CATCACHE_MAXKEYS];
    int         refcount; 
    bool        dead;    
    bool        ordered;
    short       nkeys; 
    int         n_members;
    CatCache   *my_cache;
    CatCTup    *members[FLEXIBLE_ARRAY_MEMBER]; 
} CatCList;

And in C I would write something like this(untested)

CatCList *memlist;
int i;

// There is no binding to SearchSysCacheList1 in pgx so I used SearchSysCacheList
memlist = SearchSysCacheList1(AUTHMEMMEMROLE, ObjectIdGetDatum(GetUserId()));

for (i = 0; i < memlist->n_members; i++)
{
    HeapTuple tup = &memlist->members[i]->tuple;
    Form_pg_auth_members members = (Form_pg_auth_members) GETSTRUCT(tup);

    // and work with a fields of the members structure here.
    // like members->roleid
}

And in rust the structure of catclist is empty. No n_members or members fields. Maybe there is another way to iterate the list of role members? It is pretty much the whole code I'm trying to run. The function will look like this:

pub fn get_current_user_groups() -> Vec<String> {
    let user_oid = pg_sys::GetUserId();

    let roles = pg_sys::SearchSysCacheList(
        SysCacheIdentifier_AUTHMEMMEMROLE as i32,
        1,
        user_oid.into_datum().unwrap(),
        0,
        0,
    );
    
    // And here I need to iterate roles binding which is *mut catclist
}

icewind avatar Jul 15 '22 21:07 icewind

Seems like I need to add utils/catcache.h to the includes list in pgx_sys. I added it and it successfully generated bindings, but it changed thousands lines of code(seems like unwanted PR). Maybe I can submit a PR with a few changes in the includes and bindings will be generated during the release process? Or it is fine? I mean issue a PR with autogenerated changes?

icewind avatar Aug 01 '22 11:08 icewind

Closing this because your original PR suggests that it wasn't a settled question as to which bindings exactly were needed, but we're happy to accept a new PR for whatever bindings you want to add!

workingjubilee avatar Jul 25 '23 03:07 workingjubilee