Hi, hackers
When executing \du, you can see duplicates of the same role in 'member of'.
This happens when admin | inherit | set options are granted by another role.
---
postgres=# create role role_a login createrole;
CREATE ROLE
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
role_a | Create role
| {}
shinya | Superuser, Create role, Create DB, Replication, Bypass RLS
| {}
postgres=# set role role_a;
SET
postgres=> create role role_b;
CREATE ROLE
postgres=> \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------
role_a | Create role
| {role_b}
role_b | Cannot login
| {}
shinya | Superuser, Create role, Create DB, Replication, Bypass RLS
| {}
postgres=> grant role_b to role_a;
GRANT ROLE
postgres=> \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+-----------------
role_a | Create role
| {role_b,role_b}
role_b | Cannot login
| {}
shinya | Superuser, Create role, Create DB, Replication, Bypass RLS
| {}
postgres=> select rolname, oid from pg_roles where rolname = 'role_b';
rolname | oid
---------+-------
role_b | 16401
(1 row)
postgres=> select * from pg_auth_members where roleid = 16401;
oid | roleid | member | grantor | admin_option | inherit_option |
set_option
-------+--------+--------+---------+--------------+----------------+------------
16402 | 16401 | 16400 | 10 | t | f | f
16403 | 16401 | 16400 | 16400 | f | t | t
(2 rows)
---
Attached patch resolves this issue.
Do you think?
Regards,
Shinya Kato
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 058e41e749..8aeb669100 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -3632,7 +3632,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
"SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
" r.rolconnlimit, r.rolvaliduntil,\n"
- " ARRAY(SELECT b.rolname\n"
+ " ARRAY(SELECT DISTINCT b.rolname\n"
" FROM pg_catalog.pg_auth_members m\n"
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");