Skip to content

Commit 062d4b8

Browse files
Pavel LuzanovCommitfest Bot
Pavel Luzanov
authored and
Commitfest Bot
committed
psql: Rethinking of \du command
Cnanges in the \du command - "Login", "Connection limit" and "Valid until" attributes are placed in separate columns. to understand that there is no limit. - The "Attributes" column includes only the enabled logical attributes. - The attribute names correspond to the keywords of the CREATE ROLE command. - The attributes are listed in the same order as in the documentation. - Value -1 for "Connection limit" replaced by NULL to make it easier - General refactoring of describeRoles function in describe.c.
1 parent d73d4cf commit 062d4b8

File tree

3 files changed

+72
-126
lines changed

3 files changed

+72
-126
lines changed

src/bin/psql/describe.c

+39-107
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ static bool describeOneTableDetails(const char *schemaname,
4343
bool verbose);
4444
static void add_tablespace_footer(printTableContent *const cont, char relkind,
4545
Oid tablespace, const bool newline);
46-
static void add_role_attribute(PQExpBuffer buf, const char *const str);
4746
static bool listTSParsersVerbose(const char *pattern);
4847
static bool describeOneTSParser(const char *oid, const char *nspname,
4948
const char *prsname);
@@ -3712,34 +3711,47 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
37123711
{
37133712
PQExpBufferData buf;
37143713
PGresult *res;
3715-
printTableContent cont;
3716-
printTableOpt myopt = pset.popt.topt;
3717-
int ncols = 2;
3718-
int nrows = 0;
3719-
int i;
3720-
int conns;
3721-
const char align = 'l';
3722-
char **attr;
3723-
3724-
myopt.default_footer = false;
3714+
printQueryOpt myopt = pset.popt;
37253715

37263716
initPQExpBuffer(&buf);
3727-
37283717
printfPQExpBuffer(&buf,
3729-
"SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
3730-
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
3731-
" r.rolconnlimit, r.rolvaliduntil");
3732-
3733-
if (verbose)
3734-
{
3735-
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
3736-
ncols++;
3737-
}
3738-
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
3718+
"SELECT r.rolname AS \"%s\",\n"
3719+
" CASE WHEN r.rolcanlogin THEN '%s' ELSE '%s' END \"%s\",\n"
3720+
" pg_catalog.concat_ws(E'\\n',\n"
3721+
" CASE WHEN r.rolsuper THEN '%s' END,\n"
3722+
" CASE WHEN r.rolcreatedb THEN '%s' END,\n"
3723+
" CASE WHEN r.rolcreaterole THEN '%s' END,\n"
3724+
" CASE WHEN r.rolinherit THEN '%s' END,\n"
3725+
" CASE WHEN r.rolreplication THEN '%s' END",
3726+
gettext_noop("Role name"),
3727+
gettext_noop("yes"), gettext_noop("no"),
3728+
gettext_noop("Login"),
3729+
gettext_noop("Superuser"),
3730+
gettext_noop("Create DB"),
3731+
gettext_noop("Create role"),
3732+
gettext_noop("Inherit"),
3733+
gettext_noop("Replication"));
37393734

37403735
if (pset.sversion >= 90500)
3736+
appendPQExpBuffer(&buf,
3737+
",\n CASE WHEN r.rolbypassrls THEN '%s' END",
3738+
gettext_noop("Bypass RLS"));
3739+
3740+
appendPQExpBuffer(&buf, "\n ) AS \"%s\"", gettext_noop("Attributes"));
3741+
3742+
appendPQExpBuffer(&buf,
3743+
",\n r.rolvaliduntil AS \"%s\",\n"
3744+
" CASE WHEN r.rolconnlimit = -1 THEN NULL\n"
3745+
" ELSE r.rolconnlimit\n"
3746+
" END \"%s\"",
3747+
gettext_noop("Valid until"),
3748+
gettext_noop("Connection limit"));
3749+
3750+
if (verbose)
37413751
{
3742-
appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
3752+
appendPQExpBuffer(&buf,
3753+
",\n pg_catalog.shobj_description(r.oid, 'pg_authid') AS \"%s\"",
3754+
gettext_noop("Description"));
37433755
}
37443756

37453757
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
@@ -3758,99 +3770,19 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
37583770
appendPQExpBufferStr(&buf, "ORDER BY 1;");
37593771

