Show more-intuitive titles for psql commands \dt, \di, etc.
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Feb 2025 17:45:58 +0000 (12:45 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 5 Feb 2025 17:45:58 +0000 (12:45 -0500)
If exactly one relation type is requested in a command of the \dtisv
family, say "tables", "indexes", etc instead of "relations".  This
should cover the majority of actual uses, without creating a huge
number of new translatable strings.  The error messages for no
matching relations are adjusted as well.

In passing, invent "pg_log_error_internal()" to be used for frontend
error messages that don't seem to need translation, analogously to
errmsg_internal() in the backend.  The implementation is a bit cheesy,
being just a macro to prevent xgettext from recognizing a trigger
keyword.  This won't avoid a useless gettext lookup cycle at runtime
--- but surely we don't care about an extra microsecond or two in
what's supposed to be a can't-happen case.  I (tgl) also made
"pg_fatal_internal()", though it's not used in this patch.

Author: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAKAnmm+7o93fQV-RFkGaN1QnP-0D4d3JTykD+cLueqjDMKdfag@mail.gmail.com

src/bin/psql/describe.c
src/include/common/logging.h
src/test/regress/expected/dependency.out
src/test/regress/expected/psql.out

index aa4363b200a8e28644cf53252efe12a6f2e7c052..0312de7dcb734876e15c04749ce10ec8f058d767 100644 (file)
@@ -4011,14 +4011,18 @@ listTables(const char *tabtypes, const char *pattern, bool verbose, bool showSys
    bool        showSeq = strchr(tabtypes, 's') != NULL;
    bool        showForeign = strchr(tabtypes, 'E') != NULL;
 
+   int         ntypes;
    PQExpBufferData buf;
    PGresult   *res;
    printQueryOpt myopt = pset.popt;
    int         cols_so_far;
    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) */
-   if (!(showTables || showIndexes || showViews || showMatViews || showSeq || showForeign))
+   /* Count the number of explicitly-requested relation types */
+   ntypes = showTables + showIndexes + showViews + showMatViews +
+       showSeq + showForeign;
+   /* If none, we default to \dtvmsE (but see also command.c) */
+   if (ntypes == 0)
        showTables = showViews = showMatViews = showSeq = showForeign = true;
 
    initPQExpBuffer(&buf);
@@ -4169,14 +4173,63 @@ 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);
+       {
+           if (ntypes != 1)
+               pg_log_error("Did not find any relations named \"%s\".",
+                            pattern);
+           else if (showTables)
+               pg_log_error("Did not find any tables named \"%s\".",
+                            pattern);
+           else if (showIndexes)
+               pg_log_error("Did not find any indexes named \"%s\".",
+                            pattern);
+           else if (showViews)
+               pg_log_error("Did not find any views named \"%s\".",
+                            pattern);
+           else if (showMatViews)
+               pg_log_error("Did not find any materialized views named \"%s\".",
+                            pattern);
+           else if (showSeq)
+               pg_log_error("Did not find any sequences named \"%s\".",
+                            pattern);
+           else if (showForeign)
+               pg_log_error("Did not find any foreign tables named \"%s\".",
+                            pattern);
+           else                /* should not get here */
+               pg_log_error_internal("Did not find any ??? named \"%s\".",
+                                     pattern);
+       }
        else
