Rebased
>From 4d88986706e334e2dccc6f576139342c102033f8 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From c8db22278993a2456563df0a6f30c6dadbf6f059 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From 8e35b070f37fec54445d40c0b152aef111ba3931 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From 5b09d2d3d97d840af3718e6005f1f2a65648b93d Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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