37603772
res = PSQLexec(buf.data);
3773+
termPQExpBuffer(&buf);
37613774
if (!res)
37623775
return false;
37633776

3764-
nrows = PQntuples(res);
3765-
attr = pg_malloc0((nrows + 1) * sizeof(*attr));
3766-
3767-
printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
3768-
3769-
printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
3770-
printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
3771-
3772-
if (verbose)
3773-
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
3774-
3775-
for (i = 0; i < nrows; i++)
3776-
{
3777-
printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
3778-
3779-
resetPQExpBuffer(&buf);
3780-
if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
3781-
add_role_attribute(&buf, _("Superuser"));
3782-
3783-
if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
3784-
add_role_attribute(&buf, _("No inheritance"));
3785-
3786-
if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
3787-
add_role_attribute(&buf, _("Create role"));
3788-
3789-
if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
3790-
add_role_attribute(&buf, _("Create DB"));
3791-
3792-
if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
3793-
add_role_attribute(&buf, _("Cannot login"));
3794-
3795-
if (strcmp(PQgetvalue(res, i, (verbose ? 9 : 8)), "t") == 0)
3796-
add_role_attribute(&buf, _("Replication"));
3797-
3798-
if (pset.sversion >= 90500)
3799-
if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3800-
add_role_attribute(&buf, _("Bypass RLS"));
3801-
3802-
conns = atoi(PQgetvalue(res, i, 6));
3803-
if (conns >= 0)
3804-
{
3805-
if (buf.len > 0)
3806-
appendPQExpBufferChar(&buf, '\n');
3807-
3808-
if (conns == 0)
3809-
appendPQExpBufferStr(&buf, _("No connections"));
3810-
else
3811-
appendPQExpBuffer(&buf, ngettext("%d connection",
3812-
"%d connections",
3813-
conns),
3814-
conns);
3815-
}
3816-
3817-
if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3818-
{
3819-
if (buf.len > 0)
3820-
appendPQExpBufferChar(&buf, '\n');
3821-
appendPQExpBufferStr(&buf, _("Password valid until "));
3822-
appendPQExpBufferStr(&buf, PQgetvalue(res, i, 7));
3823-
}
3824-
3825-
attr[i] = pg_strdup(buf.data);
3826-
3827-
printTableAddCell(&cont, attr[i], false, false);
3828-
3829-
if (verbose)
3830-
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3831-
}
3832-
termPQExpBuffer(&buf);
3833-
3834-
printTable(&cont, pset.queryFout, false, pset.logfile);
3835-
printTableCleanup(&cont);
3777+
myopt.title = _("List of roles");
3778+
myopt.translate_header = true;
38363779

3837-
for (i = 0; i < nrows; i++)
3838-
free(attr[i]);
3839-
free(attr);
3780+
printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
38403781

38413782
PQclear(res);
38423783
return true;
38433784
}
38443785

3845-
static void
3846-
add_role_attribute(PQExpBuffer buf, const char *const str)
3847-
{
3848-
if (buf->len > 0)
3849-
appendPQExpBufferStr(buf, ", ");
3850-
3851-
appendPQExpBufferStr(buf, str);
3852-
}
3853-
38543786
/*
38553787
* \drds
38563788
*/

src/test/regress/expected/psql.out

+26-14
Original file line numberDiff line numberDiff line change
@@ -6396,9 +6396,10 @@ List of text search templates
63966396
(0 rows)
63976397

63986398
\dg "no.such.role"
6399-
List of roles
6400-
Role name | Attributes
6401-
-----------+------------
6399+
List of roles
6400+
Role name | Login | Attributes | Valid until | Connection limit
6401+
-----------+-------+------------+-------------+------------------
6402+
(0 rows)
64026403

