[PATCH] psql: \dn+ to show size of each schema..
\db+ and \l+ show sizes of tablespaces and databases, so I was surprised in the
past that \dn+ didn't show sizes of schemas. I would find that somewhat
convenient, and I assume other people would use it even more useful.
\db+ and \l+ seem to walk the filesystem, and this is distinguished from those
cases. (Also, schemas are per-DB, not global).
Maybe it's an issue if \dn+ is slow and expensive, since that's how to display
ACL. But \db+ has the same issue. Maybe there should be a \db++ and \dn++ to
allow \dn+ to showing the ACL but not the size.
pg_relation_size() only includes one fork, and the other functions include
toast, which should be in its separate schema, so it has to be summed across
forks.
postgres=# \dnS+
child | postgres | | | 946 MB
information_schema | postgres | postgres=UC/postgres+| | 88 kB
| | =U/postgres | |
pg_catalog | postgres | postgres=UC/postgres+| system catalog schema | 42 MB
| | =U/postgres | |
pg_toast | postgres | | reserved schema for TOAST tables | 3908 MB
public | postgres | postgres=UC/postgres+| standard public schema | 5627 MB
| | =UC/postgres | |
From c2d68eb54f785c759253d4100460aa1af9cbc676 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH] psql: \dn+ to show size of each schema..
See also: 358a897fa, 528ac10c7
---
src/bin/psql/describe.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 2abf255798..6b9b6ea34a 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -5036,6 +5036,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ appendPQExpBuffer(&buf,
+ ",\n (SELECT pg_catalog.pg_size_pretty(sum(pg_relation_size(oid,fork))) FROM pg_catalog.pg_class c,\n"
+ " (VALUES('main'),('fsm'),('vm'),('init')) AS fork(fork) WHERE c.relnamespace = n.oid) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
--
2.17.0
Hi
2021年7月14日(水) 12:07 Justin Pryzby <pryzby@telsasoft.com>:
\db+ and \l+ show sizes of tablespaces and databases, so I was surprised in the
past that \dn+ didn't show sizes of schemas. I would find that somewhat
convenient, and I assume other people would use it even more useful.
It's something which would be useful to have. But see this previous proposal:
/messages/by-id/2d6d2ebf-4dbc-4f74-17d8-05461f4782e2@dalibo.com
Regards
Ian Barwick
--
EnterpriseDB: https://www.enterprisedb.com
On Wed, 2021-07-14 at 14:05 +0900, Ian Lawrence Barwick wrote:
2021年7月14日(水) 12:07 Justin Pryzby <pryzby@telsasoft.com>:
\db+ and \l+ show sizes of tablespaces and databases, so I was surprised in the
past that \dn+ didn't show sizes of schemas. I would find that somewhat
convenient, and I assume other people would use it even more useful.It's something which would be useful to have. But see this previous proposal:
/messages/by-id/2d6d2ebf-4dbc-4f74-17d8-05461f4782e2@dalibo.com
Right, I would not like to cause a lot of I/O activity just to look at the
permissions on a schema...
Besides, schemas are not physical, but logical containers. So I see a point in
measuring the storage used in a certain tablespace, but not so much by all objects
in a certain schema. It might be useful for accounting purposes, though.
But I don't expect it to be in frequent enough demand to add a psql command.
What about inventing a function pg_schema_size(regnamespace)?
Yours,
Laurenz Albe
st 14. 7. 2021 v 7:42 odesílatel Laurenz Albe <laurenz.albe@cybertec.at>
napsal:
On Wed, 2021-07-14 at 14:05 +0900, Ian Lawrence Barwick wrote:
2021年7月14日(水) 12:07 Justin Pryzby <pryzby@telsasoft.com>:
\db+ and \l+ show sizes of tablespaces and databases, so I was
surprised in the
past that \dn+ didn't show sizes of schemas. I would find that
somewhat
convenient, and I assume other people would use it even more useful.
It's something which would be useful to have. But see this previous
proposal:
/messages/by-id/2d6d2ebf-4dbc-4f74-17d8-05461f4782e2@dalibo.com
Right, I would not like to cause a lot of I/O activity just to look at the
permissions on a schema...Besides, schemas are not physical, but logical containers. So I see a
point in
measuring the storage used in a certain tablespace, but not so much by all
objects
in a certain schema. It might be useful for accounting purposes, though.
But I don't expect it to be in frequent enough demand to add a psql
command.What about inventing a function pg_schema_size(regnamespace)?
+1 good idea
Pavel
Show quoted text
Yours,
Laurenz Albe
On Wed, Jul 14, 2021 at 02:05:29PM +0900, Ian Lawrence Barwick wrote:
2021年7月14日(水) 12:07 Justin Pryzby <pryzby@telsasoft.com>:
\db+ and \l+ show sizes of tablespaces and databases, so I was surprised in the
past that \dn+ didn't show sizes of schemas. I would find that somewhat
convenient, and I assume other people would use it even more useful.It's something which would be useful to have. But see this previous proposal:
/messages/by-id/2d6d2ebf-4dbc-4f74-17d8-05461f4782e2@dalibo.com
Thanks for finding that.
It sounds like the objections were:
1) it may be too slow - I propose the size should be shown only with \n++;
I think \db and \l should get the same treatment, and probably everywhere
should change to use the "int verbose". I moved the ++ columns to the
right-most column.
2) it may fail or be misleading if user lacks permissions.
I think Tom's concern was that at some point we might decide to avoid showing a
relation's size to a user who has no access to the rel, and then \dn+ would
show misleading information, or fail.
I implemented this a server-side function for super-user/monitoring role only.
I think \dn++ is also a reasonable way to address the second concern - if
someone asksk for "very verbose" outpu, they get more of an internal,
implementation dependant output, which might be more likely to change in future
releases. For example, if we move the ++ columns to the right, someone might
jusifiably think that the \n and \n+ columns would be less likely to change in
the future than the \n++ columns.
I imagine ++ would find more uses in the future. Like, say, size of an access
methods \dA++. I'll add that in a future revision - I hope that PG15 will also
have create table like (INCLUDE ACCESS METHOD), ALTER TABLE SET ACCESS METHOD,
and pg_restore --no-tableam.
++ may also allow improved testing of psql features - platform dependent stuff
like size can be in ++, allowing better/easier/testing of +.
--
Justin
Attachments:
v2-0001-psql-dn-to-show-size-of-each-schema.patchtext/x-diff; charset=us-asciiDownload
From 21bb5d22492089a804903a817b8dd5c179643056 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH v2 1/5] psql: \dn+ to show size of each schema..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 81 +++++++++++++++++++++++++++++++++
src/bin/psql/describe.c | 7 +++
src/include/catalog/pg_proc.dat | 10 ++++
3 files changed, 98 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index d5a7fb13f3..d13e691807 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,8 +13,10 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
@@ -25,6 +27,8 @@
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
@@ -832,6 +836,83 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/* Compute the size of a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ int64 totalsize = 0;
+ AclResult aclresult;
+ Relation pg_class;
+ ScanKeyData skey;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ ScanKeyInit(&skey, Anum_pg_class_relnamespace,
+ BTEqualStrategyNumber, F_OIDEQ, nspOid);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (int forkNum = 1; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size == 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size == 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ba658f731b..76b50b429d 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -5036,6 +5036,13 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n (SELECT pg_catalog.pg_size_pretty(pg_namespace_size(n.oid))) AS \"%s\"",
+ // ",\n (SELECT pg_catalog.pg_size_pretty(sum(pg_relation_size(oid,fork))) FROM pg_catalog.pg_class c,\n"
+ // " (VALUES('main'),('fsm'),('vm'),('init')) AS fork(fork) WHERE c.relnamespace = n.oid) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index fde251fa4f..2d07f66b67 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7158,6 +7158,16 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.0
v2-0002-psql-dn-db-and-l-to-show-the-size-only-with.patchtext/x-diff; charset=us-asciiDownload
From d6b1732958a3812b4a72538aa8c1f016cf856d1a Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:14:20 -0500
Subject: [PATCH v2 2/5] psql \dn, \db and \l to show the size only with ++..
\dt+ and \dP+ are not changed, since showing the table sizes is their primary
purpose.
---
src/bin/psql/command.c | 20 +++++++++++++-------
src/bin/psql/describe.c | 12 ++++++------
src/bin/psql/describe.h | 6 +++---
3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 49d4c0e3ce..92952b4d19 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -362,7 +362,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -707,6 +708,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -714,7 +716,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -766,7 +771,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
success = listConversions(pattern, show_verbose, show_system);
@@ -813,7 +818,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1870,14 +1875,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
if (pattern)
free(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 76b50b429d..b6a6a378a4 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -217,7 +217,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -263,7 +263,7 @@ describeTablespaces(const char *pattern, bool verbose)
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
- if (verbose && pset.sversion >= 90200)
+ if (verbose > 1 && pset.sversion >= 90200)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
@@ -1023,7 +1023,7 @@ describeOperators(const char *oper_pattern,
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -1046,7 +1046,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 1 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -5016,7 +5016,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -5037,7 +5037,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
- if (verbose && pset.sversion >= 150000)
+ if (verbose > 1 && pset.sversion >= 150000)
appendPQExpBuffer(&buf,
",\n (SELECT pg_catalog.pg_size_pretty(pg_namespace_size(n.oid))) AS \"%s\"",
// ",\n (SELECT pg_catalog.pg_size_pretty(sum(pg_relation_size(oid,fork))) FROM pg_catalog.pg_class c,\n"
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 71b320f1fc..a65f111130 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -16,7 +16,7 @@ extern bool describeAggregates(const char *pattern, bool verbose, bool showSyste
extern bool describeAccessMethods(const char *pattern, bool verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -83,7 +83,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.0
v2-0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 6fc9726ce426aa7542bb28391391771a526a9e4b Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH v2 3/5] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 76 ++++++++++++++++++++---------------------
src/bin/psql/describe.c | 62 ++++++++++++++++-----------------
src/bin/psql/describe.h | 56 +++++++++++++++---------------
3 files changed, 96 insertions(+), 98 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 92952b4d19..34f1ee54b5 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -709,8 +709,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -719,7 +718,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -728,10 +726,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -744,19 +742,19 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -768,16 +766,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
break;
case 'c':
- success = listConversions(pattern, show_verbose, show_system);
+ success = listConversions(pattern, verbose, show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -786,7 +784,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -800,7 +798,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -809,23 +807,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
success = do_lo_list();
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -848,7 +846,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -856,7 +854,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -878,36 +876,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -918,16 +916,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -935,7 +933,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -944,7 +942,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -966,7 +964,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -989,11 +987,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index b6a6a378a4..afdb330d41 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -32,7 +32,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -61,7 +61,7 @@ static bool listOneExtensionContents(const char *extname, const char *oid);
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -147,7 +147,7 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -315,7 +315,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -714,7 +714,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -890,7 +890,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1527,10 +1527,10 @@ objectDescription(const char *pattern, bool showSystem)
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1611,7 +1611,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -3736,7 +3736,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3992,7 +3992,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -4208,7 +4208,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4404,7 +4404,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4479,7 +4479,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4565,7 +4565,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4641,7 +4641,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4799,7 +4799,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4917,7 +4917,7 @@ listCasts(const char *pattern, bool verbose)
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -5080,7 +5080,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5327,7 +5327,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5398,7 +5398,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5469,7 +5469,7 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5675,7 +5675,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5758,7 +5758,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5840,7 +5840,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5901,7 +5901,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6390,7 +6390,7 @@ describePublications(const char *pattern)
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6501,7 +6501,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6595,7 +6595,7 @@ listOperatorClasses(const char *access_method_pattern,
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6677,7 +6677,7 @@ listOperatorFamilies(const char *access_method_pattern,
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6764,7 +6764,7 @@ listOpFamilyOperators(const char *access_method_pattern,
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index a65f111130..cdf286242b 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,10 +10,10 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
extern bool describeTablespaces(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,58 +47,58 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -110,7 +110,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -119,25 +119,25 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
#endif /* DESCRIBE_H */
--
2.17.0
v2-0004-f-change-if-verbose-to-if-verbose-0.patchtext/x-diff; charset=us-asciiDownload
From 72679f3c7d8b56b2a1f341d389f79040ccca9dd2 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:23:25 -0500
Subject: [PATCH v2 4/5] f! change if (verbose) to if (verbose > 0)
---
src/bin/psql/command.c | 4 +-
src/bin/psql/describe.c | 112 ++++++++++++++++++++--------------------
2 files changed, 58 insertions(+), 58 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 34f1ee54b5..c3738a106f 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -876,7 +876,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
@@ -933,7 +933,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index afdb330d41..4d76f117c3 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -177,7 +177,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -252,13 +252,13 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
}
- if (verbose && pset.sversion >= 90000)
+ if (verbose > 0 && pset.sversion >= 90000)
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
@@ -268,7 +268,7 @@ describeTablespaces(const char *pattern, int verbose)
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Description"));
@@ -475,7 +475,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -535,7 +535,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -727,7 +727,7 @@ describeTypes(const char *pattern, int verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
" CASE WHEN t.typrelid != 0\n"
@@ -738,7 +738,7 @@ describeTypes(const char *pattern, int verbose, bool showSystem)
" END AS \"%s\",\n",
gettext_noop("Internal name"),
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80300)
+ if (verbose > 0 && pset.sversion >= 80300)
{
appendPQExpBufferStr(&buf,
" pg_catalog.array_to_string(\n"
@@ -760,13 +760,13 @@ describeTypes(const char *pattern, int verbose, bool showSystem)
" ) AS \"%s\",\n",
gettext_noop("Elements"));
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
gettext_noop("Owner"));
}
- if (verbose && pset.sversion >= 90200)
+ if (verbose > 0 && pset.sversion >= 90200)
{
printACLColumn(&buf, "t.typacl");
appendPQExpBufferStr(&buf, ",\n ");
@@ -927,7 +927,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1053,17 +1053,17 @@ listAllDbs(const char *pattern, int verbose)
" ELSE 'No Access'\n"
" END as \"%s\"",
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80000)
+ if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\"",
gettext_noop("Tablespace"));
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose && pset.sversion >= 80000)
+ if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -2050,7 +2050,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2313,7 +2313,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2336,7 +2336,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3543,7 +3543,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3593,7 +3593,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3617,7 +3617,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3625,7 +3625,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3633,7 +3633,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3764,7 +3764,7 @@ describeRoles(const char *pattern, int verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
@@ -3819,7 +3819,7 @@ describeRoles(const char *pattern, int verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3879,7 +3879,7 @@ describeRoles(const char *pattern, int verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -4057,7 +4057,7 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged. Like
@@ -4283,7 +4283,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n c2.oid::regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4318,7 +4318,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4424,7 +4424,7 @@ listLanguages(const char *pattern, int verbose, bool showSystem)
" l.lanpltrusted AS \"%s\"",
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4510,7 +4510,7 @@ listDomains(const char *pattern, int verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion >= 90200)
{
@@ -4526,7 +4526,7 @@ listDomains(const char *pattern, int verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4589,7 +4589,7 @@ listConversions(const char *pattern, int verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4599,7 +4599,7 @@ listConversions(const char *pattern, int verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4672,7 +4672,7 @@ listEventTriggers(const char *pattern, int verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4847,7 +4847,7 @@ listCasts(const char *pattern, int verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4868,7 +4868,7 @@ listCasts(const char *pattern, int verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4966,7 +4966,7 @@ listCollations(const char *pattern, int verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5029,7 +5029,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5096,7 +5096,7 @@ listTSParsers(const char *pattern, int verbose)
return true;
}
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5352,7 +5352,7 @@ listTSDictionaries(const char *pattern, int verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5416,7 +5416,7 @@ listTSTemplates(const char *pattern, int verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5485,7 +5485,7 @@ listTSConfigs(const char *pattern, int verbose)
return true;
}
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5705,7 +5705,7 @@ listForeignDataWrappers(const char *pattern, int verbose)
" fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5726,7 +5726,7 @@ listForeignDataWrappers(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose && pset.sversion >= 90100)
+ if (verbose > 0 && pset.sversion >= 90100)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5783,7 +5783,7 @@ listForeignServers(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5808,7 +5808,7 @@ listForeignServers(const char *pattern, int verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5863,7 +5863,7 @@ listUserMappings(const char *pattern, int verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5926,7 +5926,7 @@ listForeignTables(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5946,7 +5946,7 @@ listForeignTables(const char *pattern, int verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6420,7 +6420,7 @@ describeSubscriptions(const char *pattern, int verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6536,7 +6536,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6552,7 +6552,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6620,7 +6620,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6710,7 +6710,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6719,7 +6719,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6791,7 +6791,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
--
2.17.0
v2-0005-Move-the-double-plus-verbose-options-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 5339b8a9dd54874ee07c53877e9aee4eae744ddc Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 13:35:26 -0500
Subject: [PATCH v2 5/5] Move the double-plus verbose options to the right-most
column
---
src/bin/psql/describe.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 4d76f117c3..4304e0b890 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -263,16 +263,16 @@ describeTablespaces(const char *pattern, int verbose)
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
- if (verbose > 1 && pset.sversion >= 90200)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Description"));
+ if (verbose > 1 && pset.sversion >= 90200)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -1046,13 +1046,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1 && pset.sversion >= 80200)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
+
if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\"",
@@ -1061,6 +1055,15 @@ listAllDbs(const char *pattern, int verbose)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 80200)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0 && pset.sversion >= 80000)
--
2.17.0
On Wed, Jul 14, 2021 at 07:42:33AM +0200, Laurenz Albe wrote:
Besides, schemas are not physical, but logical containers. So I see a point in
measuring the storage used in a certain tablespace, but not so much by all objects
in a certain schema. It might be useful for accounting purposes, though.
We use only a few schemas, 1) to hide child tables; 2) to exclude some extended
stats from backups, and 1-2 other things. But it's useful to be able to see
how storage is used by schema, and better to do it conveniently.
I think it'd be even more useful for people who use schemas more widely than we
do:
"Who's using all our space?"
\dn++
"Oh, it's that one - let me clean that up..."
Or, "what's the pg_toast stuff, and do I need to do something about it?"
But I don't expect it to be in frequent enough demand to add a psql command.
What about inventing a function pg_schema_size(regnamespace)?
But for "physical" storage it's also possible to get the size from the OS, much
more efficiently, using /bin/df or zfs list (assuming nothing else is using
those filesystems). The pg_*_size functions are inefficient, but psql \db+ and
\l+ already call them anyway.
For schemas, there's no way to get the size from the OS, so it's nice to make
the size available from psql, conveniently.
v3 patch:
- fixes an off by one in forkNum loop;
- removes an unnecessary subquery in describe.c;
- returns 0 rather than NULL if the schema is empty;
- adds pg_am_size;
regression=# \dA++
List of access methods
Name | Type | Handler | Description | Size
--------+-------+----------------------+----------------------------------------+---------
brin | Index | brinhandler | block range index (BRIN) access method | 744 kB
btree | Index | bthandler | b-tree index access method | 21 MB
gin | Index | ginhandler | GIN index access method | 2672 kB
gist | Index | gisthandler | GiST index access method | 2800 kB
hash | Index | hashhandler | hash index access method | 2112 kB
heap | Table | heap_tableam_handler | heap table access method | 60 MB
heap2 | Table | heap_tableam_handler | | 120 kB
spgist | Index | spghandler | SP-GiST index access method | 5840 kB
(8 rows)
regression=# \dn++
List of schemas
Name | Owner | Access privileges | Description | Size
--------------------+---------+--------------------+------------------------+---------
fkpart3 | pryzbyj | | | 168 kB
fkpart4 | pryzbyj | | | 104 kB
fkpart5 | pryzbyj | | | 40 kB
fkpart6 | pryzbyj | | | 48 kB
mvtest_mvschema | pryzbyj | | | 16 kB
public | pryzbyj | pryzbyj=UC/pryzbyj+| standard public schema | 69 MB
| | =UC/pryzbyj | |
regress_indexing | pryzbyj | | | 48 kB
regress_rls_schema | pryzbyj | | | 0 bytes
regress_schema_2 | pryzbyj | | | 0 bytes
testxmlschema | pryzbyj | | | 24 kB
(10 rows)
--
Justin
Attachments:
v3-0001-psql-show-size-of-schemas-and-AMs-in-dn-and-dA.patchtext/x-diff; charset=us-asciiDownload
From d7f5446c0aa1a12a512482d2ed121eb44f6e2f59 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH v3 1/4] psql: show size of schemas and AMs in \dn+ and \dA+..
See also: 358a897fa, 528ac10c7
Add pg_am_size() and psql \dA++
---
src/backend/utils/adt/dbsize.c | 138 ++++++++++++++++++++++++++++++++
src/bin/psql/describe.c | 12 ++-
src/include/catalog/pg_proc.dat | 19 +++++
3 files changed, 168 insertions(+), 1 deletion(-)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index d5a7fb13f3..62273d4f15 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,23 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
@@ -832,6 +837,139 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/* Return the sum of size of relations for which the given attribute has the specified OID */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (int forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using an access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(amOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_am_name(amOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ba658f731b..fe5d88a2b7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -152,7 +152,7 @@ describeAccessMethods(const char *pattern, bool verbose)
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -184,6 +184,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -5036,6 +5041,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index fde251fa4f..4518aad200 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7158,6 +7158,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.0
v3-0002-psql-dn-dA-db-and-l-to-show-the-size-only-with.patchtext/x-diff; charset=us-asciiDownload
From 351de9f97334467b5513b2245e62ea3edad3d1f5 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:14:20 -0500
Subject: [PATCH v3 2/4] psql \dn, \dA, \db and \l to show the size only with
++..
\dt+ and \dP+ are not changed, since showing the table sizes is their primary
purpose.
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 16 ++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 49d4c0e3ce..bfb10d91e4 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -362,7 +362,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -707,6 +708,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -714,7 +716,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -739,7 +744,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -766,7 +771,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
success = listConversions(pattern, show_verbose, show_system);
@@ -813,7 +818,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1870,14 +1875,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
if (pattern)
free(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index fe5d88a2b7..ce04dbb9ce 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -147,7 +147,7 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -185,7 +185,7 @@ describeAccessMethods(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Description"));
- if (pset.sversion >= 150000)
+ if (verbose > 1 && pset.sversion >= 150000)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
gettext_noop("Size"));
@@ -222,7 +222,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -268,7 +268,7 @@ describeTablespaces(const char *pattern, bool verbose)
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
- if (verbose && pset.sversion >= 90200)
+ if (verbose > 1 && pset.sversion >= 90200)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
@@ -1028,7 +1028,7 @@ describeOperators(const char *oper_pattern,
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -1051,7 +1051,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 1 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -5021,7 +5021,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -5042,7 +5042,7 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
- if (verbose && pset.sversion >= 150000)
+ if (verbose > 1 && pset.sversion >= 150000)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
gettext_noop("Size"));
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 71b320f1fc..edeea38580 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -83,7 +83,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.0
v3-0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 79b02af25ba0253b6025cef6b3e94abb2ddfe2eb Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH v3 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 74 +++++++++--------
src/bin/psql/describe.c | 172 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 54 ++++++-------
3 files changed, 149 insertions(+), 151 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index bfb10d91e4..c3738a106f 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -709,8 +709,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -719,7 +718,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -728,10 +726,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -747,16 +745,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -768,16 +766,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
break;
case 'c':
- success = listConversions(pattern, show_verbose, show_system);
+ success = listConversions(pattern, verbose, show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -786,7 +784,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -800,7 +798,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -809,23 +807,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
success = do_lo_list();
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -848,7 +846,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -856,7 +854,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -878,36 +876,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -918,16 +916,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -935,7 +933,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -944,7 +942,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -966,7 +964,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -989,11 +987,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ce04dbb9ce..d6e3fee154 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -32,7 +32,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -61,7 +61,7 @@ static bool listOneExtensionContents(const char *extname, const char *oid);
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -177,7 +177,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -257,13 +257,13 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
}
- if (verbose && pset.sversion >= 90000)
+ if (verbose > 0 && pset.sversion >= 90000)
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
@@ -273,7 +273,7 @@ describeTablespaces(const char *pattern, int verbose)
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Description"));
@@ -320,7 +320,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -480,7 +480,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -540,7 +540,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -719,7 +719,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -732,7 +732,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
" CASE WHEN t.typrelid != 0\n"
@@ -743,7 +743,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" END AS \"%s\",\n",
gettext_noop("Internal name"),
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80300)
+ if (verbose > 0 && pset.sversion >= 80300)
{
appendPQExpBufferStr(&buf,
" pg_catalog.array_to_string(\n"
@@ -765,13 +765,13 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" ) AS \"%s\",\n",
gettext_noop("Elements"));
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
gettext_noop("Owner"));
}
- if (verbose && pset.sversion >= 90200)
+ if (verbose > 0 && pset.sversion >= 90200)
{
printACLColumn(&buf, "t.typacl");
appendPQExpBufferStr(&buf, ",\n ");
@@ -895,7 +895,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -932,7 +932,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1058,17 +1058,17 @@ listAllDbs(const char *pattern, int verbose)
" ELSE 'No Access'\n"
" END as \"%s\"",
gettext_noop("Size"));
- if (verbose && pset.sversion >= 80000)
+ if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\"",
gettext_noop("Tablespace"));
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose && pset.sversion >= 80000)
+ if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1532,10 +1532,10 @@ objectDescription(const char *pattern, bool showSystem)
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1616,7 +1616,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -2055,7 +2055,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2318,7 +2318,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2341,7 +2341,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3548,7 +3548,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3598,7 +3598,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3622,7 +3622,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3630,7 +3630,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3638,7 +3638,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3741,7 +3741,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3769,7 +3769,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
@@ -3824,7 +3824,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3884,7 +3884,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose && pset.sversion >= 80200)
+ if (verbose > 0 && pset.sversion >= 80200)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3997,7 +3997,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -4062,7 +4062,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged. Like
@@ -4213,7 +4213,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4288,7 +4288,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4323,7 +4323,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4409,7 +4409,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4429,7 +4429,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
" l.lanpltrusted AS \"%s\"",
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4484,7 +4484,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4515,7 +4515,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion >= 90200)
{
@@ -4531,7 +4531,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4570,7 +4570,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4594,7 +4594,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4604,7 +4604,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4646,7 +4646,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4677,7 +4677,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4804,7 +4804,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4852,7 +4852,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4873,7 +4873,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4922,7 +4922,7 @@ listCasts(const char *pattern, bool verbose)
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4971,7 +4971,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5034,7 +5034,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5083,7 +5083,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5099,7 +5099,7 @@ listTSParsers(const char *pattern, bool verbose)
return true;
}
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5330,7 +5330,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5355,7 +5355,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5401,7 +5401,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5419,7 +5419,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5472,7 +5472,7 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5488,7 +5488,7 @@ listTSConfigs(const char *pattern, bool verbose)
return true;
}
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5678,7 +5678,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5708,7 +5708,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
" fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5729,7 +5729,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose && pset.sversion >= 90100)
+ if (verbose > 0 && pset.sversion >= 90100)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5761,7 +5761,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5786,7 +5786,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5811,7 +5811,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5843,7 +5843,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5866,7 +5866,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5904,7 +5904,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5929,7 +5929,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5949,7 +5949,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6393,7 +6393,7 @@ describePublications(const char *pattern)
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6423,7 +6423,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6504,7 +6504,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6539,7 +6539,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6555,7 +6555,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6598,7 +6598,7 @@ listOperatorClasses(const char *access_method_pattern,
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6623,7 +6623,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6680,7 +6680,7 @@ listOperatorFamilies(const char *access_method_pattern,
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6713,7 +6713,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6722,7 +6722,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6767,7 +6767,7 @@ listOpFamilyOperators(const char *access_method_pattern,
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6794,7 +6794,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index edeea38580..cdf286242b 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,58 +47,58 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -110,7 +110,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -119,25 +119,25 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
#endif /* DESCRIBE_H */
--
2.17.0
v3-0004-Move-the-double-plus-verbose-options-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 4dd48f8ce389d176bf153dcfce601558b9e823fb Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 13:35:26 -0500
Subject: [PATCH v3 4/4] Move the double-plus verbose options to the right-most
column
---
src/bin/psql/describe.c | 27 +++++++++++++++------------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index d6e3fee154..2829d3c0f1 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -268,16 +268,16 @@ describeTablespaces(const char *pattern, int verbose)
",\n spcoptions AS \"%s\"",
gettext_noop("Options"));
- if (verbose > 1 && pset.sversion >= 90200)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
if (verbose > 0 && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Description"));
+ if (verbose > 1 && pset.sversion >= 90200)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -1051,13 +1051,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1 && pset.sversion >= 80200)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
+
if (verbose > 0 && pset.sversion >= 80000)
appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\"",
@@ -1066,6 +1060,15 @@ listAllDbs(const char *pattern, int verbose)
appendPQExpBuffer(&buf,
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 80200)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0 && pset.sversion >= 80000)
--
2.17.0
On Thu, 2021-07-15 at 20:16 -0500, Justin Pryzby wrote:
On Wed, Jul 14, 2021 at 07:42:33AM +0200, Laurenz Albe wrote:
Besides, schemas are not physical, but logical containers. So I see a point in
measuring the storage used in a certain tablespace, but not so much by all objects
in a certain schema. It might be useful for accounting purposes, though.But I don't expect it to be in frequent enough demand to add a psql command.
But for "physical" storage it's also possible to get the size from the OS, much
more efficiently, using /bin/df or zfs list (assuming nothing else is using
those filesystems). The pg_*_size functions are inefficient, but psql \db+ and
\l+ already call them anyway.
Hm, yes, the fact that \l+ does something similar detracts from my argument.
It seems somewhat inconsistent to have the size in \l+, but not in \dn+.
Still, there is a difference: I never need \l+, because \l already shows
the permissions on the database, but I often need \dn+ to see the permissions
on schemas. And I don't want to measure the size when I do that.
The problem is that our backslash commands are not totally consistent in
that respect, and we can hardly fix that.
Yours,
Laurenz Albe
pá 17. 9. 2021 v 11:10 odesílatel Justin Pryzby <pryzby@telsasoft.com>
napsal:
On Wed, Jul 14, 2021 at 07:42:33AM +0200, Laurenz Albe wrote:
Besides, schemas are not physical, but logical containers. So I see a
point in
measuring the storage used in a certain tablespace, but not so much by
all objects
in a certain schema. It might be useful for accounting purposes, though.
We use only a few schemas, 1) to hide child tables; 2) to exclude some
extended
stats from backups, and 1-2 other things. But it's useful to be able to
see
how storage is used by schema, and better to do it conveniently.I think it'd be even more useful for people who use schemas more widely
than we
do:
"Who's using all our space?"
\dn++
"Oh, it's that one - let me clean that up..."Or, "what's the pg_toast stuff, and do I need to do something about it?"
But I don't expect it to be in frequent enough demand to add a psql
command.
What about inventing a function pg_schema_size(regnamespace)?
But for "physical" storage it's also possible to get the size from the OS,
much
more efficiently, using /bin/df or zfs list (assuming nothing else is using
those filesystems). The pg_*_size functions are inefficient, but psql
\db+ and
\l+ already call them anyway.For schemas, there's no way to get the size from the OS, so it's nice to
make
the size available from psql, conveniently.v3 patch:
- fixes an off by one in forkNum loop;
- removes an unnecessary subquery in describe.c;
- returns 0 rather than NULL if the schema is empty;
- adds pg_am_size;regression=# \dA++
List of access methods
Name | Type | Handler | Description
| Size--------+-------+----------------------+----------------------------------------+---------
brin | Index | brinhandler | block range index (BRIN) access
method | 744 kB
btree | Index | bthandler | b-tree index access method
| 21 MB
gin | Index | ginhandler | GIN index access method
| 2672 kB
gist | Index | gisthandler | GiST index access method
| 2800 kB
hash | Index | hashhandler | hash index access method
| 2112 kB
heap | Table | heap_tableam_handler | heap table access method
| 60 MB
heap2 | Table | heap_tableam_handler |
| 120 kB
spgist | Index | spghandler | SP-GiST index access method
| 5840 kB
(8 rows)regression=# \dn++
List of schemas
Name | Owner | Access privileges | Description
| Size--------------------+---------+--------------------+------------------------+---------
fkpart3 | pryzbyj | |
| 168 kB
fkpart4 | pryzbyj | |
| 104 kB
fkpart5 | pryzbyj | |
| 40 kB
fkpart6 | pryzbyj | |
| 48 kB
mvtest_mvschema | pryzbyj | |
| 16 kB
public | pryzbyj | pryzbyj=UC/pryzbyj+| standard public
schema | 69 MB
| | =UC/pryzbyj |
|
regress_indexing | pryzbyj | |
| 48 kB
regress_rls_schema | pryzbyj | |
| 0 bytes
regress_schema_2 | pryzbyj | |
| 0 bytes
testxmlschema | pryzbyj | |
| 24 kB
(10 rows)
I tested this patch. It looks well. The performance is good enough. I got
the result for a schema with 100K tables in 3 seconds.
I am not sure if using \dt+ and \dP+ without change is a good idea. I can
imagine \dt+ and \dt++. \dP can exist just only in ++ form or we can ignore
it (like now, and support \dP+ and \dP++) with same result
I can live with the proposed patch, and I understand why ++ was
introduced. But I am still not sure it is really user friendly. I prefer to
extend \dA and \dn with some columns (\dA has only two columns and \dn has
two columns too), and then we don't need special ++ variants for sizes.
Using three levels of detail looks not too practical (more when the basic
reports \dA and \dn) are really very simple).
Regards
Pavel
--
Show quoted text
Justin
On Fri, Sep 17, 2021 at 12:05:04PM +0200, Pavel Stehule wrote:
I can live with the proposed patch, and I understand why ++ was
introduced. But I am still not sure it is really user friendly. I prefer to
extend \dA and \dn with some columns (\dA has only two columns and \dn has
two columns too), and then we don't need special ++ variants for sizes.
Using three levels of detail looks not too practical (more when the basic
reports \dA and \dn) are really very simple).
You're suggesting to include the ACL+description in \dn and handler+description
and \dA.
Another option is to add pg_schema_size() and pg_am_size() without shortcuts in
psql. That would avoid showing a potentially huge ACL when all one wants is
the schema size, and would serve my purposes well enough to write
| SELECT pg_namespace_size(oid), nspname FROM pg_namespace ORDER BY 1 DESC LIMIT 9;
--
Justin
út 28. 9. 2021 v 4:46 odesílatel Justin Pryzby <pryzby@telsasoft.com>
napsal:
On Fri, Sep 17, 2021 at 12:05:04PM +0200, Pavel Stehule wrote:
I can live with the proposed patch, and I understand why ++ was
introduced. But I am still not sure it is really user friendly. I preferto
extend \dA and \dn with some columns (\dA has only two columns and \dn
has
two columns too), and then we don't need special ++ variants for sizes.
Using three levels of detail looks not too practical (more when the basic
reports \dA and \dn) are really very simple).You're suggesting to include the ACL+description in \dn and
handler+description
and \dA.
yes
Another option is to add pg_schema_size() and pg_am_size() without
shortcuts in
psql. That would avoid showing a potentially huge ACL when all one wants
is
the schema size, and would serve my purposes well enough to write
| SELECT pg_namespace_size(oid), nspname FROM pg_namespace ORDER BY 1 DESC
LIMIT 9;
It can work too.
I think the long ACL is a customer design issue, but can be. But the same
problem is in \dt+, and I don't see an objection against this design.
Maybe I am too subjective, because 4 years I use pspg, and wide reports are
not a problem for me. When the size is on the end, then it is easy to see
it in pspg.
I like to see size in \dn+ report, and I like to use pg_namespace_size
separately too. Both can be very practical functionality.
I think so \dt+ and \l+ is working very well now, and I am not too happy to
break it (partially break it). Although the proposed change is very
minimalistic.
But your example "SELECT pg_namespace_size(oid), nspname FROM pg_namespace
ORDER BY 1 DESC LIMIT 9" navigates me to the second idea (that just
enhances the previous). Can be nice if you can have prepared views on the
server side that are +/- equivalent to psql reports, and anybody can simply
write their own custom reports.
some like
SELECT schema, tablename, owner, pg_size_pretty(size) FROM
pg_description.tables ORDER BY size DESC LIMIT 10
SELECT schema, owner, pg_size_pretty(size) FROM pg_description.schemas
ORDER BY size DESC LIMIT 10
In the future, it can simplify psql code, and it allows pretty nice
customization in any client for a lot of purposes.
Regards
Pavel
Show quoted text
--
Justin
Remove bogus ACL check for AMs.
Rebased on cf0cab868.
Use ForkNumber rather than int.
Update comments and commit message.
Also move the Size column of \l and \dt
Attachments:
v4-0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From a1d33780e4c61a7bdb64ee6ab5c248e1175a3efd Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH v4 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 130 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 149 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index d5a7fb13f3..908432ba28 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,23 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
@@ -832,6 +837,131 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 4d992dc224..ff08b2ac01 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7230,6 +7230,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.0
v4-0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From d736a7ba55eeebe797f6811413bfc47545fb61e4 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH v4 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with ++ in \dn, \dA, \db and (for consistency) \l
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 30 ++++++++++++++++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index ccd7b48108..c9b0a01f9d 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -362,7 +362,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -707,6 +708,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -714,7 +716,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -739,7 +744,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -766,7 +771,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
success = listConversions(pattern, show_verbose, show_system);
@@ -813,7 +818,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1856,14 +1861,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
if (pattern)
free(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index c28788e84f..c818e657da 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -128,12 +128,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -165,6 +165,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -198,7 +203,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -218,12 +223,16 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -877,7 +886,7 @@ describeOperators(const char *oper_pattern,
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -898,7 +907,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -4657,7 +4666,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4679,6 +4688,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 71b320f1fc..edeea38580 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -83,7 +83,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.0
v4-0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From ec7b0104a4d32e231e1fe6be24b6d53c32247337 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH v4 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 74 +++++++++----------
src/bin/psql/describe.c | 159 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 54 +++++++-------
3 files changed, 143 insertions(+), 144 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index c9b0a01f9d..5654495192 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -709,8 +709,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -719,7 +718,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -728,10 +726,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -747,16 +745,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -768,16 +766,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
break;
case 'c':
- success = listConversions(pattern, show_verbose, show_system);
+ success = listConversions(pattern, verbose, show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -786,7 +784,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -800,7 +798,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -809,23 +807,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
success = do_lo_list();
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -848,7 +846,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -856,7 +854,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -878,36 +876,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -918,16 +916,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -935,7 +933,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -944,7 +942,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -966,7 +964,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -989,11 +987,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index c818e657da..710bf8ef91 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -62,7 +62,7 @@ static bool listOneExtensionContents(const char *extname, const char *oid);
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -158,7 +158,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -219,7 +219,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -278,7 +278,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -363,7 +363,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -423,7 +423,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -601,7 +601,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -614,7 +614,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -754,7 +754,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -790,7 +790,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -920,7 +920,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1359,10 +1359,10 @@ objectDescription(const char *pattern, bool showSystem)
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1443,7 +1443,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1815,7 +1815,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2073,7 +2073,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2096,7 +2096,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3267,7 +3267,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3317,7 +3317,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3341,7 +3341,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3349,7 +3349,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3357,7 +3357,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3459,7 +3459,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3485,11 +3485,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3521,7 +3522,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3580,7 +3581,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3683,7 +3684,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3742,7 +3743,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -3877,7 +3878,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -3952,7 +3953,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -3987,7 +3988,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4073,7 +4074,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4089,7 +4090,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4143,7 +4144,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4170,7 +4171,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4183,7 +4184,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4222,7 +4223,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4246,7 +4247,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4256,7 +4257,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4298,7 +4299,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4339,7 +4340,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4466,7 +4467,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4507,7 +4508,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4528,7 +4529,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4577,7 +4578,7 @@ listCasts(const char *pattern, bool verbose)
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4616,7 +4617,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -4681,7 +4682,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -4793,13 +4794,13 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5030,7 +5031,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5045,7 +5046,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5091,7 +5092,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5099,7 +5100,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5152,13 +5153,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5348,7 +5349,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5365,7 +5366,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5383,7 +5384,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5415,7 +5416,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5430,7 +5431,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5455,7 +5456,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5487,7 +5488,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5500,7 +5501,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5538,7 +5539,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5553,7 +5554,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5573,7 +5574,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6029,7 +6030,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6059,7 +6060,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6135,7 +6136,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6170,7 +6171,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6186,7 +6187,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6229,7 +6230,7 @@ listOperatorClasses(const char *access_method_pattern,
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6254,7 +6255,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6311,7 +6312,7 @@ listOperatorFamilies(const char *access_method_pattern,
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6344,7 +6345,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6353,7 +6354,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6398,7 +6399,7 @@ listOpFamilyOperators(const char *access_method_pattern,
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6425,7 +6426,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index edeea38580..cdf286242b 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,58 +47,58 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -110,7 +110,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -119,25 +119,25 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
#endif /* DESCRIBE_H */
--
2.17.0
v4-0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 9fad0b322f7e6e60b8b0dbad68d8bc34a470da01 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH v4 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, \d and \dP+
It doesn't make much sense that one cannot show a database's default tablespace
without also showing its size, and stat()ing every segment of every relation
in the DB.
---
src/bin/psql/describe.c | 42 ++++++++++++++---------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 710bf8ef91..42bad9281e 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -224,11 +224,6 @@ describeTablespaces(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
@@ -236,6 +231,11 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Description"));
}
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -907,17 +907,22 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
+
+ if (verbose > 0)
appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " 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\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3772,10 +3777,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -3954,6 +3962,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -3970,9 +3983,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 930ce8597a..9a521a80b3 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2845,47 +2845,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.17.0
Rebased before Julian asks.
Attachments:
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From cece72e72b35110f222228e8f71397e4fc72469a Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 80 ++++++++++----------
src/bin/psql/describe.c | 163 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 56 +++++++-------
3 files changed, 149 insertions(+), 150 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index cfae8fd6d12..2326f4c5d98 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -720,8 +720,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -730,7 +729,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -739,10 +737,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -758,16 +756,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -779,16 +777,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
break;
case 'c':
- success = listConversions(pattern, show_verbose, show_system);
+ success = listConversions(pattern, verbose, show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -797,7 +795,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -811,7 +809,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -820,23 +818,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -850,7 +848,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -859,7 +857,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -867,7 +865,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -889,36 +887,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -929,16 +927,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -946,7 +944,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -955,7 +953,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -977,7 +975,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1000,11 +998,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -1976,9 +1974,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index de62822674e..ee7990ab7e4 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -62,7 +62,7 @@ static bool listOneExtensionContents(const char *extname, const char *oid);
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -158,7 +158,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -219,7 +219,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -278,7 +278,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -363,7 +363,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -423,7 +423,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -601,7 +601,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -614,7 +614,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -754,7 +754,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -790,7 +790,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -920,7 +920,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1359,10 +1359,10 @@ objectDescription(const char *pattern, bool showSystem)
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1443,7 +1443,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1815,7 +1815,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2073,7 +2073,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2096,7 +2096,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3275,7 +3275,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3325,7 +3325,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3349,7 +3349,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3357,7 +3357,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3365,7 +3365,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3467,7 +3467,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3493,11 +3493,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3529,7 +3530,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3588,7 +3589,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3691,7 +3692,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3750,7 +3751,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -3885,7 +3886,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -3960,7 +3961,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -3995,7 +3996,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4081,7 +4082,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4097,7 +4098,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4151,7 +4152,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4178,7 +4179,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4191,7 +4192,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4230,7 +4231,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4254,7 +4255,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4264,7 +4265,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4306,7 +4307,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4347,7 +4348,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4474,7 +4475,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4515,7 +4516,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4536,7 +4537,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4585,7 +4586,7 @@ listCasts(const char *pattern, bool verbose)
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4624,7 +4625,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -4689,7 +4690,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -4801,13 +4802,13 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5038,7 +5039,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5053,7 +5054,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5099,7 +5100,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5107,7 +5108,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5160,13 +5161,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5356,7 +5357,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5373,7 +5374,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5391,7 +5392,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5423,7 +5424,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5438,7 +5439,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5463,7 +5464,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5495,7 +5496,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5508,7 +5509,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5546,7 +5547,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5561,7 +5562,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5581,7 +5582,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6037,7 +6038,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6067,7 +6068,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6143,7 +6144,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6178,7 +6179,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6194,7 +6195,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6237,7 +6238,7 @@ listOperatorClasses(const char *access_method_pattern,
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6262,7 +6263,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6319,7 +6320,7 @@ listOperatorFamilies(const char *access_method_pattern,
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6352,7 +6353,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6361,7 +6362,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6406,7 +6407,7 @@ listOpFamilyOperators(const char *access_method_pattern,
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6433,7 +6434,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -6483,7 +6484,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6497,7 +6498,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 5a1b97805df..7795680f31c 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,58 +47,58 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -110,7 +110,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -119,27 +119,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.17.1
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From cf57143c85a2a6088fe6038e6d41771fd60aae34 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 130 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 149 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 3a2f2e1f99d..6cde01f0587 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,23 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
@@ -832,6 +837,131 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index d6bf1f3274b..18248799e73 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7230,6 +7230,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From 771086b0b1d6116309a831e1e122cdce05d7dd6b Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with ++ in \dn, \dA, \db and (for consistency) \l
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 30 ++++++++++++++++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index f5904748553..cfae8fd6d12 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -366,7 +366,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -718,6 +719,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -725,7 +727,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -750,7 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -777,7 +782,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
success = listConversions(pattern, show_verbose, show_system);
@@ -824,7 +829,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1904,14 +1909,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
if (pattern)
free(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 8587b19160d..de62822674e 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -128,12 +128,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -165,6 +165,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -198,7 +203,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -218,12 +223,16 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -877,7 +886,7 @@ describeOperators(const char *oper_pattern,
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -898,7 +907,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -4665,7 +4674,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4687,6 +4696,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 150000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index fd6079679c6..5a1b97805df 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -83,7 +83,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 25671fe1088283adce706ba5dace7323c6de7da9 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, \d and \dP+
It doesn't make much sense that one cannot show a database's default tablespace
without also showing its size, and stat()ing every segment of every relation
in the DB.
---
src/bin/psql/describe.c | 42 ++++++++++++++---------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index ee7990ab7e4..44ae6ca9a75 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -224,11 +224,6 @@ describeTablespaces(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
@@ -236,6 +231,11 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Description"));
}
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -907,17 +907,22 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Ctype"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
+
+ if (verbose > 0)
appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " 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\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3780,10 +3785,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -3962,6 +3970,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -3978,9 +3991,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 6428ebc507d..47166727318 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2857,47 +2857,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.17.1
Hi
I like this feature, but I don't like the introduction of double + too
much. I think it is confusing.
Is it really necessary? Cannot be enough just reorganization of \dn and
\dn+.
Regards
Pavel
pá 14. 1. 2022 v 17:35 odesílatel Justin Pryzby <pryzby@telsasoft.com>
napsal:
Show quoted text
Rebased before Julian asks.
Rebased
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 4d88986706e334e2dccc6f576139342c102033f8 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 130 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 149 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index b4a2c8d2197..a1348083ba3 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,23 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenodemap.h"
@@ -832,6 +837,131 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&rel->rd_node, rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 87aa571a331..7507193f85d 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7281,6 +7281,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From c8db22278993a2456563df0a6f30c6dadbf6f059 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with ++ in \dn, \dA, \db and (for consistency) \l
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 30 ++++++++++++++++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index b51d28780b1..cb65283547c 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -366,7 +366,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -718,6 +719,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -725,7 +727,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -750,7 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -777,7 +782,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -831,7 +836,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1911,14 +1916,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
if (pattern)
free(pattern);
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 1a5d924a23f..67163e834bc 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -136,12 +136,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -173,6 +173,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -208,7 +213,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -228,12 +233,16 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -899,7 +908,7 @@ describeOperators(const char *oper_pattern,
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -932,7 +941,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -4881,7 +4890,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4903,6 +4912,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 7872c71f58d..4d889c71368 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -87,7 +87,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.1
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 8e35b070f37fec54445d40c0b152aef111ba3931 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 165 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 152 insertions(+), 153 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index cb65283547c..592b0bb09ca 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -720,8 +720,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -730,7 +729,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -739,10 +737,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -758,16 +756,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -779,7 +777,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -787,15 +785,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -804,7 +802,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -818,7 +816,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -827,23 +825,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -857,7 +855,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -866,7 +864,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -874,7 +872,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -896,36 +894,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -936,16 +934,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -953,7 +951,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -962,7 +960,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -984,7 +982,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1007,11 +1005,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -1983,9 +1981,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 67163e834bc..220262aa84c 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -166,7 +166,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -229,7 +229,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -290,7 +290,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -375,7 +375,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -435,7 +435,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -617,7 +617,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -630,7 +630,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -772,7 +772,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -808,7 +808,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -954,7 +954,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1411,10 +1411,10 @@ objectDescription(const char *pattern, bool showSystem)
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1497,7 +1497,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1871,7 +1871,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2129,7 +2129,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2152,7 +2152,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3388,7 +3388,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3438,7 +3438,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3462,7 +3462,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3470,7 +3470,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3478,7 +3478,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3580,7 +3580,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3606,11 +3606,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3644,7 +3645,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3703,7 +3704,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3809,7 +3810,7 @@ listDbRoleSettings(const char *pattern, const char *pattern2)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3868,7 +3869,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4005,7 +4006,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4080,7 +4081,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4115,7 +4116,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4203,7 +4204,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4219,7 +4220,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4275,7 +4276,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4302,7 +4303,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4315,7 +4316,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4356,7 +4357,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4380,7 +4381,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4390,7 +4391,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4434,7 +4435,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4503,7 +4504,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4544,7 +4545,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4675,7 +4676,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4716,7 +4717,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4737,7 +4738,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4790,7 +4791,7 @@ listCasts(const char *pattern, bool verbose)
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4838,7 +4839,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -4905,7 +4906,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5019,13 +5020,13 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5260,7 +5261,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5275,7 +5276,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5323,7 +5324,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5331,7 +5332,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5386,13 +5387,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5586,7 +5587,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5603,7 +5604,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5621,7 +5622,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5655,7 +5656,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5670,7 +5671,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5695,7 +5696,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5729,7 +5730,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5742,7 +5743,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5782,7 +5783,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5797,7 +5798,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5817,7 +5818,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6362,7 +6363,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6392,7 +6393,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6478,7 +6479,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6513,7 +6514,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6529,7 +6530,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6576,7 +6577,7 @@ listOperatorClasses(const char *access_method_pattern,
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6601,7 +6602,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6662,7 +6663,7 @@ listOperatorFamilies(const char *access_method_pattern,
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6695,7 +6696,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6704,7 +6705,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6753,7 +6754,7 @@ listOpFamilyOperators(const char *access_method_pattern,
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6780,7 +6781,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -6834,7 +6835,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6848,7 +6849,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 4d889c71368..7d0b4a258e2 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,62 +47,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -114,7 +114,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -123,27 +123,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.17.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 5b09d2d3d97d840af3718e6005f1f2a65648b93d Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, \d and \dP+
It doesn't make much sense that one cannot show a database's default tablespace
without also showing its size, and stat()ing every segment of every relation
in the DB.
---
src/bin/psql/describe.c | 42 ++++++++++++++---------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 220262aa84c..9f73e90df23 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -234,11 +234,6 @@ describeTablespaces(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
@@ -246,6 +241,11 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Description"));
}
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -941,17 +941,22 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
+
+ if (verbose > 0)
appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " 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\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3898,10 +3903,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4082,6 +4090,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4098,9 +4111,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 60acbd1241e..8da23d7216c 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2857,47 +2857,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.17.1
rebased
Attachments:
v8-0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 1e560284832c157ca18a43f44b090e5b35b0cfb3 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH v8 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 130 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 149 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 34efa121b40..85a3dd4b7ab 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,23 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -832,6 +837,131 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = pg_namespace_aclcheck(nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index be47583122b..6c29b9f9d5f 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7289,6 +7289,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.17.1
v8-0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From 6ccdd7f2c1b9e7302d7121055855b3d16c33eabc Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH v8 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with ++ in \dn, \dA, \db and (for consistency) \l
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 30 ++++++++++++++++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index a81bd3307b4..99ee47f436a 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -366,7 +366,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -717,6 +718,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -724,7 +726,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -749,7 +754,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -775,7 +780,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -829,7 +834,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1904,14 +1909,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 327a69487bb..677dd64cda0 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -139,12 +139,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -176,6 +176,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -214,7 +219,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -234,12 +239,16 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -919,7 +928,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -952,7 +961,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -4949,7 +4958,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4971,6 +4980,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 7872c71f58d..4d889c71368 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -87,7 +87,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.17.1
v8-0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From aeea61db0844b6742bd95949d2f05bcea342458e Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH v8 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 165 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 152 insertions(+), 153 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 99ee47f436a..9f3910cd332 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -75,7 +75,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -719,8 +719,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -729,7 +728,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -738,10 +736,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -757,16 +755,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -777,7 +775,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -785,15 +783,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -802,7 +800,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -816,7 +814,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -825,23 +823,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -855,7 +853,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -864,7 +862,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -872,7 +870,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -893,36 +891,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -933,16 +931,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -950,7 +948,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -959,7 +957,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -980,7 +978,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1003,11 +1001,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -1975,9 +1973,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 677dd64cda0..2e47ea448f7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -169,7 +169,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -235,7 +235,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -299,7 +299,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -384,7 +384,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -444,7 +444,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -630,7 +630,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -643,7 +643,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -788,7 +788,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -824,7 +824,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -974,7 +974,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1442,10 +1442,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1531,7 +1531,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1904,7 +1904,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2162,7 +2162,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2185,7 +2185,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3421,7 +3421,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3471,7 +3471,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3495,7 +3495,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3503,7 +3503,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3511,7 +3511,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3611,7 +3611,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3637,11 +3637,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3678,7 +3679,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3737,7 +3738,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3847,7 +3848,7 @@ error_return:
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3906,7 +3907,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4046,7 +4047,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4121,7 +4122,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4156,7 +4157,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4247,7 +4248,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4263,7 +4264,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4324,7 +4325,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4351,7 +4352,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4364,7 +4365,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4408,7 +4409,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4432,7 +4433,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4442,7 +4443,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4489,7 +4490,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4558,7 +4559,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4599,7 +4600,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4736,7 +4737,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4777,7 +4778,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4798,7 +4799,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4855,7 +4856,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4903,7 +4904,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -4973,7 +4974,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5085,13 +5086,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5335,7 +5336,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5350,7 +5351,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5401,7 +5402,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5409,7 +5410,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5467,13 +5468,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5673,7 +5674,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5690,7 +5691,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5708,7 +5709,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5745,7 +5746,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5760,7 +5761,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5785,7 +5786,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5822,7 +5823,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5835,7 +5836,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5878,7 +5879,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5893,7 +5894,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5913,7 +5914,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6477,7 +6478,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6507,7 +6508,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6601,7 +6602,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6636,7 +6637,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6652,7 +6653,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6703,7 +6704,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6728,7 +6729,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6793,7 +6794,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6826,7 +6827,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6835,7 +6836,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6892,7 +6893,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6919,7 +6920,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -6981,7 +6982,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6995,7 +6996,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 4d889c71368..7d0b4a258e2 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,62 +47,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -114,7 +114,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -123,27 +123,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *opclass_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *accessMethod_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.17.1
v8-0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 58b3d5a2b4be561707ed85fd86a156b26239cf03 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH v8 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, \d and \dP+
It doesn't make much sense that one cannot show a database's default tablespace
without also showing its size, and stat()ing every segment of every relation
in the DB.
---
src/bin/psql/describe.c | 42 ++++++++++++++---------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 2e47ea448f7..22fc19a47dd 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -240,11 +240,6 @@ describeTablespaces(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
@@ -252,6 +247,11 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Description"));
}
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -961,17 +961,22 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
+
+ if (verbose > 0)
appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " 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\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3936,10 +3941,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4123,6 +4131,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4139,9 +4152,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index a7f5700edc1..2daa4685b4b 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2858,47 +2858,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.17.1
As discussed in [1]/messages/by-id/86140760-8ba5-6f3a-3e6e-5ca6c060bd24@timescale.com, we're taking this opportunity to return some
patchsets that don't appear to be getting enough reviewer interest.
This is not a rejection, since we don't necessarily think there's
anything unacceptable about the entry, but it differs from a standard
"Returned with Feedback" in that there's probably not much actionable
feedback at all. Rather than code changes, what this patch needs is more
community interest. You might
- ask people for help with your approach,
- see if there are similar patches that your code could supplement,
- get interested parties to agree to review your patch in a CF, or
- possibly present the functionality in a way that's easier to review
overall.
(Doing these things is no guarantee that there will be interest, but
it's hopefully better than endlessly rebasing a patchset that is not
receiving any feedback from the community.)
Once you think you've built up some community support and the patchset
is ready for review, you (or any interested party) can resurrect the
patch entry by visiting
https://commitfest.postgresql.org/38/3256/
and changing the status to "Needs Review", and then changing the
status again to "Move to next CF". (Don't forget the second step;
hopefully we will have streamlined this in the near future!)
Thanks,
--Jacob
[1]: /messages/by-id/86140760-8ba5-6f3a-3e6e-5ca6c060bd24@timescale.com
Rebased on c727f511b.
This patch record was "closed for lack of interest", but I think what's
actually needed is committer review of which approach to take.
- add backend functions but do not modify psql ?
- add to psql slash-plus commnds ?
- introduce psql double-plus commands for new options ?
- change pre-existing psql plus commands to only show size with
double-plus ?
- go back to the original, two-line client-side sum() ?
Until then, the patchset is organized with those questions in mind.
--
Justin
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 84316b06d1a6286d30e163c4815c840548d639db Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 131 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 150 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 141db7c9c1c..2e7e98f5676 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,19 +13,25 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -833,6 +839,131 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(int attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Relation rel;
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid nspOid = PG_GETARG_OID(0);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Oid amOid = PG_GETARG_OID(0);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ int64 size;
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 719599649a9..cd4342c864f 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7331,6 +7331,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.25.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From fe3ff020b26a6b75dd27ca18e64ec77f5034816a Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with ++ in \dn, \dA, \db and (for consistency) \l
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 22 ++++++++++++++--------
src/bin/psql/describe.c | 30 ++++++++++++++++++++++--------
src/bin/psql/describe.h | 8 ++++----
3 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index de6a3a71f8a..40956cc32dc 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -368,7 +368,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
- strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
+ strcmp(cmd, "l+") == 0 || strcmp(cmd, "l++") == 0 ||
+ strcmp(cmd, "list+") == 0 || strcmp(cmd, "list++") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
status = exec_command_lo(scan_state, active_branch, cmd);
@@ -753,6 +754,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -760,7 +762,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -785,7 +790,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -811,7 +816,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -865,7 +870,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1942,14 +1947,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index df166365e81..57666d8c5b8 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -139,12 +139,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -176,6 +176,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -214,7 +219,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -234,12 +239,16 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -919,7 +928,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -952,7 +961,7 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
@@ -4954,7 +4963,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4976,6 +4985,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index bd051e09cbb..84df35f4623 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -87,7 +87,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.25.1
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 512ee3cc9773d7e945f1973f094806a4340276fa Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 165 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 152 insertions(+), 153 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 40956cc32dc..e73ad7cc3b5 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -76,7 +76,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -755,8 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -765,7 +764,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -774,10 +772,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -793,16 +791,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -813,7 +811,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -821,15 +819,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -838,7 +836,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -852,7 +850,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -861,23 +859,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern);
@@ -891,7 +889,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -900,7 +898,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -908,7 +906,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -929,36 +927,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -969,16 +967,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -986,7 +984,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -995,7 +993,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -1016,7 +1014,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1039,11 +1037,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -2013,9 +2011,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 57666d8c5b8..f7b646062bd 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -169,7 +169,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -235,7 +235,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -299,7 +299,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -384,7 +384,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -444,7 +444,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -630,7 +630,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -643,7 +643,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -788,7 +788,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -824,7 +824,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -974,7 +974,7 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Description"));
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -1442,10 +1442,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1531,7 +1531,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1904,7 +1904,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2162,7 +2162,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2185,7 +2185,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3421,7 +3421,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3473,7 +3473,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3497,7 +3497,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3505,7 +3505,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3513,7 +3513,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3613,7 +3613,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3639,11 +3639,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3680,7 +3681,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3739,7 +3740,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3852,7 +3853,7 @@ error_return:
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3911,7 +3912,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4051,7 +4052,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4126,7 +4127,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4161,7 +4162,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4252,7 +4253,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4268,7 +4269,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4329,7 +4330,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4356,7 +4357,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4369,7 +4370,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4413,7 +4414,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4437,7 +4438,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4447,7 +4448,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4494,7 +4495,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4563,7 +4564,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4604,7 +4605,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4741,7 +4742,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4782,7 +4783,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4803,7 +4804,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4860,7 +4861,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4908,7 +4909,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -4978,7 +4979,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5090,13 +5091,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5340,7 +5341,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5355,7 +5356,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5406,7 +5407,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5414,7 +5415,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5472,13 +5473,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5678,7 +5679,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5695,7 +5696,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5713,7 +5714,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5750,7 +5751,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5765,7 +5766,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5790,7 +5791,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5827,7 +5828,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5840,7 +5841,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5883,7 +5884,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5898,7 +5899,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5918,7 +5919,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6482,7 +6483,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6512,7 +6513,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6606,7 +6607,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6641,7 +6642,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6657,7 +6658,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6708,7 +6709,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6733,7 +6734,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6798,7 +6799,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6831,7 +6832,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6840,7 +6841,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6897,7 +6898,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6924,7 +6925,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -6986,7 +6987,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7000,7 +7001,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 84df35f4623..7edf30118fd 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,62 +47,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -114,7 +114,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -123,27 +123,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.25.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From c9011ebee742378788b393270773193c02358b74 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, \d and \dP+
It doesn't make much sense that one cannot show a database's default tablespace
without also showing its size, and stat()ing every segment of every relation
in the DB.
---
src/bin/psql/describe.c | 42 ++++++++++++++---------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 53 insertions(+), 43 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index f7b646062bd..77a883815fe 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -240,11 +240,6 @@ describeTablespaces(const char *pattern, int verbose)
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
- gettext_noop("Size"));
-
appendPQExpBuffer(&buf,
",\n spcoptions AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
@@ -252,6 +247,11 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Description"));
}
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_tablespace\n");
@@ -961,17 +961,22 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Locale Provider"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
+
+ if (verbose > 0)
appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " 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\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3941,10 +3946,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4128,6 +4136,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4144,9 +4157,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 8fc62cebd2d..cd95680994b 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2889,47 +2889,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.25.1
čt 15. 12. 2022 v 17:13 odesílatel Justin Pryzby <pryzby@telsasoft.com>
napsal:
Rebased on c727f511b.
This patch record was "closed for lack of interest", but I think what's
actually needed is committer review of which approach to take.- add backend functions but do not modify psql ?
- add to psql slash-plus commnds ?
- introduce psql double-plus commands for new options ?
- change pre-existing psql plus commands to only show size with
double-plus ?
- go back to the original, two-line client-side sum() ?Until then, the patchset is organized with those questions in mind.
+1
This format makes sense to me.
Regards
Pavel
Show quoted text
--
Justin
On Thu, Dec 15, 2022 at 10:13:23AM -0600, Justin Pryzby wrote:
Rebased on c727f511b.
Rebased on 30a53b792.
With minor changes including fixes to an intermediate patch.
Show quoted text
This patch record was "closed for lack of interest", but I think what's
actually needed is committer review of which approach to take.- add backend functions but do not modify psql ?
- add to psql slash-plus commnds ?
- introduce psql double-plus commands for new options ?
- change pre-existing psql plus commands to only show size with
double-plus ?
- go back to the original, two-line client-side sum() ?Until then, the patchset is organized with those questions in mind.
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From cf1596faa449ff1bd1d8b56306118d5eac764291 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
src/backend/utils/adt/dbsize.c | 132 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
2 files changed, 151 insertions(+)
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index e5c0f1c45b6..af0955d1790 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,19 +13,25 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -858,6 +864,132 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(AttrNumber attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+ Relation rel;
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid nspOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid amOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 1351d4be67c..ae658e721fd 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7389,6 +7389,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.34.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From a9b9a3736403521ad3c1bd5dd4c8fefefd630917 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with \dA++ and \dn++ (for which the single-plus
commands have historically not done any slow operations).
Also change to show the size only with \db++ and \l++ (for which it's
useful to show the ACL without also doing any slow operations).
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose.
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 20 +++++++++++-------
src/bin/psql/describe.c | 46 +++++++++++++++++++++++++++++------------
src/bin/psql/describe.h | 8 +++----
3 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 955397ee9dc..875b659a26d 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -369,6 +369,7 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
+ strcmp(cmd, "l++") == 0 || strcmp(cmd, "list++") == 0 ||
strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
@@ -754,6 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -761,7 +763,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -786,7 +791,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -812,7 +817,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -866,7 +871,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1943,14 +1948,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 99e28f607e8..7de604a894d 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -139,12 +139,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -176,6 +176,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -214,7 +219,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -234,12 +239,18 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ appendPQExpBuffer(&buf,
+ ",\n spcoptions AS \"%s\"",
+ gettext_noop("Options"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -914,7 +925,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -961,20 +972,24 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
" ELSE 'No Access'\n"
- " END as \"%s\""
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
+ if (verbose > 0)
+ appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\""
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -4973,7 +4988,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4995,6 +5010,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 160000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 554fe867255..d2fd8a72a36 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -87,7 +87,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.34.1
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 853c193c880a5a58b799d16e76c02d209321614e Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 163 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 151 insertions(+), 152 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 875b659a26d..7024db26a86 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -76,7 +76,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -756,8 +756,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -766,7 +765,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -775,10 +773,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -794,16 +792,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -814,7 +812,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -822,15 +820,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -853,7 +851,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -862,23 +860,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern, show_system);
@@ -892,7 +890,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -901,7 +899,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -909,7 +907,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -930,36 +928,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -970,16 +968,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -987,7 +985,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -996,7 +994,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -1017,7 +1015,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1040,11 +1038,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -2014,9 +2012,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 7de604a894d..5fc4f5774e8 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -169,7 +169,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -235,7 +235,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -301,7 +301,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -386,7 +386,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -441,7 +441,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -627,7 +627,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -640,7 +640,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -785,7 +785,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -821,7 +821,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1455,10 +1455,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1544,7 +1544,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1917,7 +1917,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2175,7 +2175,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2198,7 +2198,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3434,7 +3434,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3486,7 +3486,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3510,7 +3510,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3518,7 +3518,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3526,7 +3526,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3626,7 +3626,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3652,11 +3652,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3693,7 +3694,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3752,7 +3753,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3865,7 +3866,7 @@ error_return:
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3924,7 +3925,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4064,7 +4065,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4139,7 +4140,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4174,7 +4175,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4265,7 +4266,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4281,7 +4282,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4342,7 +4343,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4369,7 +4370,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4382,7 +4383,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4426,7 +4427,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4450,7 +4451,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4460,7 +4461,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4507,7 +4508,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4576,7 +4577,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4617,7 +4618,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4754,7 +4755,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4795,7 +4796,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4816,7 +4817,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4873,7 +4874,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4933,7 +4934,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5003,7 +5004,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5115,13 +5116,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5365,7 +5366,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5380,7 +5381,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5431,7 +5432,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5439,7 +5440,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5497,13 +5498,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5703,7 +5704,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5720,7 +5721,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5738,7 +5739,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5775,7 +5776,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5790,7 +5791,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5815,7 +5816,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5852,7 +5853,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5865,7 +5866,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5908,7 +5909,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5923,7 +5924,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5943,7 +5944,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6507,7 +6508,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6537,7 +6538,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6644,7 +6645,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6679,7 +6680,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6695,7 +6696,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6746,7 +6747,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6771,7 +6772,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6836,7 +6837,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6869,7 +6870,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6878,7 +6879,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6935,7 +6936,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6962,7 +6963,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -7024,7 +7025,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7038,7 +7039,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index d2fd8a72a36..23d601fbc97 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,62 +47,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -114,7 +114,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -123,27 +123,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.34.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 767df8a196a515708cdc5b017db10f2118566613 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, and (for consistency) \d and \dP+
It doesn't make much sense that one cannot show a database's default
tablespace without also showing its size, and stat()ing every segment of
every relation in the DB.
---
src/bin/psql/describe.c | 40 ++++++++++++----------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 5fc4f5774e8..a64e4ccba4d 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -241,17 +241,15 @@ describeTablespaces(const char *pattern, int verbose)
printACLColumn(&buf, "spcacl");
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\"",
- gettext_noop("Options"));
+ ",\n spcoptions AS \"%s\""
+ ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
+ gettext_noop("Options"),
+ gettext_noop("Description"));
if (verbose > 1)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
-
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
@@ -972,13 +970,6 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
if (verbose > 0)
appendPQExpBuffer(&buf,
@@ -987,6 +978,14 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Tablespace"),
gettext_noop("Description"));
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3954,10 +3953,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4141,6 +4143,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4157,9 +4164,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index c00e28361c7..b9c95502a45 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2889,47 +2889,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.34.1
I added documentation for the SQL functions in 001.
And updated to say 170000
I'm planning to set this patch as ready - it has not changed
significantly in 18 months. Not for the first time, I've implemented a
workaround at a higher layer.
--
Justin
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 917e5e36d14018b6de457ba9eafe8936c0e88c3c Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
doc/src/sgml/func.sgml | 39 ++++++++++
src/backend/utils/adt/dbsize.c | 132 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
3 files changed, 190 insertions(+)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 5a47ce43434..6cbf4e9aa56 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -27762,6 +27762,45 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
</para></entry>
</row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_namespace_size</primary>
+ </indexterm>
+ <function>pg_namespace_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_namespace_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations in the namespace (schema)
+ with the specified name or OID. To use this function, you must
+ have <literal>CREATE</literal> privilege on the specified namespace
+ or have privileges of the <literal>pg_read_all_stats</literal> role,
+ unless it is the default namespace for the current database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_am_size</primary>
+ </indexterm>
+ <function>pg_am_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_am_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations using the access method
+ with the specified name or OID.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index e5c0f1c45b6..af0955d1790 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,19 +13,25 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -858,6 +864,132 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(AttrNumber attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+ Relation rel;
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid nspOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid amOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989a..a14a4ac53d5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7411,6 +7411,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.34.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From c01392a36a0dcc774ccc816ff67f125c4c28b356 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with \dA++ and \dn++ (for which the single-plus
commands have historically not done any slow operations).
Also change to show the size only with \db++ and \l++ (for which it's
useful to show the ACL without also doing any slow operations).
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose (??)
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 20 +++++++++++-------
src/bin/psql/describe.c | 46 +++++++++++++++++++++++++++++------------
src/bin/psql/describe.h | 8 +++----
3 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 511debbe814..b695e09017d 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -369,6 +369,7 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
+ strcmp(cmd, "l++") == 0 || strcmp(cmd, "list++") == 0 ||
strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
@@ -754,6 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -761,7 +763,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -786,7 +791,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -812,7 +817,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -866,7 +871,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1943,14 +1948,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 9325a46b8fd..f7f737e8b59 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -139,12 +139,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -176,6 +176,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -214,7 +219,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -234,12 +239,18 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ appendPQExpBuffer(&buf,
+ ",\n spcoptions AS \"%s\"",
+ gettext_noop("Options"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -914,7 +925,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -961,20 +972,24 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
" ELSE 'No Access'\n"
- " END as \"%s\""
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
+ if (verbose > 0)
+ appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\""
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -4970,7 +4985,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4992,6 +5007,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 554fe867255..d2fd8a72a36 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -62,7 +62,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -87,7 +87,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.34.1
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From 902e0d29e272d68586bc616fae2db2fe3df39e39 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 163 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 151 insertions(+), 152 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index b695e09017d..5f4cde03250 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -76,7 +76,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -756,8 +756,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -766,7 +765,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -775,10 +773,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -794,16 +792,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -814,7 +812,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -822,15 +820,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -853,7 +851,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -862,23 +860,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern, show_system);
@@ -892,7 +890,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -901,7 +899,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -909,7 +907,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -930,36 +928,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -970,16 +968,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -987,7 +985,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -996,7 +994,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -1017,7 +1015,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1040,11 +1038,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -2014,9 +2012,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index f7f737e8b59..8ab4b4cb46a 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -169,7 +169,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -235,7 +235,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -301,7 +301,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -386,7 +386,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -441,7 +441,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -627,7 +627,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -640,7 +640,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -785,7 +785,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -821,7 +821,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1455,10 +1455,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1544,7 +1544,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1917,7 +1917,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2175,7 +2175,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2198,7 +2198,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3434,7 +3434,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3486,7 +3486,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3510,7 +3510,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3518,7 +3518,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3526,7 +3526,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3626,7 +3626,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3652,11 +3652,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
" WHERE m.member = r.oid) as memberof");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3693,7 +3694,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
/* ignores implicit memberships from superuser & pg_database_owner */
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3752,7 +3753,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
}
termPQExpBuffer(&buf);
@@ -3862,7 +3863,7 @@ error_return:
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3921,7 +3922,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4061,7 +4062,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4136,7 +4137,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4171,7 +4172,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4262,7 +4263,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4278,7 +4279,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4339,7 +4340,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4366,7 +4367,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4379,7 +4380,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4423,7 +4424,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4447,7 +4448,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4457,7 +4458,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4504,7 +4505,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4573,7 +4574,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4614,7 +4615,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4751,7 +4752,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4792,7 +4793,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4813,7 +4814,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4870,7 +4871,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4930,7 +4931,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5000,7 +5001,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5112,13 +5113,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5362,7 +5363,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5377,7 +5378,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5428,7 +5429,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5436,7 +5437,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5494,13 +5495,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5700,7 +5701,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5717,7 +5718,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5735,7 +5736,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5772,7 +5773,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5787,7 +5788,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5812,7 +5813,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5849,7 +5850,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5862,7 +5863,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5905,7 +5906,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5920,7 +5921,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5940,7 +5941,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6504,7 +6505,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6534,7 +6535,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6645,7 +6646,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6680,7 +6681,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6696,7 +6697,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6747,7 +6748,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6772,7 +6773,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6837,7 +6838,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6870,7 +6871,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6879,7 +6880,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6936,7 +6937,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6963,7 +6964,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -7025,7 +7026,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7039,7 +7040,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index d2fd8a72a36..23d601fbc97 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -47,62 +47,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -114,7 +114,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -123,27 +123,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.34.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 13c1dae0013665769c9c07839eac9fdccadfddad Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, and (for consistency) \d and \dP+
It doesn't make much sense that one cannot show a database's default
tablespace without also showing its size, and stat()ing every segment of
every relation in the DB.
---
src/bin/psql/describe.c | 40 ++++++++++++----------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 8ab4b4cb46a..1b7e5c5bcd2 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -241,17 +241,15 @@ describeTablespaces(const char *pattern, int verbose)
printACLColumn(&buf, "spcacl");
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\"",
- gettext_noop("Options"));
+ ",\n spcoptions AS \"%s\""
+ ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
+ gettext_noop("Options"),
+ gettext_noop("Description"));
if (verbose > 1)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
-
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
@@ -972,13 +970,6 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
if (verbose > 0)
appendPQExpBuffer(&buf,
@@ -987,6 +978,14 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Tablespace"),
gettext_noop("Description"));
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -3951,10 +3950,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4138,6 +4140,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4154,9 +4161,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 8f930283636..4666333f73f 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2889,47 +2889,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.34.1
On 24 May 2023, at 23:05, Justin Pryzby <pryzby@telsasoft.com> wrote:
I'm planning to set this patch as ready
This is marked RfC so I'm moving this to the next CF, but the patch no longer
applies so it needs a rebase.
--
Daniel Gustafsson
On Thu, Dec 15, 2022 at 10:13:23AM -0600, Justin Pryzby wrote:
This patch record was "closed for lack of interest", but I think what's
actually needed is committer review of which approach to take.
On Tue, Aug 01, 2023 at 09:54:34AM +0200, Daniel Gustafsson wrote:
On 24 May 2023, at 23:05, Justin Pryzby <pryzby@telsasoft.com> wrote:
I'm planning to set this patch as ready
This is marked RfC so I'm moving this to the next CF, but the patch no longer
applies so it needs a rebase.
I was still hoping to receive some feedback on which patches to squish.
--
Justin
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 2b97b0fe27199a343f00f31aaf3fcd79fd1228f1 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
doc/src/sgml/func.sgml | 39 ++++++++++
src/backend/utils/adt/dbsize.c | 132 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
3 files changed, 190 insertions(+)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index be2f54c9141..8a1c8226c48 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -27814,6 +27814,45 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
</para></entry>
</row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_namespace_size</primary>
+ </indexterm>
+ <function>pg_namespace_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_namespace_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations in the namespace (schema)
+ with the specified name or OID. To use this function, you must
+ have <literal>CREATE</literal> privilege on the specified namespace
+ or have privileges of the <literal>pg_read_all_stats</literal> role,
+ unless it is the default namespace for the current database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_am_size</primary>
+ </indexterm>
+ <function>pg_am_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_am_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations using the access method
+ with the specified name or OID.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index e5c0f1c45b6..af0955d1790 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,19 +13,25 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -858,6 +864,132 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(AttrNumber attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+ Relation rel;
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid nspOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid amOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6996073989a..a14a4ac53d5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7411,6 +7411,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.34.1
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From cb1f2efc9f5bf4a5f5249917e07e7c231bf9423c Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with \dA++ and \dn++ (for which the single-plus
commands have historically not done any slow operations).
Also change to show the size only with \db++ and \l++ (for which it's
useful to show the ACL without also doing any slow operations).
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose (??)
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 20 +++++++++++-------
src/bin/psql/describe.c | 46 +++++++++++++++++++++++++++++------------
src/bin/psql/describe.h | 8 +++----
3 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 1300869d797..667beb1b16e 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -369,6 +369,7 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
+ strcmp(cmd, "l++") == 0 || strcmp(cmd, "list++") == 0 ||
strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
@@ -754,6 +755,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -761,7 +763,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -786,7 +791,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -812,7 +817,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -866,7 +871,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1945,14 +1950,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 45f6a86b872..3be7a5b8dc8 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -139,12 +139,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -176,6 +176,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -214,7 +219,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -234,12 +239,18 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ appendPQExpBuffer(&buf,
+ ",\n spcoptions AS \"%s\"",
+ gettext_noop("Options"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -914,7 +925,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -961,20 +972,24 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
" ELSE 'No Access'\n"
- " END as \"%s\""
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
+ if (verbose > 0)
+ appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\""
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -5031,7 +5046,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -5053,6 +5068,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 24c0884a347..f11579a7bbc 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -65,7 +65,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -90,7 +90,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.34.1
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From b41f6a5613bb25b46eadbfc5b89ab0a129490697 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 163 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 151 insertions(+), 152 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 667beb1b16e..3039aaca699 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -76,7 +76,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -756,8 +756,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -766,7 +765,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -775,10 +773,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -794,16 +792,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -814,7 +812,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -822,15 +820,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -839,7 +837,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -853,7 +851,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -862,23 +860,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern, show_system);
@@ -892,7 +890,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -901,7 +899,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -909,7 +907,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -932,36 +930,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -972,16 +970,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -989,7 +987,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -998,7 +996,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -1019,7 +1017,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1042,11 +1040,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -2016,9 +2014,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 3be7a5b8dc8..7eff1249015 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -169,7 +169,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -235,7 +235,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -301,7 +301,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -386,7 +386,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -441,7 +441,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -627,7 +627,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -640,7 +640,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -785,7 +785,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -821,7 +821,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1455,10 +1455,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1544,7 +1544,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1917,7 +1917,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2175,7 +2175,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2198,7 +2198,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3434,7 +3434,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3486,7 +3486,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3510,7 +3510,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3518,7 +3518,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3526,7 +3526,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3626,7 +3626,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3648,11 +3648,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
" r.rolconnlimit, r.rolvaliduntil");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3687,7 +3688,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3744,7 +3745,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, attr[i], false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
}
termPQExpBuffer(&buf);
@@ -3923,7 +3924,7 @@ describeRoleGrants(const char *pattern, bool showSystem)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3982,7 +3983,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4122,7 +4123,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4197,7 +4198,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4232,7 +4233,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4323,7 +4324,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4339,7 +4340,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4400,7 +4401,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4427,7 +4428,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4440,7 +4441,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4484,7 +4485,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4508,7 +4509,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4518,7 +4519,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4565,7 +4566,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4634,7 +4635,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4675,7 +4676,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4812,7 +4813,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4853,7 +4854,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4874,7 +4875,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4931,7 +4932,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4991,7 +4992,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5061,7 +5062,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5173,13 +5174,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5423,7 +5424,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5438,7 +5439,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5489,7 +5490,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5497,7 +5498,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5555,13 +5556,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5761,7 +5762,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5778,7 +5779,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5796,7 +5797,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5833,7 +5834,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5848,7 +5849,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5873,7 +5874,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5910,7 +5911,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5923,7 +5924,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5966,7 +5967,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5981,7 +5982,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -6001,7 +6002,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6565,7 +6566,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6595,7 +6596,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6706,7 +6707,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6741,7 +6742,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6757,7 +6758,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6808,7 +6809,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6833,7 +6834,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6898,7 +6899,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6931,7 +6932,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6940,7 +6941,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6997,7 +6998,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7024,7 +7025,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -7086,7 +7087,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7100,7 +7101,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index f11579a7bbc..8776a20a6b6 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -50,62 +50,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -117,7 +117,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -126,27 +126,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.34.1
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From 372a74a3c89329cf9a3309ac6de242a7700f4dfa Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, and (for consistency) \d and \dP+
It doesn't make much sense that one cannot show a database's default
tablespace without also showing its size, and stat()ing every segment of
every relation in the DB.
---
src/bin/psql/describe.c | 40 ++++++++++++----------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 7eff1249015..cc5f00fffe7 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -241,17 +241,15 @@ describeTablespaces(const char *pattern, int verbose)
printACLColumn(&buf, "spcacl");
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\"",
- gettext_noop("Options"));
+ ",\n spcoptions AS \"%s\""
+ ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
+ gettext_noop("Options"),
+ gettext_noop("Description"));
if (verbose > 1)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
-
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
@@ -972,13 +970,6 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
if (verbose > 0)
appendPQExpBuffer(&buf,
@@ -987,6 +978,14 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Tablespace"),
gettext_noop("Description"));
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -4012,10 +4011,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4199,6 +4201,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4215,9 +4222,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 7cd0c27cca8..e623a2df7c9 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2900,47 +2900,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.34.1
2024-01 Commitfest.
Hi, This patch had a CF status of "Ready for Committer", but the
thread has been inactive for 5+ months.
Since the last post from Justin said "hoping to receive some feedback"
I have changed the CF status back to "Needs Review" [1]https://commitfest.postgresql.org/46/3256/.
======
[1]: https://commitfest.postgresql.org/46/3256/
Kind Regards,
Peter Smith.
Hi Justin,
Thanks for the patch and the work on it. In reviewing the basic
feature, I think this is something that has utility and is worthwhile
at the high level.
A few more specific notes:
The pg_namespace_size() function can stand on its own, and probably
has some utility for the released Postgres versions.
I do think the psql implementation for the \dn+ or \dA+ commands
shouldn't need to use this same function; it's a straightforward
expansion of the SQL query that can be run in a way that will be
backwards-compatible with any connected postgres version, so no reason
to exclude this information for this cases. (This may have been in an
earlier revision of the patchset; I didn't check everything.)
I think the \dX++ command versions add code complexity without a real
need for it. We have precedence with \l(+) to show permissions on the
basic display and size on the extended display, and I think this is
sufficient in this case here. While moving the permissions to \dn is
a behavior change, it's adding information, not taking it away, and as
an interactive command it is unlikely to introduce significant
breakage in any scripting scenario.
(In reviewing the patch we've also seen a bit of odd behavior/possible
bug with the existing extended + commands, which introducing
significant ++ overloading might be confusing, but not the
fault/concern of this patch.)
Quickie summary:
0001-Add-pg_am_size-pg_namespace_size.patch
- fine, but needs rebase to work
0002-psql-add-convenience-commands-dA-and-dn.patch
- split into just + variant; remove \l++
- make the \dn show permission and \dn+ show size
0003-f-convert-the-other-verbose-to-int-too.patch
- unneeded
0004-Move-the-double-plus-Size-columns-to-the-right.patch
- unneeded
Docs on the first patch seemed fine; I do think we'll need docs
changes for the psql changes.
Best,
David
On Thu, May 30, 2024 at 10:59:06AM -0700, David Christensen wrote:
Hi Justin,
Thanks for the patch and the work on it. In reviewing the basic
feature, I think this is something that has utility and is worthwhile
at the high level.
Thanks for looking.
A few more specific notes:
The pg_namespace_size() function can stand on its own, and probably
has some utility for the released Postgres versions.
Are you suggesting to add the C function retroactively in back branches?
I don't think anybody would consider doing that.
It wouldn't be used by anything internally, and any module that wanted
to use it would have to check the minor version, instead of just the
major version, which is wrong.
I do think the psql implementation for the \dn+ or \dA+ commands
shouldn't need to use this same function; it's a straightforward
expansion of the SQL query that can be run in a way that will be
backwards-compatible with any connected postgres version, so no reason
to exclude this information for this cases. (This may have been in an
earlier revision of the patchset; I didn't check everything.)
I think you're suggesting to write the query in SQL rather than in C.
But I did that in the first version of the patch, and the response was
that maybe in the future someone would want to add permission checks
that would compromize the ability to get correct results from SQL, so
then I presented the functionality writen in C.
I recommend that reviewers try to read the existing communication on the
thread, otherwise we end up going back and forth about the same things.
I think the \dX++ command versions add code complexity without a real
need for it.
If you view this as a way to "show schema sizes", then you're right,
there's no need. But I don't want this patch to necessary further
embrace the idea that it's okay for "plus commands to be slow and show
nonportable results". If there were a consensus that it'd be fine in a
plus command, I would be okay with that, though.
We have precedence with \l(+) to show permissions on the
basic display and size on the extended display, and I think this is
sufficient in this case here.
You also have the precedence that \db doesn't show the ACL, and you
can't get it without also computing the sizes. That's 1) inconsistent
with \l and 2) pretty inconvenient for someone who wants to show the
ACL (as mentioned in the first message on this thread).
0001-Add-pg_am_size-pg_namespace_size.patch
- fine, but needs rebase to work
I suggest reviewers to consider sending a rebased patch, optionally with
any proposed changes in a separate patch.
0002-psql-add-convenience-commands-dA-and-dn.patch
- split into just + variant; remove \l++
- make the \dn show permission and \dn+ show size
0003-f-convert-the-other-verbose-to-int-too.patch
- unneeded
0004-Move-the-double-plus-Size-columns-to-the-right.patch
- unneeded
You say they're unneeded, but what I've been hoping for is a committer
interested enough to at least suggest whether to run with 001, 001+002,
001+002+003, or 001+002+003+004. They're intentionally presented as
such.
I've also thought about submitting a patch specifically dedicated to
"moving size out of + and into ++". I find the idea compelling, for the
reasons I wrote in the the patch description. That'd be like presenting
003+004 first.
I'm opened to changing the behavior or the implementation. But changing
the patch as I've presented it based on one suggestion I think will lead
to incoherent code trashing. I need to hear a wider agreement.
--
Justin
Attachments:
0001-Add-pg_am_size-pg_namespace_size.patchtext/x-diff; charset=us-asciiDownload
From 713213bb75dd4b7c45eab9219422a3ab4339df25 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Tue, 13 Jul 2021 21:25:48 -0500
Subject: [PATCH 1/4] Add pg_am_size(), pg_namespace_size() ..
See also: 358a897fa, 528ac10c7
---
doc/src/sgml/func.sgml | 39 ++++++++++
src/backend/utils/adt/dbsize.c | 132 ++++++++++++++++++++++++++++++++
src/include/catalog/pg_proc.dat | 19 +++++
3 files changed, 190 insertions(+)
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 17c44bc3384..0515412ed30 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -29596,6 +29596,45 @@ postgres=# SELECT '0/0'::pg_lsn + pd.segment_number * ps.setting::int + :offset
</para></entry>
</row>
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_namespace_size</primary>
+ </indexterm>
+ <function>pg_namespace_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_namespace_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations in the namespace (schema)
+ with the specified name or OID. To use this function, you must
+ have <literal>CREATE</literal> privilege on the specified namespace
+ or have privileges of the <literal>pg_read_all_stats</literal> role,
+ unless it is the default namespace for the current database.
+ </para></entry>
+ </row>
+
+ <row>
+ <entry role="func_table_entry"><para role="func_signature">
+ <indexterm>
+ <primary>pg_am_size</primary>
+ </indexterm>
+ <function>pg_am_size</function> ( <type>name</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para role="func_signature">
+ <function>pg_am_size</function> ( <type>oid</type> )
+ <returnvalue>bigint</returnvalue>
+ </para>
+ <para>
+ Computes the total disk space used by relations using the access method
+ with the specified name or OID.
+ </para></entry>
+ </row>
+
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
diff --git a/src/backend/utils/adt/dbsize.c b/src/backend/utils/adt/dbsize.c
index 25d7110c130..90f9639051b 100644
--- a/src/backend/utils/adt/dbsize.c
+++ b/src/backend/utils/adt/dbsize.c
@@ -13,18 +13,24 @@
#include <sys/stat.h>
+#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
+#include "access/table.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_database.h"
+#include "catalog/pg_namespace.h"
#include "catalog/pg_tablespace.h"
#include "commands/dbcommands.h"
+#include "commands/defrem.h"
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "storage/fd.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/rel.h"
#include "utils/relfilenumbermap.h"
@@ -857,6 +863,132 @@ pg_size_bytes(PG_FUNCTION_ARGS)
PG_RETURN_INT64(result);
}
+/*
+ * Return the sum of size of relations for which the given attribute of
+ * pg_class matches the specified OID value.
+ */
+static int64
+calculate_size_attvalue(AttrNumber attnum, Oid attval)
+{
+ int64 totalsize = 0;
+ ScanKeyData skey;
+ Relation pg_class;
+ SysScanDesc scan;
+ HeapTuple tuple;
+
+ ScanKeyInit(&skey, attnum,
+ BTEqualStrategyNumber, F_OIDEQ, attval);
+
+ pg_class = table_open(RelationRelationId, AccessShareLock);
+ scan = systable_beginscan(pg_class, InvalidOid, false, NULL, 1, &skey);
+ while (HeapTupleIsValid(tuple = systable_getnext(scan)))
+ {
+ Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
+ Relation rel;
+
+ rel = try_relation_open(classtuple->oid, AccessShareLock);
+ if (!rel)
+ continue;
+
+ for (ForkNumber forkNum = 0; forkNum <= MAX_FORKNUM; forkNum++)
+ totalsize += calculate_relation_size(&(rel->rd_locator), rel->rd_backend, forkNum);
+
+ relation_close(rel, AccessShareLock);
+ }
+
+ systable_endscan(scan);
+ table_close(pg_class, AccessShareLock);
+ return totalsize;
+}
+
+/* Compute the size of relations in a schema (namespace) */
+static int64
+calculate_namespace_size(Oid nspOid)
+{
+ /*
+ * User must be a member of pg_read_all_stats or have CREATE privilege for
+ * target namespace.
+ */
+ if (!is_member_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS))
+ {
+ AclResult aclresult;
+
+ aclresult = object_aclcheck(NamespaceRelationId, nspOid, GetUserId(), ACL_CREATE);
+ if (aclresult != ACLCHECK_OK)
+ aclcheck_error(aclresult, OBJECT_SCHEMA,
+ get_namespace_name(nspOid));
+ }
+
+ return calculate_size_attvalue(Anum_pg_class_relnamespace, nspOid);
+}
+
+Datum
+pg_namespace_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid nspOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_namespace_size_name(PG_FUNCTION_ARGS)
+{
+ Name nspName = PG_GETARG_NAME(0);
+ Oid nspOid = get_namespace_oid(NameStr(*nspName), false);
+ int64 size;
+
+ size = calculate_namespace_size(nspOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+/* Compute the size of relations using the given access method */
+static int64
+calculate_am_size(Oid amOid)
+{
+ /* XXX acl_check? */
+
+ return calculate_size_attvalue(Anum_pg_class_relam, amOid);
+}
+
+Datum
+pg_am_size_oid(PG_FUNCTION_ARGS)
+{
+ Oid amOid = PG_GETARG_OID(0);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
+Datum
+pg_am_size_name(PG_FUNCTION_ARGS)
+{
+ Name amName = PG_GETARG_NAME(0);
+ Oid amOid = get_am_oid(NameStr(*amName), false);
+ int64 size;
+
+ size = calculate_am_size(amOid);
+
+ if (size < 0)
+ PG_RETURN_NULL();
+
+ PG_RETURN_INT64(size);
+}
+
/*
* Get the filenode of a relation
*
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 6a5476d3c4c..e8acaf6e5e5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7478,6 +7478,25 @@
descr => 'total disk space usage for the specified tablespace',
proname => 'pg_tablespace_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'name', prosrc => 'pg_tablespace_size_name' },
+
+{ oid => '9410',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_namespace_size_oid' },
+{ oid => '9411',
+ descr => 'total disk space usage for the specified namespace',
+ proname => 'pg_namespace_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_namespace_size_name' },
+
+{ oid => '9412',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'oid', prosrc => 'pg_am_size_oid' },
+{ oid => '9413',
+ descr => 'total disk space usage for the specified access method',
+ proname => 'pg_am_size', provolatile => 'v', prorettype => 'int8',
+ proargtypes => 'name', prosrc => 'pg_am_size_name' },
+
{ oid => '2324', descr => 'total disk space usage for the specified database',
proname => 'pg_database_size', provolatile => 'v', prorettype => 'int8',
proargtypes => 'oid', prosrc => 'pg_database_size_oid' },
--
2.42.0
0002-psql-add-convenience-commands-dA-and-dn.patchtext/x-diff; charset=us-asciiDownload
From a89d18fdbee65ec9ee6bc7d5bd98190a21512386 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Sat, 18 Dec 2021 14:58:06 -0600
Subject: [PATCH 2/4] psql: add convenience commands: \dA+ and \dn+
show the size only with \dA++ and \dn++ (for which the single-plus
commands have historically not done any slow operations).
Also change to show the size only with \db++ and \l++ (for which it's
useful to show the ACL without also doing any slow operations).
\dt+ and \dP+ are not changed, since showing the table sizes seems to be their
primary purpose (??)
The idea for plusplus commands were previously discussed here.
https://www.postgresql.org/message-id/20190506163359.GA29291%40alvherre.pgsql
---
src/bin/psql/command.c | 20 +++++++++++-------
src/bin/psql/describe.c | 46 +++++++++++++++++++++++++++++------------
src/bin/psql/describe.h | 8 +++----
3 files changed, 50 insertions(+), 24 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index fae5940b54e..14c772c18f3 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -370,6 +370,7 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "if") == 0)
status = exec_command_if(scan_state, cstack, query_buf);
else if (strcmp(cmd, "l") == 0 || strcmp(cmd, "list") == 0 ||
+ strcmp(cmd, "l++") == 0 || strcmp(cmd, "list++") == 0 ||
strcmp(cmd, "l+") == 0 || strcmp(cmd, "list+") == 0)
status = exec_command_list(scan_state, active_branch, cmd);
else if (strncmp(cmd, "lo_", 3) == 0)
@@ -757,6 +758,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
+ int verbose = 0;
bool show_verbose,
show_system;
@@ -764,7 +766,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
+
+ show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -789,7 +794,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
case '\0':
case '+':
- success = describeAccessMethods(pattern, show_verbose);
+ success = describeAccessMethods(pattern, verbose);
break;
case 'c':
success = listOperatorClasses(pattern, pattern2, show_verbose);
@@ -815,7 +820,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAggregates(pattern, show_verbose, show_system);
break;
case 'b':
- success = describeTablespaces(pattern, show_verbose);
+ success = describeTablespaces(pattern, verbose);
break;
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
@@ -869,7 +874,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listLanguages(pattern, show_verbose, show_system);
break;
case 'n':
- success = listSchemas(pattern, show_verbose, show_system);
+ success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
@@ -1952,14 +1957,15 @@ exec_command_list(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (active_branch)
{
char *pattern;
- bool show_verbose;
+ int verbose = 0;
pattern = psql_scan_slash_option(scan_state,
OT_NORMAL, NULL, true);
- show_verbose = strchr(cmd, '+') ? true : false;
+ for (const char *t = cmd; *t != '\0'; ++t)
+ verbose += *t == '+' ? 1 : 0;
- success = listAllDbs(pattern, show_verbose);
+ success = listAllDbs(pattern, verbose);
free(pattern);
}
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index f67bf0b8925..1d18f7c6cd9 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -138,12 +138,12 @@ describeAggregates(const char *pattern, bool verbose, bool showSystem)
* Takes an optional regexp to select particular access methods
*/
bool
-describeAccessMethods(const char *pattern, bool verbose)
+describeAccessMethods(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- static const bool translate_columns[] = {false, true, false, false};
+ static const bool translate_columns[] = {false, true, false, false, false};
if (pset.sversion < 90600)
{
@@ -175,6 +175,11 @@ describeAccessMethods(const char *pattern, bool verbose)
" pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_am_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -212,7 +217,7 @@ describeAccessMethods(const char *pattern, bool verbose)
* Takes an optional regexp to select particular tablespaces
*/
bool
-describeTablespaces(const char *pattern, bool verbose)
+describeTablespaces(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -232,12 +237,18 @@ describeTablespaces(const char *pattern, bool verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
+
+ appendPQExpBuffer(&buf,
+ ",\n spcoptions AS \"%s\"",
+ gettext_noop("Options"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\""
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Options"),
- gettext_noop("Size"),
gettext_noop("Description"));
}
@@ -908,7 +919,7 @@ error_return:
* for \l, \list, and -l switch
*/
bool
-listAllDbs(const char *pattern, bool verbose)
+listAllDbs(const char *pattern, int verbose)
{
PGresult *res;
PQExpBufferData buf;
@@ -959,20 +970,24 @@ listAllDbs(const char *pattern, bool verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose)
+ if (verbose > 1)
appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
" ELSE 'No Access'\n"
- " END as \"%s\""
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
+ if (verbose > 0)
+ appendPQExpBuffer(&buf,
",\n t.spcname as \"%s\""
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Tablespace"),
gettext_noop("Description"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
@@ -5023,7 +5038,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
* Describes schemas (namespaces)
*/
bool
-listSchemas(const char *pattern, bool verbose, bool showSystem)
+listSchemas(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -5045,6 +5060,11 @@ listSchemas(const char *pattern, bool verbose, bool showSystem)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
gettext_noop("Description"));
+
+ if (verbose > 1 && pset.sversion >= 170000)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_namespace_size(n.oid)) AS \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 273f974538e..10271ba1393 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -13,10 +13,10 @@
extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
/* \dA */
-extern bool describeAccessMethods(const char *pattern, bool verbose);
+extern bool describeAccessMethods(const char *pattern, int verbose);
/* \db */
-extern bool describeTablespaces(const char *pattern, bool verbose);
+extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
@@ -65,7 +65,7 @@ extern bool listTSDictionaries(const char *pattern, bool verbose);
extern bool listTSTemplates(const char *pattern, bool verbose);
/* \l */
-extern bool listAllDbs(const char *pattern, bool verbose);
+extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
@@ -90,7 +90,7 @@ extern bool listCasts(const char *pattern, bool verbose);
extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
/* \dn */
-extern bool listSchemas(const char *pattern, bool verbose, bool showSystem);
+extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
extern bool listForeignDataWrappers(const char *pattern, bool verbose);
--
2.42.0
0003-f-convert-the-other-verbose-to-int-too.patchtext/x-diff; charset=us-asciiDownload
From e60146531711890993042f00667734097aca021d Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Thu, 15 Jul 2021 03:19:58 -0500
Subject: [PATCH 3/4] f!convert the other verbose to int, too
---
src/bin/psql/command.c | 82 ++++++++++----------
src/bin/psql/describe.c | 163 ++++++++++++++++++++--------------------
src/bin/psql/describe.h | 58 +++++++-------
3 files changed, 151 insertions(+), 152 deletions(-)
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 14c772c18f3..6ee91bd2892 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -76,7 +76,7 @@ static backslashResult exec_command_d(PsqlScanState scan_state, bool active_bran
const char *cmd);
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system);
+ int verbose, bool show_system);
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf, PQExpBuffer previous_buf);
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -759,8 +759,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
{
char *pattern;
int verbose = 0;
- bool show_verbose,
- show_system;
+ bool show_system;
/* We don't do SQLID reduction on the pattern yet */
pattern = psql_scan_slash_option(scan_state,
@@ -769,7 +768,6 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
for (const char *t = cmd; *t != '\0'; ++t)
verbose += *t == '+' ? 1 : 0;
- show_verbose = (bool) (verbose != 0);
show_system = strchr(cmd, 'S') ? true : false;
switch (cmd[1])
@@ -778,10 +776,10 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case '+':
case 'S':
if (pattern)
- success = describeTableDetails(pattern, show_verbose, show_system);
+ success = describeTableDetails(pattern, verbose, show_system);
else
/* standard listing of interesting things */
- success = listTables("tvmsE", NULL, show_verbose, show_system);
+ success = listTables("tvmsE", NULL, verbose, show_system);
break;
case 'A':
{
@@ -797,16 +795,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = describeAccessMethods(pattern, verbose);
break;
case 'c':
- success = listOperatorClasses(pattern, pattern2, show_verbose);
+ success = listOperatorClasses(pattern, pattern2, verbose);
break;
case 'f':
- success = listOperatorFamilies(pattern, pattern2, show_verbose);
+ success = listOperatorFamilies(pattern, pattern2, verbose);
break;
case 'o':
- success = listOpFamilyOperators(pattern, pattern2, show_verbose);
+ success = listOpFamilyOperators(pattern, pattern2, verbose);
break;
case 'p':
- success = listOpFamilyFunctions(pattern, pattern2, show_verbose);
+ success = listOpFamilyFunctions(pattern, pattern2, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -817,7 +815,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'a':
- success = describeAggregates(pattern, show_verbose, show_system);
+ success = describeAggregates(pattern, verbose, show_system);
break;
case 'b':
success = describeTablespaces(pattern, verbose);
@@ -825,15 +823,15 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'c':
if (strncmp(cmd, "dconfig", 7) == 0)
success = describeConfigurationParameters(pattern,
- show_verbose,
+ verbose,
show_system);
else
success = listConversions(pattern,
- show_verbose,
+ verbose,
show_system);
break;
case 'C':
- success = listCasts(pattern, show_verbose);
+ success = listCasts(pattern, verbose);
break;
case 'd':
if (strncmp(cmd, "ddp", 3) == 0)
@@ -842,7 +840,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = objectDescription(pattern, show_system);
break;
case 'D':
- success = listDomains(pattern, show_verbose, show_system);
+ success = listDomains(pattern, verbose, show_system);
break;
case 'f': /* function subsystem */
switch (cmd[2])
@@ -856,7 +854,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'w':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -865,23 +863,23 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
break;
case 'g':
/* no longer distinct from \du */
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'l':
- success = listLargeObjects(show_verbose);
+ success = listLargeObjects(verbose);
break;
case 'L':
- success = listLanguages(pattern, show_verbose, show_system);
+ success = listLanguages(pattern, verbose, show_system);
break;
case 'n':
success = listSchemas(pattern, verbose, show_system);
break;
case 'o':
success = exec_command_dfo(scan_state, cmd, pattern,
- show_verbose, show_system);
+ verbose, show_system);
break;
case 'O':
- success = listCollations(pattern, show_verbose, show_system);
+ success = listCollations(pattern, verbose, show_system);
break;
case 'p':
success = permissionsList(pattern, show_system);
@@ -895,7 +893,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 't':
case 'i':
case 'n':
- success = listPartitionedTables(&cmd[2], pattern, show_verbose);
+ success = listPartitionedTables(&cmd[2], pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -904,7 +902,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'T':
- success = describeTypes(pattern, show_verbose, show_system);
+ success = describeTypes(pattern, verbose, show_system);
break;
case 't':
case 'v':
@@ -912,7 +910,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
case 'i':
case 's':
case 'E':
- success = listTables(&cmd[1], pattern, show_verbose, show_system);
+ success = listTables(&cmd[1], pattern, verbose, show_system);
break;
case 'r':
if (cmd[2] == 'd' && cmd[3] == 's')
@@ -935,36 +933,36 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 'p':
- if (show_verbose)
+ if (verbose > 0)
success = describePublications(pattern);
else
success = listPublications(pattern);
break;
case 's':
- success = describeSubscriptions(pattern, show_verbose);
+ success = describeSubscriptions(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
}
break;
case 'u':
- success = describeRoles(pattern, show_verbose, show_system);
+ success = describeRoles(pattern, verbose, show_system);
break;
case 'F': /* text search subsystem */
switch (cmd[2])
{
case '\0':
case '+':
- success = listTSConfigs(pattern, show_verbose);
+ success = listTSConfigs(pattern, verbose);
break;
case 'p':
- success = listTSParsers(pattern, show_verbose);
+ success = listTSParsers(pattern, verbose);
break;
case 'd':
- success = listTSDictionaries(pattern, show_verbose);
+ success = listTSDictionaries(pattern, verbose);
break;
case 't':
- success = listTSTemplates(pattern, show_verbose);
+ success = listTSTemplates(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -975,16 +973,16 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
switch (cmd[2])
{
case 's':
- success = listForeignServers(pattern, show_verbose);
+ success = listForeignServers(pattern, verbose);
break;
case 'u':
- success = listUserMappings(pattern, show_verbose);
+ success = listUserMappings(pattern, verbose);
break;
case 'w':
- success = listForeignDataWrappers(pattern, show_verbose);
+ success = listForeignDataWrappers(pattern, verbose);
break;
case 't':
- success = listForeignTables(pattern, show_verbose);
+ success = listForeignTables(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -992,7 +990,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
break;
case 'x': /* Extensions */
- if (show_verbose)
+ if (verbose > 0)
success = listExtensionContents(pattern);
else
success = listExtensions(pattern);
@@ -1001,7 +999,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
success = listExtendedStats(pattern);
break;
case 'y': /* Event Triggers */
- success = listEventTriggers(pattern, show_verbose);
+ success = listEventTriggers(pattern, verbose);
break;
default:
status = PSQL_CMD_UNKNOWN;
@@ -1022,7 +1020,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
static bool
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
const char *pattern,
- bool show_verbose, bool show_system)
+ int verbose, bool show_system)
{
bool success;
char *arg_patterns[FUNC_MAX_ARGS];
@@ -1045,11 +1043,11 @@ exec_command_dfo(PsqlScanState scan_state, const char *cmd,
if (cmd[1] == 'f')
success = describeFunctions(&cmd[2], pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
else
success = describeOperators(pattern,
arg_patterns, num_arg_patterns,
- show_verbose, show_system);
+ verbose, show_system);
while (--num_arg_patterns >= 0)
free(arg_patterns[num_arg_patterns]);
@@ -2023,9 +2021,9 @@ exec_command_lo(PsqlScanState scan_state, bool active_branch, const char *cmd)
}
else if (strcmp(cmd + 3, "list") == 0)
- success = listLargeObjects(false);
+ success = listLargeObjects(0);
else if (strcmp(cmd + 3, "list+") == 0)
- success = listLargeObjects(true);
+ success = listLargeObjects(1);
else if (strcmp(cmd + 3, "unlink") == 0)
{
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 1d18f7c6cd9..83f51d6c880 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -33,7 +33,7 @@ static const char *map_typename_pattern(const char *pattern);
static bool describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose);
+ int verbose);
static void add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, const bool newline);
static void add_role_attribute(PQExpBuffer buf, const char *const str);
@@ -68,7 +68,7 @@ static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern,
* Takes an optional regexp to select particular aggregates
*/
bool
-describeAggregates(const char *pattern, bool verbose, bool showSystem)
+describeAggregates(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -168,7 +168,7 @@ describeAccessMethods(const char *pattern, int verbose)
gettext_noop("Table"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n amhandler AS \"%s\",\n"
@@ -233,7 +233,7 @@ describeTablespaces(const char *pattern, int verbose)
gettext_noop("Owner"),
gettext_noop("Location"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "spcacl");
@@ -298,7 +298,7 @@ describeTablespaces(const char *pattern, int verbose)
bool
describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
bool showAggregate = strchr(functypes, 'a') != NULL;
bool showNormal = strchr(functypes, 'n') != NULL;
@@ -383,7 +383,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
gettext_noop("func"),
gettext_noop("Type"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n CASE\n"
@@ -438,7 +438,7 @@ describeFunctions(const char *functypes, const char *func_pattern,
i, i, i, i, i, i);
}
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
@@ -623,7 +623,7 @@ error_return:
* describe types
*/
bool
-describeTypes(const char *pattern, bool verbose, bool showSystem)
+describeTypes(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -636,7 +636,7 @@ describeTypes(const char *pattern, bool verbose, bool showSystem)
" pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" t.typname AS \"%s\",\n"
@@ -780,7 +780,7 @@ map_typename_pattern(const char *pattern)
bool
describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem)
+ int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -816,7 +816,7 @@ describeOperators(const char *oper_pattern,
gettext_noop("Right arg type"),
gettext_noop("Result type"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
" o.oprcode AS \"%s\",\n",
gettext_noop("Function"));
@@ -1454,10 +1454,10 @@ error_return:
* This routine finds the tables to be displayed, and calls
* describeOneTableDetails for each one.
*
- * verbose: if true, this is \d+
+ * verbose: this is \d+ (or \d++)
*/
bool
-describeTableDetails(const char *pattern, bool verbose, bool showSystem)
+describeTableDetails(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -1543,7 +1543,7 @@ static bool
describeOneTableDetails(const char *schemaname,
const char *relationname,
const char *oid,
- bool verbose)
+ int verbose)
{
bool retval = false;
PQExpBufferData buf;
@@ -1916,7 +1916,7 @@ describeOneTableDetails(const char *schemaname,
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
fdwopts_col = cols++;
}
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n a.attstorage");
attstorage_col = cols++;
@@ -2174,7 +2174,7 @@ describeOneTableDetails(const char *schemaname,
"false as inhdetachpending");
/* If verbose, also request the partition constraint definition */
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
",\n pg_catalog.pg_get_partition_constraintdef(c.oid)");
appendPQExpBuffer(&buf,
@@ -2197,7 +2197,7 @@ describeOneTableDetails(const char *schemaname,
strcmp(detached, "t") == 0 ? " DETACH PENDING" : "");
printTableAddFooter(&cont, tmpbuf.data);
- if (verbose)
+ if (verbose > 0)
{
char *partconstraintdef = NULL;
@@ -3434,7 +3434,7 @@ describeOneTableDetails(const char *schemaname,
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
}
- else if (!verbose)
+ else if (verbose == 0)
{
/* print the number of child tables, if any */
if (tuples > 0)
@@ -3486,7 +3486,7 @@ describeOneTableDetails(const char *schemaname,
printTableAddFooter(&cont, buf.data);
}
- if (verbose &&
+ if (verbose > 0 &&
(tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW) &&
@@ -3510,7 +3510,7 @@ describeOneTableDetails(const char *schemaname,
}
/* OIDs, if verbose and not a materialized view */
- if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
+ if (verbose > 0 && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
@@ -3518,7 +3518,7 @@ describeOneTableDetails(const char *schemaname,
true);
/* Access method info */
- if (verbose && tableinfo.relam != NULL && !pset.hide_tableam)
+ if (verbose > 0 && tableinfo.relam != NULL && !pset.hide_tableam)
{
printfPQExpBuffer(&buf, _("Access method: %s"), tableinfo.relam);
printTableAddFooter(&cont, buf.data);
@@ -3526,7 +3526,7 @@ describeOneTableDetails(const char *schemaname,
}
/* reloptions, if verbose */
- if (verbose &&
+ if (verbose > 0 &&
tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
{
const char *t = _("Options");
@@ -3626,7 +3626,7 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
* Describes roles. Any schema portion of the pattern is ignored.
*/
bool
-describeRoles(const char *pattern, bool verbose, bool showSystem)
+describeRoles(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -3648,11 +3648,12 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
" r.rolconnlimit, r.rolvaliduntil");
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
ncols++;
}
+
appendPQExpBufferStr(&buf, "\n, r.rolreplication");
if (pset.sversion >= 90500)
@@ -3687,7 +3688,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
- if (verbose)
+ if (verbose > 0)
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
for (i = 0; i < nrows; i++)
@@ -3744,7 +3745,7 @@ describeRoles(const char *pattern, bool verbose, bool showSystem)
printTableAddCell(&cont, attr[i], false, false);
- if (verbose)
+ if (verbose > 0)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
}
termPQExpBuffer(&buf);
@@ -3921,7 +3922,7 @@ describeRoleGrants(const char *pattern, bool showSystem)
* (any order of the above is fine)
*/
bool
-listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
+listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem)
{
bool showTables = strchr(tabtypes, 't') != NULL;
bool showIndexes = strchr(tabtypes, 'i') != NULL;
@@ -3980,7 +3981,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
cols_so_far++;
}
- if (verbose)
+ if (verbose > 0)
{
/*
* Show whether a relation is permanent, temporary, or unlogged.
@@ -4119,7 +4120,7 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
* and you can mix and match these in any order.
*/
bool
-listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
+listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
{
bool showTables = strchr(reltypes, 't') != NULL;
bool showIndexes = strchr(reltypes, 'i') != NULL;
@@ -4194,7 +4195,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
- if (verbose)
+ if (verbose > 0)
{
if (showNested)
{
@@ -4229,7 +4230,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
appendPQExpBufferStr(&buf,
"\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
- if (verbose)
+ if (verbose > 0)
{
if (pset.sversion < 120000)
{
@@ -4319,7 +4320,7 @@ listPartitionedTables(const char *reltypes, const char *pattern, bool verbose)
* Describes languages.
*/
bool
-listLanguages(const char *pattern, bool verbose, bool showSystem)
+listLanguages(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4335,7 +4336,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Owner"),
gettext_noop("Trusted"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
",\n NOT l.lanispl AS \"%s\",\n"
@@ -4395,7 +4396,7 @@ listLanguages(const char *pattern, bool verbose, bool showSystem)
* Describes domains.
*/
bool
-listDomains(const char *pattern, bool verbose, bool showSystem)
+listDomains(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4422,7 +4423,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
gettext_noop("Default"),
gettext_noop("Check"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
@@ -4435,7 +4436,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
"\nFROM pg_catalog.pg_type t\n"
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = t.tableoid AND d.objoid = t.oid "
@@ -4478,7 +4479,7 @@ listDomains(const char *pattern, bool verbose, bool showSystem)
* Describes conversions.
*/
bool
-listConversions(const char *pattern, bool verbose, bool showSystem)
+listConversions(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4502,7 +4503,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4512,7 +4513,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
" JOIN pg_catalog.pg_namespace n "
"ON n.oid = c.connamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d "
"ON d.classoid = c.tableoid\n"
@@ -4558,7 +4559,7 @@ listConversions(const char *pattern, bool verbose, bool showSystem)
* Describes configuration parameters.
*/
bool
-describeConfigurationParameters(const char *pattern, bool verbose,
+describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem)
{
PQExpBufferData buf;
@@ -4626,7 +4627,7 @@ describeConfigurationParameters(const char *pattern, bool verbose,
* Describes Event Triggers.
*/
bool
-listEventTriggers(const char *pattern, bool verbose)
+listEventTriggers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4667,7 +4668,7 @@ listEventTriggers(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
@@ -4802,7 +4803,7 @@ listExtendedStats(const char *pattern)
* Describes casts.
*/
bool
-listCasts(const char *pattern, bool verbose)
+listCasts(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -4843,7 +4844,7 @@ listCasts(const char *pattern, bool verbose)
gettext_noop("yes"),
gettext_noop("Implicit?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n d.description AS \"%s\"",
gettext_noop("Description"));
@@ -4864,7 +4865,7 @@ listCasts(const char *pattern, bool verbose)
" LEFT JOIN pg_catalog.pg_namespace nt\n"
" ON nt.oid = tt.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND d.objoid = "
@@ -4920,7 +4921,7 @@ error_return:
* Describes collations.
*/
bool
-listCollations(const char *pattern, bool verbose, bool showSystem)
+listCollations(const char *pattern, int verbose, bool showSystem)
{
PQExpBufferData buf;
PGresult *res;
@@ -4984,7 +4985,7 @@ listCollations(const char *pattern, bool verbose, bool showSystem)
gettext_noop("yes"),
gettext_noop("Deterministic?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
@@ -5053,7 +5054,7 @@ listSchemas(const char *pattern, int verbose, bool showSystem)
gettext_noop("Name"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "n.nspacl");
@@ -5164,13 +5165,13 @@ error_return:
* list text search parsers
*/
bool
-listTSParsers(const char *pattern, bool verbose)
+listTSParsers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSParsersVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5411,7 +5412,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
* list text search dictionaries
*/
bool
-listTSDictionaries(const char *pattern, bool verbose)
+listTSDictionaries(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5426,7 +5427,7 @@ listTSDictionaries(const char *pattern, bool verbose)
gettext_noop("Schema"),
gettext_noop("Name"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBuffer(&buf,
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
@@ -5476,7 +5477,7 @@ listTSDictionaries(const char *pattern, bool verbose)
* list text search templates
*/
bool
-listTSTemplates(const char *pattern, bool verbose)
+listTSTemplates(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5484,7 +5485,7 @@ listTSTemplates(const char *pattern, bool verbose)
initPQExpBuffer(&buf);
- if (verbose)
+ if (verbose > 0)
printfPQExpBuffer(&buf,
"SELECT\n"
" n.nspname AS \"%s\",\n"
@@ -5541,13 +5542,13 @@ listTSTemplates(const char *pattern, bool verbose)
* list text search configurations
*/
bool
-listTSConfigs(const char *pattern, bool verbose)
+listTSConfigs(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
- if (verbose)
+ if (verbose > 0)
return listTSConfigsVerbose(pattern);
initPQExpBuffer(&buf);
@@ -5745,7 +5746,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
* Describes foreign-data wrappers
*/
bool
-listForeignDataWrappers(const char *pattern, bool verbose)
+listForeignDataWrappers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5762,7 +5763,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
gettext_noop("Handler"),
gettext_noop("Validator"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "fdwacl");
@@ -5780,7 +5781,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = fdw.tableoid "
@@ -5816,7 +5817,7 @@ listForeignDataWrappers(const char *pattern, bool verbose)
* Describes foreign servers.
*/
bool
-listForeignServers(const char *pattern, bool verbose)
+listForeignServers(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5831,7 +5832,7 @@ listForeignServers(const char *pattern, bool verbose)
gettext_noop("Owner"),
gettext_noop("Foreign-data wrapper"));
- if (verbose)
+ if (verbose > 0)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "s.srvacl");
@@ -5856,7 +5857,7 @@ listForeignServers(const char *pattern, bool verbose)
"\nFROM pg_catalog.pg_foreign_server s\n"
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
"LEFT JOIN pg_catalog.pg_description d\n "
"ON d.classoid = s.tableoid AND d.objoid = s.oid "
@@ -5892,7 +5893,7 @@ listForeignServers(const char *pattern, bool verbose)
* Describes user mappings.
*/
bool
-listUserMappings(const char *pattern, bool verbose)
+listUserMappings(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5905,7 +5906,7 @@ listUserMappings(const char *pattern, bool verbose)
gettext_noop("Server"),
gettext_noop("User name"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5947,7 +5948,7 @@ listUserMappings(const char *pattern, bool verbose)
* Describes foreign tables.
*/
bool
-listForeignTables(const char *pattern, bool verbose)
+listForeignTables(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -5962,7 +5963,7 @@ listForeignTables(const char *pattern, bool verbose)
gettext_noop("Table"),
gettext_noop("Server"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
@@ -5982,7 +5983,7 @@ listForeignTables(const char *pattern, bool verbose)
" ON n.oid = c.relnamespace\n"
" INNER JOIN pg_catalog.pg_foreign_server s"
" ON s.oid = ft.ftserver\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_description d\n"
" ON d.classoid = c.tableoid AND "
@@ -6542,7 +6543,7 @@ error_return:
* Takes an optional regexp to select particular subscriptions
*/
bool
-describeSubscriptions(const char *pattern, bool verbose)
+describeSubscriptions(const char *pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6573,7 +6574,7 @@ describeSubscriptions(const char *pattern, bool verbose)
gettext_noop("Enabled"),
gettext_noop("Publication"));
- if (verbose)
+ if (verbose > 0)
{
/* Binary mode and streaming are only supported in v14 and higher */
if (pset.sversion >= 140000)
@@ -6695,7 +6696,7 @@ printACLColumn(PQExpBuffer buf, const char *colname)
*/
bool
listOperatorClasses(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6730,7 +6731,7 @@ listOperatorClasses(const char *access_method_pattern,
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n CASE\n"
" WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
@@ -6746,7 +6747,7 @@ listOperatorClasses(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
" LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
" LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
" LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
@@ -6796,7 +6797,7 @@ error_return:
*/
bool
listOperatorFamilies(const char *access_method_pattern,
- const char *type_pattern, bool verbose)
+ const char *type_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6821,7 +6822,7 @@ listOperatorFamilies(const char *access_method_pattern,
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Applicable types"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
gettext_noop("Owner"));
@@ -6885,7 +6886,7 @@ error_return:
*/
bool
listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -6918,7 +6919,7 @@ listOpFamilyOperators(const char *access_method_pattern,
gettext_noop("search"),
gettext_noop("Purpose"));
- if (verbose)
+ if (verbose > 0)
appendPQExpBuffer(&buf,
", ofs.opfname AS \"%s\"\n",
gettext_noop("Sort opfamily"));
@@ -6927,7 +6928,7 @@ listOpFamilyOperators(const char *access_method_pattern,
" LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
" LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
" LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
- if (verbose)
+ if (verbose > 0)
appendPQExpBufferStr(&buf,
" LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
@@ -6983,7 +6984,7 @@ error_return:
*/
bool
listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose)
+ const char *family_pattern, int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7010,7 +7011,7 @@ listOpFamilyFunctions(const char *access_method_pattern,
gettext_noop("Registered right type"),
gettext_noop("Number"));
- if (!verbose)
+ if (verbose == 0)
appendPQExpBuffer(&buf,
", p.proname AS \"%s\"\n",
gettext_noop("Function"));
@@ -7071,7 +7072,7 @@ error_return:
* Lists large objects
*/
bool
-listLargeObjects(bool verbose)
+listLargeObjects(int verbose)
{
PQExpBufferData buf;
PGresult *res;
@@ -7085,7 +7086,7 @@ listLargeObjects(bool verbose)
gettext_noop("ID"),
gettext_noop("Owner"));
- if (verbose)
+ if (verbose > 0)
{
printACLColumn(&buf, "lomacl");
appendPQExpBufferStr(&buf, ",\n ");
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 10271ba1393..e0181bb3877 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -10,7 +10,7 @@
/* \da */
-extern bool describeAggregates(const char *pattern, bool verbose, bool showSystem);
+extern bool describeAggregates(const char *pattern, int verbose, bool showSystem);
/* \dA */
extern bool describeAccessMethods(const char *pattern, int verbose);
@@ -21,18 +21,18 @@ extern bool describeTablespaces(const char *pattern, int verbose);
/* \df, \dfa, \dfn, \dft, \dfw, etc. */
extern bool describeFunctions(const char *functypes, const char *func_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \dT */
-extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTypes(const char *pattern, int verbose, bool showSystem);
/* \do */
extern bool describeOperators(const char *oper_pattern,
char **arg_patterns, int num_arg_patterns,
- bool verbose, bool showSystem);
+ int verbose, bool showSystem);
/* \du, \dg */
-extern bool describeRoles(const char *pattern, bool verbose, bool showSystem);
+extern bool describeRoles(const char *pattern, int verbose, bool showSystem);
/* \drds */
extern bool listDbRoleSettings(const char *pattern, const char *pattern2);
@@ -50,62 +50,62 @@ extern bool listDefaultACLs(const char *pattern);
extern bool objectDescription(const char *pattern, bool showSystem);
/* \d foo */
-extern bool describeTableDetails(const char *pattern, bool verbose, bool showSystem);
+extern bool describeTableDetails(const char *pattern, int verbose, bool showSystem);
/* \dF */
-extern bool listTSConfigs(const char *pattern, bool verbose);
+extern bool listTSConfigs(const char *pattern, int verbose);
/* \dFp */
-extern bool listTSParsers(const char *pattern, bool verbose);
+extern bool listTSParsers(const char *pattern, int verbose);
/* \dFd */
-extern bool listTSDictionaries(const char *pattern, bool verbose);
+extern bool listTSDictionaries(const char *pattern, int verbose);
/* \dFt */
-extern bool listTSTemplates(const char *pattern, bool verbose);
+extern bool listTSTemplates(const char *pattern, int verbose);
/* \l */
extern bool listAllDbs(const char *pattern, int verbose);
/* \dt, \di, \ds, \dS, etc. */
-extern bool listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSystem);
+extern bool listTables(const char *tabtypes, const char *pattern, int verbose, bool showSystem);
/* \dP */
-extern bool listPartitionedTables(const char *reltypes, const char *pattern, bool verbose);
+extern bool listPartitionedTables(const char *reltypes, const char *pattern, int verbose);
/* \dD */
-extern bool listDomains(const char *pattern, bool verbose, bool showSystem);
+extern bool listDomains(const char *pattern, int verbose, bool showSystem);
/* \dc */
-extern bool listConversions(const char *pattern, bool verbose, bool showSystem);
+extern bool listConversions(const char *pattern, int verbose, bool showSystem);
/* \dconfig */
-extern bool describeConfigurationParameters(const char *pattern, bool verbose,
+extern bool describeConfigurationParameters(const char *pattern, int verbose,
bool showSystem);
/* \dC */
-extern bool listCasts(const char *pattern, bool verbose);
+extern bool listCasts(const char *pattern, int verbose);
/* \dO */
-extern bool listCollations(const char *pattern, bool verbose, bool showSystem);
+extern bool listCollations(const char *pattern, int verbose, bool showSystem);
/* \dn */
extern bool listSchemas(const char *pattern, int verbose, bool showSystem);
/* \dew */
-extern bool listForeignDataWrappers(const char *pattern, bool verbose);
+extern bool listForeignDataWrappers(const char *pattern, int verbose);
/* \des */
-extern bool listForeignServers(const char *pattern, bool verbose);
+extern bool listForeignServers(const char *pattern, int verbose);
/* \deu */
-extern bool listUserMappings(const char *pattern, bool verbose);
+extern bool listUserMappings(const char *pattern, int verbose);
/* \det */
-extern bool listForeignTables(const char *pattern, bool verbose);
+extern bool listForeignTables(const char *pattern, int verbose);
/* \dL */
-extern bool listLanguages(const char *pattern, bool verbose, bool showSystem);
+extern bool listLanguages(const char *pattern, int verbose, bool showSystem);
/* \dx */
extern bool listExtensions(const char *pattern);
@@ -117,7 +117,7 @@ extern bool listExtensionContents(const char *pattern);
extern bool listExtendedStats(const char *pattern);
/* \dy */
-extern bool listEventTriggers(const char *pattern, bool verbose);
+extern bool listEventTriggers(const char *pattern, int verbose);
/* \dRp */
bool listPublications(const char *pattern);
@@ -126,27 +126,27 @@ bool listPublications(const char *pattern);
bool describePublications(const char *pattern);
/* \dRs */
-bool describeSubscriptions(const char *pattern, bool verbose);
+bool describeSubscriptions(const char *pattern, int verbose);
/* \dAc */
extern bool listOperatorClasses(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAf */
extern bool listOperatorFamilies(const char *access_method_pattern,
const char *type_pattern,
- bool verbose);
+ int verbose);
/* \dAo */
extern bool listOpFamilyOperators(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dAp */
extern bool listOpFamilyFunctions(const char *access_method_pattern,
- const char *family_pattern, bool verbose);
+ const char *family_pattern, int verbose);
/* \dl or \lo_list */
-extern bool listLargeObjects(bool verbose);
+extern bool listLargeObjects(int verbose);
#endif /* DESCRIBE_H */
--
2.42.0
0004-Move-the-double-plus-Size-columns-to-the-right.patchtext/x-diff; charset=us-asciiDownload
From b291f61f15e54306cc653faf6c87fee1e95ca94b Mon Sep 17 00:00:00 2001
From: Justin Pryzby <pryzbyj@telsasoft.com>
Date: Fri, 17 Dec 2021 09:35:46 -0600
Subject: [PATCH 4/4] Move the double-plus "Size" columns to the right
\dn, \dA, \db, \l, and (for consistency) \d and \dP+
It doesn't make much sense that one cannot show a database's default
tablespace without also showing its size, and stat()ing every segment of
every relation in the DB.
---
src/bin/psql/describe.c | 40 ++++++++++++----------
src/test/regress/expected/psql.out | 54 +++++++++++++++---------------
2 files changed, 49 insertions(+), 45 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 83f51d6c880..b62355f2a58 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -239,17 +239,15 @@ describeTablespaces(const char *pattern, int verbose)
printACLColumn(&buf, "spcacl");
appendPQExpBuffer(&buf,
- ",\n spcoptions AS \"%s\"",
- gettext_noop("Options"));
+ ",\n spcoptions AS \"%s\""
+ ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
+ gettext_noop("Options"),
+ gettext_noop("Description"));
if (verbose > 1)
appendPQExpBuffer(&buf,
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
gettext_noop("Size"));
-
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
@@ -970,13 +968,6 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("ICU Rules"));
appendPQExpBufferStr(&buf, " ");
printACLColumn(&buf, "d.datacl");
- if (verbose > 1)
- appendPQExpBuffer(&buf,
- ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
- " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
- " ELSE 'No Access'\n"
- " END as \"%s\"",
- gettext_noop("Size"));
if (verbose > 0)
appendPQExpBuffer(&buf,
@@ -985,6 +976,14 @@ listAllDbs(const char *pattern, int verbose)
gettext_noop("Tablespace"),
gettext_noop("Description"));
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
+ " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
+ " ELSE 'No Access'\n"
+ " END as \"%s\"",
+ gettext_noop("Size"));
+
appendPQExpBufferStr(&buf,
"\nFROM pg_catalog.pg_database d\n");
if (verbose > 0)
@@ -4010,10 +4009,13 @@ listTables(const char *tabtypes, const char *pattern, int verbose, bool showSyst
gettext_noop("Access method"));
appendPQExpBuffer(&buf,
- ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Size"),
gettext_noop("Description"));
+
+ if (verbose > 1)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"",
+ gettext_noop("Size"));
}
appendPQExpBufferStr(&buf,
@@ -4196,6 +4198,11 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
gettext_noop("Table"));
if (verbose > 0)
+ appendPQExpBuffer(&buf,
+ ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
+ gettext_noop("Description"));
+
+ if (verbose > 1)
{
if (showNested)
{
@@ -4212,9 +4219,6 @@ listPartitionedTables(const char *reltypes, const char *pattern, int verbose)
",\n s.tps as \"%s\"",
gettext_noop("Total size"));
- appendPQExpBuffer(&buf,
- ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
- gettext_noop("Description"));
}
appendPQExpBufferStr(&buf,
diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out
index 3bbe4c5f974..4b2db3174b0 100644
--- a/src/test/regress/expected/psql.out
+++ b/src/test/regress/expected/psql.out
@@ -2905,47 +2905,47 @@ Access method: heap
-- AM is displayed for tables, indexes and materialized views.
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent | |
(4 rows)
\dt+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
- tableam_display | tbl_heap | table | regress_display_role | permanent | heap | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+---------------+-------+----------------------+-------------+---------------+-------------
+ tableam_display | tbl_heap | table | regress_display_role | permanent | heap |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent | heap_psql |
(2 rows)
\dm+
- List of relations
- Schema | Name | Type | Owner | Persistence | Access method | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Access method | Description
+-----------------+--------------------+-------------------+----------------------+-------------+---------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | heap_psql |
(1 row)
-- But not for views and sequences.
\dv+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+----------------+------+----------------------+-------------+---------+-------------
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+----------------+------+----------------------+-------------+-------------
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(1 row)
\set HIDE_TABLEAM on
\d+
- List of relations
- Schema | Name | Type | Owner | Persistence | Size | Description
------------------+--------------------+-------------------+----------------------+-------------+---------+-------------
- tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap | table | regress_display_role | permanent | 0 bytes |
- tableam_display | tbl_heap_psql | table | regress_display_role | permanent | 0 bytes |
- tableam_display | view_heap_psql | view | regress_display_role | permanent | 0 bytes |
+ List of relations
+ Schema | Name | Type | Owner | Persistence | Description
+-----------------+--------------------+-------------------+----------------------+-------------+-------------
+ tableam_display | mat_view_heap_psql | materialized view | regress_display_role | permanent |
+ tableam_display | tbl_heap | table | regress_display_role | permanent |
+ tableam_display | tbl_heap_psql | table | regress_display_role | permanent |
+ tableam_display | view_heap_psql | view | regress_display_role | permanent |
(4 rows)
RESET ROLE;
--
2.42.0
po 3. 6. 2024 v 16:10 odesílatel Justin Pryzby <pryzby@telsasoft.com>
napsal:
On Thu, May 30, 2024 at 10:59:06AM -0700, David Christensen wrote:
Hi Justin,
Thanks for the patch and the work on it. In reviewing the basic
feature, I think this is something that has utility and is worthwhile
at the high level.Thanks for looking.
A few more specific notes:
The pg_namespace_size() function can stand on its own, and probably
has some utility for the released Postgres versions.Are you suggesting to add the C function retroactively in back branches?
I don't think anybody would consider doing that.It wouldn't be used by anything internally, and any module that wanted
to use it would have to check the minor version, instead of just the
major version, which is wrong.I do think the psql implementation for the \dn+ or \dA+ commands
shouldn't need to use this same function; it's a straightforward
expansion of the SQL query that can be run in a way that will be
backwards-compatible with any connected postgres version, so no reason
to exclude this information for this cases. (This may have been in an
earlier revision of the patchset; I didn't check everything.)I think you're suggesting to write the query in SQL rather than in C.
But I did that in the first version of the patch, and the response was
that maybe in the future someone would want to add permission checks
that would compromize the ability to get correct results from SQL, so
then I presented the functionality writen in C.I recommend that reviewers try to read the existing communication on the
thread, otherwise we end up going back and forth about the same things.I think the \dX++ command versions add code complexity without a real
need for it.If you view this as a way to "show schema sizes", then you're right,
there's no need. But I don't want this patch to necessary further
embrace the idea that it's okay for "plus commands to be slow and show
nonportable results". If there were a consensus that it'd be fine in a
plus command, I would be okay with that, though.
I think showing size in \dX+ command is consistent with any other +
commands and the introduction ++ variant is inconsistent and not too
intuitive.
So I personally vote just for \dX+ without the introduction ++ command. Any
time, in this case we can introduce ++ in future when we see some
performance problems.
Show quoted text
We have precedence with \l(+) to show permissions on the
basic display and size on the extended display, and I think this is
sufficient in this case here.You also have the precedence that \db doesn't show the ACL, and you
can't get it without also computing the sizes. That's 1) inconsistent
with \l and 2) pretty inconvenient for someone who wants to show the
ACL (as mentioned in the first message on this thread).0001-Add-pg_am_size-pg_namespace_size.patch
- fine, but needs rebase to workI suggest reviewers to consider sending a rebased patch, optionally with
any proposed changes in a separate patch.0002-psql-add-convenience-commands-dA-and-dn.patch
- split into just + variant; remove \l++
- make the \dn show permission and \dn+ show size0003-f-convert-the-other-verbose-to-int-too.patch
- unneeded
0004-Move-the-double-plus-Size-columns-to-the-right.patch
- unneededYou say they're unneeded, but what I've been hoping for is a committer
interested enough to at least suggest whether to run with 001, 001+002,
001+002+003, or 001+002+003+004. They're intentionally presented as
such.I've also thought about submitting a patch specifically dedicated to
"moving size out of + and into ++". I find the idea compelling, for the
reasons I wrote in the the patch description. That'd be like presenting
003+004 first.I'm opened to changing the behavior or the implementation. But changing
the patch as I've presented it based on one suggestion I think will lead
to incoherent code trashing. I need to hear a wider agreement.--
Justin
On Mon, Jun 3, 2024 at 9:10 AM Justin Pryzby <pryzby@telsasoft.com> wrote:
On Thu, May 30, 2024 at 10:59:06AM -0700, David Christensen wrote:
Hi Justin,
Thanks for the patch and the work on it. In reviewing the basic
feature, I think this is something that has utility and is worthwhile
at the high level.Thanks for looking.
A few more specific notes:
The pg_namespace_size() function can stand on its own, and probably
has some utility for the released Postgres versions.Are you suggesting to add the C function retroactively in back branches?
I don't think anybody would consider doing that.It wouldn't be used by anything internally, and any module that wanted
to use it would have to check the minor version, instead of just the
major version, which is wrong.
Ah, I meant once released it would be useful going forward, but
re-reading it can see the ambiguity. No, definitely not suggesting
adding to back branches.
I do think the psql implementation for the \dn+ or \dA+ commands
shouldn't need to use this same function; it's a straightforward
expansion of the SQL query that can be run in a way that will be
backwards-compatible with any connected postgres version, so no reason
to exclude this information for this cases. (This may have been in an
earlier revision of the patchset; I didn't check everything.)I think you're suggesting to write the query in SQL rather than in C.
Yes.
But I did that in the first version of the patch, and the response was
that maybe in the future someone would want to add permission checks
that would compromize the ability to get correct results from SQL, so
then I presented the functionality writen in C.I recommend that reviewers try to read the existing communication on the
thread, otherwise we end up going back and forth about the same things.
Yes, I reviewed the whole thread, just not all of the patch contents.
I'd agree that suggestion flapping is not useful, but just presenting
my take on this at this time (as well as several others in the Patch
Review workshop at PGConf.dev, which is where this one got revived).
I think the \dX++ command versions add code complexity without a real
need for it.If you view this as a way to "show schema sizes", then you're right,
there's no need. But I don't want this patch to necessary further
embrace the idea that it's okay for "plus commands to be slow and show
nonportable results". If there were a consensus that it'd be fine in a
plus command, I would be okay with that, though.
I think this is a separate discussion in terms of introducing
verbosity levels and not needed at this point for this feature.
Certainly revamping all inconsistencies with the psql command
interfaces is out of scope, just thinking about which one we'd want to
model going forward and providing an opinion there (for what it's
worth... :D)
We have precedence with \l(+) to show permissions on the
basic display and size on the extended display, and I think this is
sufficient in this case here.You also have the precedence that \db doesn't show the ACL, and you
can't get it without also computing the sizes. That's 1) inconsistent
with \l and 2) pretty inconvenient for someone who wants to show the
ACL (as mentioned in the first message on this thread).
I can't speak to this one, just think that adding more command options
adds to the overall complexity so probably to be avoided unless we
can't.
0001-Add-pg_am_size-pg_namespace_size.patch
- fine, but needs rebase to workI suggest reviewers to consider sending a rebased patch, optionally with
any proposed changes in a separate patch.
Sure, if you don't have time to do this; agree with your later remarks
that consensus is important before moving forward, so same applies
here.
0002-psql-add-convenience-commands-dA-and-dn.patch
- split into just + variant; remove \l++
- make the \dn show permission and \dn+ show size0003-f-convert-the-other-verbose-to-int-too.patch
- unneeded
0004-Move-the-double-plus-Size-columns-to-the-right.patch
- unneededYou say they're unneeded, but what I've been hoping for is a committer
interested enough to at least suggest whether to run with 001, 001+002,
001+002+003, or 001+002+003+004. They're intentionally presented as
such.I've also thought about submitting a patch specifically dedicated to
"moving size out of + and into ++". I find the idea compelling, for the
reasons I wrote in the the patch description. That'd be like presenting
003+004 first.I'm opened to changing the behavior or the implementation. But changing
the patch as I've presented it based on one suggestion I think will lead
to incoherent code trashing. I need to hear a wider agreement.
Agreed that some sort of consensus is important.