-           pg_log_error("Did not find any relations.");
+       {
+           if (ntypes != 1)
+               pg_log_error("Did not find any relations.");
+           else if (showTables)
+               pg_log_error("Did not find any tables.");
+           else if (showIndexes)
+               pg_log_error("Did not find any indexes.");
+           else if (showViews)
+               pg_log_error("Did not find any views.");
+           else if (showMatViews)
+               pg_log_error("Did not find any materialized views.");
+           else if (showSeq)
+               pg_log_error("Did not find any sequences.");
+           else if (showForeign)
+               pg_log_error("Did not find any foreign tables.");
+           else                /* should not get here */
+               pg_log_error_internal("Did not find any ??? relations.");
+       }
    }
    else
    {
-       myopt.title = _("List of relations");
+       myopt.title =
+           (ntypes != 1) ? _("List of relations") :
+           (showTables) ? _("List of tables") :
+           (showIndexes) ? _("List of indexes") :
+           (showViews) ? _("List of views") :
+           (showMatViews) ? _("List of materialized views") :
+           (showSeq) ? _("List of sequences") :
+           (showForeign) ? _("List of foreign tables") :
+           "List of ???";      /* should not get here */
        myopt.translate_header = true;
        myopt.translate_columns = translate_columns;
        myopt.n_translate_columns = lengthof(translate_columns);
index 5d8636f75c92ba4da49ff257af91790414b82153..81529ee8f2926ffbbcbd42ff557bb1719e792ca1 100644 (file)
@@ -153,4 +153,11 @@ void       pg_log_generic_v(enum pg_log_level level, enum pg_log_part part,
        exit(1); \
    } while(0)
 
+/*
+ * Use these variants for "can't happen" cases, if it seems translating their
+ * messages would be a waste of effort.
+ */
+#define pg_log_error_internal(...) pg_log_error(__VA_ARGS__)
+#define pg_fatal_internal(...) pg_fatal(__VA_ARGS__)
+
 #endif                         /* COMMON_LOGGING_H */
index 74d9ff2998d7ae8988ce9ed2884459fd6a428530..75a078ada9e15685c7cf76a7f4e7e11de136bc68 100644 (file)
@@ -116,7 +116,7 @@ FROM pg_type JOIN pg_class c ON typrelid = c.oid WHERE typname = 'deptest_t';
 RESET SESSION AUTHORIZATION;
 REASSIGN OWNED BY regress_dep_user1 TO regress_dep_user2;
 \dt deptest
-              List of relations
+                List of tables
  Schema |  Name   | Type  |       Owner       
 --------+---------+-------+-------------------
  public | deptest | table | regress_dep_user2
index e6f7b9013d97639052ebf8e17cfae5d4b82f95e6..f9db4032e1f1bf84efd935a51bd6661eeb8806c6 100644 (file)
@@ -3027,7 +3027,7 @@ Access method: heap
 (4 rows)
 
 \dt+
-                                                  List of relations
+                                                    List of tables
      Schema      |     Name      | Type  |        Owner         | Persistence | Access method |  Size   | Description 
 -----------------+---------------+-------+----------------------+-------------+---------------+---------+-------------
  tableam_display | tbl_heap      | table | regress_display_role | permanent   | heap          | 0 bytes | 
@@ -3035,7 +3035,7 @@ Access method: heap
 (2 rows)
 
 \dm+
-                                                           List of relations
+                                                      List of materialized views
      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 | 
@@ -3043,7 +3043,7 @@ Access method: heap
 
 -- But not for views and sequences.
 \dv+
-                                          List of relations
+                                            List of views
      Schema      |      Name      | Type |        Owner         | Persistence |  Size   | Description 
 -----------------+----------------+------+----------------------+-------------+---------+-------------
  tableam_display | view_heap_psql | view | regress_display_role | permanent   | 0 bytes | 
@@ -6244,7 +6244,7 @@ List of access methods
 (0 rows)
 
 \dt "no.such.table.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
@@ -6316,31 +6316,31 @@ List of access methods
 (0 rows)
 
 \di "no.such.index.relation"
-          List of relations
+           List of indexes
  Schema | Name | Type | Owner | Table 
 --------+------+------+-------+-------
 (0 rows)
 
 \dm "no.such.materialized.view"
-      List of relations
+  List of materialized views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \ds "no.such.relation"
-      List of relations
+      List of sequences
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dt "no.such.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dv "no.such.relation"
-      List of relations
+        List of views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
@@ -6474,7 +6474,7 @@ List of schemas
 \dA "no.such.schema"."no.such.access.method"
 improper qualified name (too many dotted names): "no.such.schema"."no.such.access.method"
 \dt "no.such.schema"."no.such.table.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
@@ -6526,31 +6526,31 @@ improper qualified name (too many dotted names): "no.such.schema"."no.such.table
 (0 rows)
 
 \di "no.such.schema"."no.such.index.relation"
-          List of relations
+           List of indexes
  Schema | Name | Type | Owner | Table 
 --------+------+------+-------+-------
 (0 rows)
 
 \dm "no.such.schema"."no.such.materialized.view"
-      List of relations
+  List of materialized views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \ds "no.such.schema"."no.such.relation"
-      List of relations
+      List of sequences
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dt "no.such.schema"."no.such.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dv "no.such.schema"."no.such.relation"
-      List of relations
+        List of views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
@@ -6641,7 +6641,7 @@ improper qualified name (too many dotted names): "no.such.schema"."no.such.insta
 improper qualified name (too many dotted names): "no.such.schema"."no.such.event.trigger"
 -- again, but with current database and dotted schema qualifications.
 \dt regression."no.such.schema"."no.such.table.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
@@ -6677,31 +6677,31 @@ improper qualified name (too many dotted names): "no.such.schema"."no.such.event
 (0 rows)
 
 \di regression."no.such.schema"."no.such.index.relation"
-          List of relations
+           List of indexes
  Schema | Name | Type | Owner | Table 
 --------+------+------+-------+-------
 (0 rows)
 
 \dm regression."no.such.schema"."no.such.materialized.view"
-      List of relations
+  List of materialized views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \ds regression."no.such.schema"."no.such.relation"
-      List of relations
+      List of sequences
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dt regression."no.such.schema"."no.such.relation"
-      List of relations
+        List of tables
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)
 
 \dv regression."no.such.schema"."no.such.relation"
-      List of relations
+        List of views
  Schema | Name | Type | Owner 
 --------+------+------+-------
 (0 rows)