]> granicus.if.org Git - postgresql/commitdiff
Add agg/normal/trigger/window flags for psql \df and in \df output.
authorBruce Momjian <bruce@momjian.us>
Tue, 21 Apr 2009 15:49:06 +0000 (15:49 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 21 Apr 2009 15:49:06 +0000 (15:49 +0000)
David Fetter

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/describe.c
src/bin/psql/describe.h
src/bin/psql/help.c
src/test/regress/expected/polymorphism.out

index c5c7fc7e81b8a6cb531cd88d4d629640d2b9742d..44d34c251ac04a537de5f4e67df306808147bca5 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.223 2009/04/08 22:29:30 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.224 2009/04/21 15:49:06 momjian Exp $
 PostgreSQL documentation
 -->
 
@@ -1039,18 +1039,22 @@ testdb=&gt;
 
       <varlistentry>
         <term><literal>\df[S+] [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
+        <term><literal>\df[antw][S+] [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
 
         <listitem>
         <para>
-        Lists available functions, together with their argument and
-        return types. If <replaceable
-        class="parameter">pattern</replaceable>
-        is specified, only functions whose names match the pattern are shown.
-        If the form <literal>\df+</literal> is used, additional information about
-        each function, including volatility, language, source code and description, is shown.
-        By default, only user-created objects are shown;  supply a
-        pattern or the <literal>S</literal> modifier to include system
-        objects.
+        Lists available functions, together with their arguments,
+        return types, and their function types: 'agg' (aggregate),
+        'normal', 'trigger', and 'window'.  To display only functions
+        of a specific type, use the corresponding letters <literal>a</>,
+        <literal>n</>, <literal>t</>, or <literal>w</>.  If <replaceable
+        class="parameter">pattern</replaceable> is specified, only
+        functions whose names match the pattern are shown.  If the
+        form <literal>\df+</literal> is used, additional information
+        about each function, including volatility, language, source
+        code and description, is shown.  By default, only user-created
+        objects are shown;  supply a pattern or the <literal>S</literal>
+        modifier to include system objects.
         </para>
 
         <note>
@@ -1064,7 +1068,6 @@ testdb=&gt;
         </listitem>
       </varlistentry>
 
-
       <varlistentry>
         <term><literal>\dF[+] [ <replaceable class="parameter">pattern</replaceable> ]</literal></term>
         <listitem>
index b92f68848b0ffa715efba0ca097d48ff29567706..f27c0bc60b9e596a58a34ca9175c8aa4ed0690e2 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.204 2009/03/25 13:07:26 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.205 2009/04/21 15:49:06 momjian Exp $
  */
 #include "postgres_fe.h"
 #include "command.h"
@@ -365,8 +365,22 @@ exec_command(const char *cmd,
                        case 'D':
                                success = listDomains(pattern, show_system);
                                break;
-                       case 'f':
-                               success = describeFunctions(pattern, show_verbose, show_system);
+                       case 'f':                       /* function subsystem */
+                               switch (cmd[2])
+                               {
+                                       case '\0':
+                                       case '+':
+                                       case 'S':
+                                       case 'a':
+                                       case 'n':
+                                       case 't':
+                                       case 'w':
+                                               success =  describeFunctions(&cmd[2], pattern, show_verbose, show_system);
+                                               break;
+                                       default:
+                                               status = PSQL_CMD_UNKNOWN;
+                                               break;
+                               }
                                break;
                        case 'g':
                                /* no longer distinct from \du */
index 83858f327d733426c040d40a6a393a31d3667f82..355a35d92ae5162ec9ca7d8c374158f03d6e4aea 100644 (file)
@@ -8,7 +8,7 @@
  *
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.208 2009/04/08 22:29:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.209 2009/04/21 15:49:06 momjian Exp $
  */
 #include "postgres_fe.h"
 
@@ -183,15 +183,43 @@ describeTablespaces(const char *pattern, bool verbose)
 
 
 /* \df
- * Takes an optional regexp to select particular functions
+ * Takes an optional regexp to select particular functions.
+ *
+ * As with \d, you can specify the kinds of functions you want:
+ *
+ * a for aggregates
+ * n for normal
+ * t for trigger
+ * w for window
+ *
+ * and you can mix and match these in any order.
  */
 bool
-describeFunctions(const char *pattern, bool verbose, bool showSystem)
+describeFunctions(const char *functypes, const char *pattern, bool verbose, bool showSystem)
 {
+       bool                    showAggregate = strchr(functypes, 'a') != NULL;
+       bool                    showNormal = strchr(functypes, 'n') != NULL;
+       bool                    showTrigger = strchr(functypes, 't') != NULL;
+       bool                    showWindow = strchr(functypes, 'w') != NULL;
+
        PQExpBufferData buf;
        PGresult   *res;
        printQueryOpt myopt = pset.popt;
 
+       if (showWindow && pset.sversion < 80400)
+       {
+               fprintf(stderr, _("\\df does not take a \"w\" decorator in %d.%d.\n"),
+                               pset.sversion / 10000, (pset.sversion / 100) % 100);
+               return true;
+       }
+
+       if (!showAggregate && !showNormal && !showTrigger && !showWindow)
+       {
+               showAggregate = showNormal = showTrigger = true;
+               if (pset.sversion >= 80400)
+                       showWindow = true;
+       }
+
        initPQExpBuffer(&buf);
 
        printfPQExpBuffer(&buf,
@@ -203,9 +231,21 @@ describeFunctions(const char *pattern, bool verbose, bool showSystem)
     if (pset.sversion >= 80400)
                appendPQExpBuffer(&buf,
                                                  "  pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n"
-                                                 "  pg_catalog.pg_get_function_arguments(p.oid) as \"%s\"",
+                                                 "  pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n"
+                                                 " CASE\n"
+                                                 "  WHEN p.proisagg THEN '%s'\n"
+                                                 "  WHEN p.proiswindow THEN '%s'\n"
+                                                 "  WHEN pg_catalog.pg_get_function_result(p.oid) = 'trigger' THEN '%s'\n"
+                                                 "  ELSE '%s'\n"
+                                                 "END as \"%s\"",
                                                  gettext_noop("Result data type"),
-                                                 gettext_noop("Argument data types"));
+                                                         gettext_noop("Argument data types"),
+                                                         /* translator: "agg" is short for "aggregate" */
+                                                         gettext_noop("agg"),
+                                                         gettext_noop("window"),
+                                                         gettext_noop("trigger"),
+                                                         gettext_noop("normal"),
+                                                         gettext_noop("Type"));
     else if (pset.sversion >= 80100)
                appendPQExpBuffer(&buf,
                                          "  CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
@@ -238,16 +278,36 @@ describeFunctions(const char *pattern, bool verbose, bool showSystem)
                                          "      FROM\n"
                                          "        pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
                                          "    ), ', ')\n"
+                                         "  END AS \"%s\",\n"
+                                         "  CASE\n"
+                                         "    WHEN p.proisagg THEN '%s'\n"
+                                         "    WHEN 'trigger' = pg_catalog.format_type(p.prorettype, NULL) THEN '%s'\n"
+                                         "    ELSE '%s'\n"
                                          "  END AS \"%s\"",
                                                  gettext_noop("Result data type"),
-                                                 gettext_noop("Argument data types"));
+                                                 gettext_noop("Argument data types"),
+                                                 /* translator: "agg" is short for "aggregate" */
+                                                 gettext_noop("agg"),
+                                                 gettext_noop("trigger"),
+                                                 gettext_noop("normal"),
+                                                 gettext_noop("Type"));
        else
                appendPQExpBuffer(&buf,
                                          "  CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
                                  "  pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
-                                         "  pg_catalog.oidvectortypes(p.proargtypes) as \"%s\"",
+                                         "  pg_catalog.oidvectortypes(p.proargtypes) as \"%s\",\n"
+                                         "  CASE\n"
+                                         "    WHEN p.proisagg THEN '%s'\n"
+                                         "    WHEN 'trigger' = pg_catalog.format_type(p.prorettype, NULL) THEN '%s'\n"
+                                         "    ELSE '%s'\n"
+                                         "  END AS \"%s\"",
                                                  gettext_noop("Result data type"),
-                                                 gettext_noop("Argument data types"));
+                                                 gettext_noop("Argument data types"),
+                                                 /* translator: "agg" is short for "aggregate" */
+                                                 gettext_noop("agg"),
+                                                 gettext_noop("trigger"),
+                                                 gettext_noop("normal"),
+                                                 gettext_noop("Type"));
 
        if (verbose)
                appendPQExpBuffer(&buf,
@@ -274,16 +334,63 @@ describeFunctions(const char *pattern, bool verbose, bool showSystem)
                appendPQExpBuffer(&buf,
                                                  "     LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
 
-       appendPQExpBuffer(&buf, "WHERE NOT p.proisagg\n");
+       processSQLNamePattern(pset.db, &buf, pattern, false, true,
+                                                 "n.nspname", "p.proname", NULL,
+                                                 "pg_catalog.pg_function_is_visible(p.oid)");
+
+       if (showNormal && showAggregate && showTrigger && showWindow)
+               /* Do nothing */;
+       else if (showNormal)
+       {
+               if (!showWindow && pset.sversion >= 80400)
+                               appendPQExpBuffer(&buf, "      AND NOT p.proiswindow\n");
+               if (!showAggregate)
+                       appendPQExpBuffer(&buf, "      AND NOT p.proisagg\n");
+               if (!showTrigger)
+               {
+                       if (pset.sversion >= 80400)
+                               appendPQExpBuffer(&buf,
+                                                                 "      AND pg_catalog.pg_get_function_result(p.oid) <> 'trigger'\n");
+                       else
+                               appendPQExpBuffer(&buf,
+                                                                 "      AND pg_catalog.format_type(p.prorettype, NULL) <> 'trigger'\n");
+               }
+       }
+       else
+       {
+               bool    needs_or = false;
+
+               appendPQExpBuffer(&buf, "      AND (\n         ");
+               if (showAggregate)
+               {
+                       appendPQExpBuffer(&buf,"p.proisagg\n");
+                       needs_or = true;
+               }
+               if (showTrigger)
+               {
+                       if (needs_or)
+                               appendPQExpBuffer(&buf, "      OR ");
+                       if (pset.sversion >= 80400)
+                               appendPQExpBuffer(&buf,
+                                                                 "pg_catalog.pg_get_function_result(p.oid) = 'trigger'\n");
+                       else
+                               appendPQExpBuffer(&buf,
+                                                                 "'trigger' <> pg_catalog.format_type(p.prorettype, NULL)\n");
+                       needs_or = true;
+               }
+               if (showWindow)
+               {
+                       if (needs_or)
+                               appendPQExpBuffer(&buf, "      OR ");
+                       appendPQExpBuffer(&buf, "p.proiswindow\n");
+               }
+               appendPQExpBuffer(&buf, "      )\n");
+       }
 
        if (!showSystem && !pattern)
                appendPQExpBuffer(&buf, "      AND n.nspname <> 'pg_catalog'\n"
                                                                "      AND n.nspname <> 'information_schema'\n");
 
-       processSQLNamePattern(pset.db, &buf, pattern, true, false,
-                                                 "n.nspname", "p.proname", NULL,
-                                                 "pg_catalog.pg_function_is_visible(p.oid)");
-
        appendPQExpBuffer(&buf, "ORDER BY 1, 2, 4;");
 
        res = PSQLexec(buf.data, false);
index 95c70a842de35aa1c96b951a7d5c7b1e2e930fc8..769ee9e975dd3dd2053383a8cf59739740833503 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.39 2009/01/20 02:13:42 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/describe.h,v 1.40 2009/04/21 15:49:06 momjian Exp $
  */
 #ifndef DESCRIBE_H
 #define DESCRIBE_H
@@ -15,8 +15,8 @@ extern bool describeAggregates(const char *pattern, bool verbose, bool showSyste
 /* \db */
 extern bool describeTablespaces(const char *pattern, bool verbose);
 
-/* \df */
-extern bool describeFunctions(const char *pattern, bool verbose, bool showSystem);
+/* \df, \dfa, \dfn, \dft, \dfw, etc. */
+extern bool describeFunctions(const char *functypes, const char *pattern, bool verbose, bool showSystem);
 
 /* \dT */
 extern bool describeTypes(const char *pattern, bool verbose, bool showSystem);
index a0ca95c3b730bcf27d62b66f8beb43046af5ea91..a3da9e2ca0261d79df9e7d720af0de6588126e71 100644 (file)
@@ -3,7 +3,7 @@
  *
  * Copyright (c) 2000-2009, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.146 2009/04/11 14:11:21 petere Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/help.c,v 1.147 2009/04/21 15:49:06 momjian Exp $
  */
 #include "postgres_fe.h"
 
@@ -196,7 +196,7 @@ slashUsage(unsigned short int pager)
        fprintf(output, _("  (options: S = show system objects, + = additional detail)\n"));
        fprintf(output, _("  \\d[S+]                 list tables, views, and sequences\n"));
        fprintf(output, _("  \\d[S+]  NAME           describe table, view, sequence, or index\n"));
-       fprintf(output, _("  \\da[S]  [PATTERN]      list aggregate functions\n"));
+       fprintf(output, _("  \\da[+]  [PATTERN]      list aggregates\n"));
        fprintf(output, _("  \\db[+]  [PATTERN]      list tablespaces\n"));
        fprintf(output, _("  \\dc[S]  [PATTERN]      list conversions\n"));
        fprintf(output, _("  \\dC     [PATTERN]      list casts\n"));
@@ -206,6 +206,7 @@ slashUsage(unsigned short int pager)
        fprintf(output, _("  \\deu[+] [PATTERN]      list user mappings\n"));
        fprintf(output, _("  \\dew[+] [PATTERN]      list foreign-data wrappers\n"));
        fprintf(output, _("  \\df[S+] [PATTERN]      list functions\n"));
+       fprintf(output, _("  \\df[antwS+] [PATTERN]  list only agg/normal/trigger/window functions\n"));
        fprintf(output, _("  \\dF[+]  [PATTERN]      list text search configurations\n"));
        fprintf(output, _("  \\dFd[+] [PATTERN]      list text search dictionaries\n"));
        fprintf(output, _("  \\dFp[+] [PATTERN]      list text search parsers\n"));
index 7648ad610bce91a6838692a444712ce6774ef32f..77f693c2b14ba19a1c645b1a2984edb491aacb65 100644 (file)
@@ -838,9 +838,9 @@ select dfunc();
 -- verify it lists properly
 \df dfunc
                                        List of functions
- Schema | Name  | Result data type |                    Argument data types                    
---------+-------+------------------+-----------------------------------------------------------
- public | dfunc | integer          | a integer DEFAULT 1, OUT sum integer, b integer DEFAULT 2
+ Schema | Name  | Result data type |                    Argument data types                    |  Type  
+--------+-------+------------------+-----------------------------------------------------------+--------
+ public | dfunc | integer          | a integer DEFAULT 1, OUT sum integer, b integer DEFAULT 2 | normal
 (1 row)
 
 drop function dfunc(int, int);
@@ -1006,9 +1006,9 @@ ERROR:  cannot remove parameter defaults from existing function
 HINT:  Use DROP FUNCTION first.
 \df dfunc
                                   List of functions
- Schema | Name  | Result data type |               Argument data types               
---------+-------+------------------+-------------------------------------------------
- public | dfunc | integer          | VARIADIC a integer[] DEFAULT ARRAY[]::integer[]
+ Schema | Name  | Result data type |               Argument data types               |  Type  
+--------+-------+------------------+-------------------------------------------------+--------
+ public | dfunc | integer          | VARIADIC a integer[] DEFAULT ARRAY[]::integer[] | normal
 (1 row)
 
 drop function dfunc(a variadic int[]);