]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
psql: Allow pg_read_all_stats to see database size in \l+
authorFujii Masao <fujii@postgresql.org>
Sat, 25 Jul 2026 10:09:19 +0000 (19:09 +0900)
committerFujii Masao <fujii@postgresql.org>
Sat, 25 Jul 2026 10:09:19 +0000 (19:09 +0900)
pg_database_size() allows access to users who have either CONNECT
privilege on the target database or privileges of the pg_read_all_stats
role. However, previously, psql's \l+ checked only for CONNECT,
so users with privileges of pg_read_all_stats still saw "No Access" for
databases they could not connect to.

Fix this by making \l+ also check
pg_has_role('pg_read_all_stats', 'USAGE'), matching
pg_database_size()'s permission rules.

For back branches, emit the pg_read_all_stats check only when
connected to PostgreSQL 10 or later, since earlier releases do not have
that predefined role.

Backpatch to all supported versions.

Author: Christoph Berg <myon@debian.org>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Discussion: https://postgr.es/m/amCo6qRmnfPVk4-V@msg.df7cb.de
Backpatch-through: 14

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/describe.c

index 7c05afd4719304ed4a46029ac6e7b6623dc5455b..844cd0d5d8b5076a18f852e4b6ebabda6bbbf703 100644 (file)
@@ -2817,8 +2817,9 @@ SELECT
         are displayed in expanded mode.
         If <literal>+</literal> is appended to the command name, database
         sizes, default tablespaces, and descriptions are also displayed.
-        (Size information is only available for databases that the current
-        user can connect to.)
+        Size information is available for databases on which the current user has
+        <literal>CONNECT</literal> privilege, or if the current user is a superuser
+        or has privileges of the <literal>pg_read_all_stats</literal> role.
         </para>
         </listitem>
       </varlistentry>
index af3935b0078715a47e341630f652131798ae428a..f258a33a8087029dbe7c859b3df32c7a76d83294 100644 (file)
@@ -1007,16 +1007,20 @@ listAllDbs(const char *pattern, bool verbose)
        appendPQExpBufferStr(&buf, "  ");
        printACLColumn(&buf, "d.datacl");
        if (verbose)
+       {
                appendPQExpBuffer(&buf,
                                                  ",\n  CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+                                                 "       %s"
                                                  "       THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
                                                  "       ELSE 'No Access'\n"
                                                  "  END as \"%s\""
                                                  ",\n  t.spcname as \"%s\""
                                                  ",\n  pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
+                                                 pset.sversion >= 100000 ? "OR pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')\n" : "",
                                                  gettext_noop("Size"),
                                                  gettext_noop("Tablespace"),
                                                  gettext_noop("Description"));
+       }
        appendPQExpBufferStr(&buf,
                                                 "\nFROM pg_catalog.pg_database d\n");
        if (verbose)