On Wed, Jul 22, 2026 at 11:52 PM Christoph Berg <[email protected]> wrote:
>
> Re: Álvaro Herrera
> > +                                               pset.sversion >= 100000 ? 
> > "OR pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')\n" : "",
>
> Should I create patch files for 14..19?

I've prepared patches for the older stable branches and attached them.

While doing so, I also updated the documentation changes.

Regards,

-- 
Fujii Masao
From 2e9ecd200233768eccafa273abbaf8f667922c0b Mon Sep 17 00:00:00 2001
From: Christoph Berg <[email protected]>
Date: Thu, 23 Jul 2026 17:39:43 +0900
Subject: [PATCH v3] psql: Allow pg_read_all_stats to see database size in \l+

pg_database_size() allows access to users who have either CONNECT
privilege on the target database or membership in the
pg_read_all_stats role. However, previously, psql's \l+ checked only for
CONNECT, so users with 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.
---
 doc/src/sgml/ref/psql-ref.sgml | 5 +++--
 src/bin/psql/describe.c        | 4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 7c05afd4719..6be4648d90e 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -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 that the current user can
+        connect to, or to superusers and roles with privileges of the
+        <literal>pg_read_all_stats</literal> role.
         </para>
         </listitem>
       </varlistentry>
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index af3935b0078..f258a33a808 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -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)
-- 
2.55.0

From 3abb56b17562e626bc18dc83818905e9dd84d50e Mon Sep 17 00:00:00 2001
From: Christoph Berg <[email protected]>
Date: Thu, 23 Jul 2026 17:39:43 +0900
Subject: [PATCH v3] psql: Allow pg_read_all_stats to see database size in \l+

pg_database_size() allows access to users who have either CONNECT
privilege on the target database or membership in the
pg_read_all_stats role. However, previously, psql's \l+ checked only for
CONNECT, so users with 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.
---
 doc/src/sgml/ref/psql-ref.sgml | 5 +++--
 src/bin/psql/describe.c        | 4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index ca3b3db59c8..49c5dd648e3 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2571,8 +2571,9 @@ SELECT
         only databases whose names match the pattern are listed.
         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 that the current user can
+        connect to, or to superusers and roles with privileges of the
+        <literal>pg_read_all_stats</literal> role.
         </para>
         </listitem>
       </varlistentry>
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 3823dca7be2..3fccc543bad 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -953,16 +953,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)
-- 
2.55.0

Attachment: v3-0001-pg20-psql-Allow-pg_read_all_stats-to-see-database-size.patch
Description: Binary data

From 518a15679cb708646fab30e43536f926dbc77233 Mon Sep 17 00:00:00 2001
From: Christoph Berg <[email protected]>
Date: Thu, 23 Jul 2026 17:39:43 +0900
Subject: [PATCH v3] psql: Allow pg_read_all_stats to see database size in \l+

pg_database_size() allows access to users who have either CONNECT
privilege on the target database or membership in the
pg_read_all_stats role. However, previously, psql's \l+ checked only for
CONNECT, so users with 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.
---
 doc/src/sgml/ref/psql-ref.sgml | 5 +++--
 src/bin/psql/describe.c        | 4 ++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index 388efae56ef..d4670e10c84 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -2531,8 +2531,9 @@ SELECT
         only databases whose names match the pattern are listed.
         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 that the current user can
+        connect to, or to superusers and roles with privileges of the
+        <literal>pg_read_all_stats</literal> role.
         </para>
         </listitem>
       </varlistentry>
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 8fe39475fa1..b853b0860f3 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1069,12 +1069,16 @@ listAllDbs(const char *pattern, bool verbose)
        appendPQExpBufferStr(&buf, "       ");
        printACLColumn(&buf, "d.datacl");
        if (verbose && pset.sversion >= 80200)
+       {
                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\"",
+                                                 pset.sversion >= 100000 ? "OR 
pg_catalog.pg_has_role('pg_read_all_stats', 'USAGE')\n" : "",
                                                  gettext_noop("Size"));
+       }
        if (verbose && pset.sversion >= 80000)
                appendPQExpBuffer(&buf,
                                                  ",\n       t.spcname as 
\"%s\"",
-- 
2.55.0

Reply via email to