Please find attached a patch to enable more intuitive titles when using
psql and doing the following actions:
\dt \di \dv \dm \ds \dE
In other words, everything in listTables()
We still default to "List or relations", but if we know that the user has
requested exactly one specific type of relation, we use that instead. So
instead of
greg=# \dv
List of relations
Schema | Name | Type | Owner
--------+-------------------------+------+-------
public | pg_stat_statements | view | greg
public | pg_stat_statements_info | view | greg
we get:
greg=# \dv
List of views
Schema | Name | Type | Owner
--------+-------------------------+------+-------
public | pg_stat_statements | view | greg
public | pg_stat_statements_info | view | greg
(2 rows)
The same applies for "misses" as well:
greg=# \di
Did not find any indexes.
greg=# \di foo*
Did not find any indexes named "foo*".
I thought about keeping that last one as singular, as it is replacing "Did
not find any relation named", but not only does it make more sense as a
plural given that wildcards can produce multiple relations, it makes the
code cleaner. :)
Inspired by a recent thread[0] over in pgsql-bugs entitled "Bug in psql".
(while not a bug, it is certainly a welcome enhancement, IMHO).
Cheers,
Greg
[0]
https://www.postgresql.org/message-id/CADrHaBEVSYwemoJWtry2%2B82KHy9tZirH2PVfi-uD96R5J8FCsw%40mail.gmail.com
From eaf1097eb0ac02d2ab093e4e4261d0a15adf8ac2 Mon Sep 17 00:00:00 2001
From: Greg Sabino Mullane <[email protected]>
Date: Mon, 3 Feb 2025 12:19:14 -0500
Subject: [PATCH] Show more intuitive titles for psql commands \dt \di \dv \dm
\ds and \dE
This applies to the modified versions as well e.g. \dt+ \dtS+
Rather than say "List of relations", if someone has entered in a \di, we say "List of indexes"
Per complaint on the bugs list on Jan 29, 2025 from [email protected]
---
src/bin/psql/describe.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index aa4363b200..19366be2c8 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -4012,9 +4012,11 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
bool showForeign = strchr(tabtypes, 'E') != NULL;
PQExpBufferData buf;
+ PQExpBufferData title;
PGresult *res;
printQueryOpt myopt = pset.popt;
int cols_so_far;
+ char *item_type;
bool translate_columns[] = {false, false, true, false, false, false, false, false, false};
/* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */
@@ -4161,6 +4163,15 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
if (!res)
return false;
+ item_type = psprintf("%s",
+ (strspn(tabtypes, "tS+") == strlen(tabtypes)) ? "tables" :
+ (strspn(tabtypes, "iS+") == strlen(tabtypes)) ? "indexes" :
+ (strspn(tabtypes, "vS+") == strlen(tabtypes)) ? "views" :
+ (strspn(tabtypes, "mS+") == strlen(tabtypes)) ? "materialized view" :
+ (strspn(tabtypes, "sS+") == strlen(tabtypes)) ? "sequences" :
+ (strspn(tabtypes, "ES+") == strlen(tabtypes)) ? "foreign tables" :
+ "relations");
+
/*
* Most functions in this file are content to print an empty table when
* there are no matching objects. We intentionally deviate from that
@@ -4169,14 +4180,16 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
if (PQntuples(res) == 0 && !pset.quiet)
{
if (pattern)
- pg_log_error("Did not find any relation named \"%s\".",
- pattern);
+ pg_log_error("Did not find any %s named \"%s\".", item_type, pattern);
else
- pg_log_error("Did not find any relations.");
+ pg_log_error("Did not find any %s.", item_type);
}
else
{
- myopt.title = _("List of relations");
+ initPQExpBuffer(&title);
+ printfPQExpBuffer(&title, _("List of %s"), item_type);
+
+ myopt.title = title.data;
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
myopt.n_translate_columns = lengthof(translate_columns);
--
2.30.2