64036404
\dL "no.such.language"
64046405
List of languages
@@ -6828,10 +6829,11 @@ cross-database references are not implemented: "no.such.database"."no.such.schem
68286829
\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"
68296830
cross-database references are not implemented: "no.such.database"."no.such.schema"."no.such.extended.statistics"
68306831
-- check \drg and \du
6831-
CREATE ROLE regress_du_role0;
6832-
CREATE ROLE regress_du_role1;
6833-
CREATE ROLE regress_du_role2;
6834-
CREATE ROLE regress_du_admin;
6832+
CREATE ROLE regress_du_role0 LOGIN PASSWORD '123' VALID UNTIL '2024-06-04' CONNECTION LIMIT 0;
6833+
CREATE ROLE regress_du_role1 CREATEROLE CONNECTION LIMIT -1 VALID UNTIL 'infinity';
6834+
CREATE ROLE regress_du_role2 LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 42;
6835+
CREATE ROLE regress_du_admin LOGIN SUPERUSER CREATEROLE CREATEDB BYPASSRLS REPLICATION INHERIT;
6836+
COMMENT ON ROLE regress_du_admin IS 'some description';
68356837
GRANT regress_du_role0 TO regress_du_admin WITH ADMIN TRUE;
68366838
GRANT regress_du_role1 TO regress_du_admin WITH ADMIN TRUE;
68376839
GRANT regress_du_role2 TO regress_du_admin WITH ADMIN TRUE;
@@ -6855,13 +6857,23 @@ GRANT regress_du_role0 TO regress_du_role2 WITH ADMIN FALSE, INHERIT FALSE, SET
68556857
regress_du_role2 | regress_du_role1 | ADMIN, SET | regress_du_admin
68566858
(7 rows)
68576859

6858-
\du regress_du_role*
6859-
List of roles
6860-
Role name | Attributes
6861-
------------------+--------------
6862-
regress_du_role0 | Cannot login
6863-
regress_du_role1 | Cannot login
6864-
regress_du_role2 | Cannot login
6860+
\du+ regress_du*
6861+
List of roles
6862+
Role name | Login | Attributes | Valid until | Connection limit | Description
6863+
------------------+-------+-------------+------------------------------+------------------+------------------
6864+
regress_du_admin | yes | Superuser +| | | some description
6865+
| | Create DB +| | |
6866+
| | Create role+| | |
6867+
| | Inherit +| | |
6868+
| | Replication+| | |
6869+
| | Bypass RLS | | |
6870+
regress_du_role0 | yes | Inherit | Tue Jun 04 00:00:00 2024 PDT | 0 |
6871+
regress_du_role1 | no | Create role+| infinity | |
6872+
| | Inherit | | |
6873+
regress_du_role2 | yes | Inherit +| | 42 |
6874+
| | Replication+| | |
6875+
| | Bypass RLS | | |
6876+
(4 rows)
68656877

68666878
DROP ROLE regress_du_role0;
68676879
DROP ROLE regress_du_role1;

src/test/regress/sql/psql.sql

+7-5
Original file line numberDiff line numberDiff line change
@@ -1886,10 +1886,12 @@ DROP FUNCTION psql_error;
18861886
\dX "no.such.database"."no.such.schema"."no.such.extended.statistics"
18871887

18881888
-- check \drg and \du
1889-
CREATE ROLE regress_du_role0;
1890-
CREATE ROLE regress_du_role1;
1891-
CREATE ROLE regress_du_role2;
1892-
CREATE ROLE regress_du_admin;
1889+
CREATE ROLE regress_du_role0 LOGIN PASSWORD '123' VALID UNTIL '2024-06-04' CONNECTION LIMIT 0;
1890+
CREATE ROLE regress_du_role1 CREATEROLE CONNECTION LIMIT -1 VALID UNTIL 'infinity';
1891+
CREATE ROLE regress_du_role2 LOGIN REPLICATION BYPASSRLS CONNECTION LIMIT 42;
1892+
CREATE ROLE regress_du_admin LOGIN SUPERUSER CREATEROLE CREATEDB BYPASSRLS REPLICATION INHERIT;
1893+
1894+
COMMENT ON ROLE regress_du_admin IS 'some description';
18931895

18941896
GRANT regress_du_role0 TO regress_du_admin WITH ADMIN TRUE;
18951897
GRANT regress_du_role1 TO regress_du_admin WITH ADMIN TRUE;
@@ -1904,7 +1906,7 @@ GRANT regress_du_role0 TO regress_du_role1 WITH ADMIN FALSE, INHERIT FALSE, SET
19041906
GRANT regress_du_role0 TO regress_du_role2 WITH ADMIN FALSE, INHERIT FALSE, SET FALSE GRANTED BY regress_du_role2;
19051907

19061908
\drg regress_du_role*
1907-
\du regress_du_role*
1909+
\du+ regress_du*
19081910

19091911
DROP ROLE regress_du_role0;
19101912
DROP ROLE regress_du_role1;

0 commit comments

Comments
 (0)