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
>From a1d33780e4c61a7bdb64ee6ab5c248e1175a3efd Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From d736a7ba55eeebe797f6811413bfc47545fb61e4 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From ec7b0104a4d32e231e1fe6be24b6d53c32247337 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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
>From 9fad0b322f7e6e60b8b0dbad68d8bc34a470da01 Mon Sep 17 00:00:00 2001
From: Justin Pryzby <[email protected]>
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