]> granicus.if.org Git - postgresql/commitdiff
psql: Add option for procedures to \df
authorPeter Eisentraut <peter_e@gmx.net>
Sat, 14 Jul 2018 10:17:49 +0000 (12:17 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Tue, 24 Jul 2018 09:38:53 +0000 (11:38 +0200)
doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/describe.c
src/bin/psql/help.c
src/test/regress/expected/create_procedure.out
src/test/regress/sql/create_procedure.sql

index b17039d60f9cfd4ac0bb68531c3ba4459b81a1d9..eb9d93a168e43dee67c1fcc8b64cee96f99ddf77 100644 (file)
@@ -1423,16 +1423,16 @@ testdb=&gt;
 
 
       <varlistentry>
-        <term><literal>\df[antwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
+        <term><literal>\df[anptwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
 
         <listitem>
         <para>
         Lists functions, together with their result data types, argument data
         types, and function types, which are classified as <quote>agg</quote>
-        (aggregate), <quote>normal</quote>, <quote>trigger</quote>, or <quote>window</quote>.
+        (aggregate), <quote>normal</quote>, <quote>procedure</quote>, <quote>trigger</quote>, or <quote>window</quote>.
         To display only functions
         of specific type(s), add the corresponding letters <literal>a</literal>,
-        <literal>n</literal>, <literal>t</literal>, or <literal>w</literal> to the command.
+        <literal>n</literal>, <literal>p</literal>, <literal>t</literal>, or <literal>w</literal> to the command.
         If <replaceable
         class="parameter">pattern</replaceable> is specified, only
         functions whose names match the pattern are shown.
index 4c85f43f09e7119405158156edbeba508ae83fbf..f82f361fd84a52a3a52110d6a91e0ace2de8e2d4 100644 (file)
@@ -754,6 +754,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
                                        case 'S':
                                        case 'a':
                                        case 'n':
+                                       case 'p':
                                        case 't':
                                        case 'w':
                                                success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
index c3bdf8555dbcfa9f53c6b3f68d60733bfdde941f..80d8338b96996bf23f3858710adcd892641a8260 100644 (file)
@@ -312,6 +312,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 {
        bool            showAggregate = strchr(functypes, 'a') != NULL;
        bool            showNormal = strchr(functypes, 'n') != NULL;
+       bool            showProcedure = strchr(functypes, 'p') != NULL;
        bool            showTrigger = strchr(functypes, 't') != NULL;
        bool            showWindow = strchr(functypes, 'w') != NULL;
        bool            have_where;
@@ -323,9 +324,20 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
        /* No "Parallel" column before 9.6 */
        static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, false, false, false, false};
 
-       if (strlen(functypes) != strspn(functypes, "antwS+"))
+       if (strlen(functypes) != strspn(functypes, "anptwS+"))
        {
-               psql_error("\\df only takes [antwS+] as options\n");
+               psql_error("\\df only takes [anptwS+] as options\n");
+               return true;
+       }
+
+       if (showProcedure && pset.sversion < 110000)
+       {
+               char            sverbuf[32];
+
+               psql_error("\\df does not take a \"%c\" option with server version %s\n",
+                                  'p',
+                                  formatPGVersionNumber(pset.sversion, false,
+                                                                                sverbuf, sizeof(sverbuf)));
                return true;
        }
 
@@ -333,15 +345,18 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
        {
                char            sverbuf[32];
 
-               psql_error("\\df does not take a \"w\" option with server version %s\n",
+               psql_error("\\df does not take a \"%c\" option with server version %s\n",
+                                  'w',
                                   formatPGVersionNumber(pset.sversion, false,
                                                                                 sverbuf, sizeof(sverbuf)));
                return true;
        }
 
-       if (!showAggregate && !showNormal && !showTrigger && !showWindow)
+       if (!showAggregate && !showNormal && !showProcedure && !showTrigger && !showWindow)
        {
                showAggregate = showNormal = showTrigger = true;
+               if (pset.sversion >= 110000)
+                       showProcedure = true;
                if (pset.sversion >= 80400)
                        showWindow = true;
        }
@@ -505,7 +520,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
        have_where = false;
 
        /* filter by function type, if requested */
-       if (showNormal && showAggregate && showTrigger && showWindow)
+       if (showNormal && showAggregate && showProcedure && showTrigger && showWindow)
                 /* Do nothing */ ;
        else if (showNormal)
        {
@@ -523,6 +538,17 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
                        else
                                appendPQExpBufferStr(&buf, "NOT p.proisagg\n");
                }
+               if (!showProcedure && pset.sversion >= 110000)
+               {
+                       if (have_where)
+                               appendPQExpBufferStr(&buf, "      AND ");
+                       else
+                       {
+                               appendPQExpBufferStr(&buf, "WHERE ");
+                               have_where = true;
+                       }
+                       appendPQExpBufferStr(&buf, "p.prokind <> 'p'\n");
+               }
                if (!showTrigger)
                {
                        if (have_where)
@@ -572,6 +598,13 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
                                                                 "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n");
                        needs_or = true;
                }
+               if (showProcedure)
+               {
+                       if (needs_or)
+                               appendPQExpBufferStr(&buf, "       OR ");
+                       appendPQExpBufferStr(&buf, "p.prokind = 'p'\n");
+                       needs_or = true;
+               }
                if (showWindow)
                {
                        if (needs_or)
index 702e742af4f3b000bd6446c72840fa0f15279553..316030d358a1e457b3ccddd3ae72835134b2cc60 100644 (file)
@@ -235,7 +235,7 @@ slashUsage(unsigned short int pager)
        fprintf(output, _("  \\des[+] [PATTERN]      list foreign servers\n"));
        fprintf(output, _("  \\deu[+] [PATTERN]      list user mappings\n"));
        fprintf(output, _("  \\dew[+] [PATTERN]      list foreign-data wrappers\n"));
-       fprintf(output, _("  \\df[antw][S+] [PATRN]  list [only agg/normal/trigger/window] functions\n"));
+       fprintf(output, _("  \\df[anptw][S+] [PATRN] list [only agg/normal/procedures/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 90e8f3c5ff0dc99f8d1106e5574e2f6635f98fb8..5b9b83839cfb4510135dfe7e821dac41b8cd3d1f 100644 (file)
@@ -15,14 +15,6 @@ LANGUAGE SQL
 AS $$
 INSERT INTO cp_test VALUES (1, x);
 $$;
-SELECT ptest1('x');  -- error
-ERROR:  ptest1(unknown) is a procedure
-LINE 1: SELECT ptest1('x');
-               ^
-HINT:  To call a procedure, use CALL.
-CALL ptest1('a');  -- ok
-CALL ptest1('xy' || 'zzy');  -- ok, constant-folded arg
-CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1));  -- ok, volatile arg
 \df ptest1
                         List of functions
  Schema |  Name  | Result data type | Argument data types | Type 
@@ -41,6 +33,30 @@ SELECT pg_get_functiondef('ptest1'::regproc);
  
 (1 row)
 
+-- show only normal functions
+\dfn public.*test*1
+                           List of functions
+ Schema |     Name     | Result data type | Argument data types | Type 
+--------+--------------+------------------+---------------------+------
+ public | cp_testfunc1 | integer          | a integer           | func
+(1 row)
+
+-- show only procedures
+\dfp public.*test*1
+                        List of functions
+ Schema |  Name  | Result data type | Argument data types | Type 
+--------+--------+------------------+---------------------+------
+ public | ptest1 |                  | x text              | proc
+(1 row)
+
+SELECT ptest1('x');  -- error
+ERROR:  ptest1(unknown) is a procedure
+LINE 1: SELECT ptest1('x');
+               ^
+HINT:  To call a procedure, use CALL.
+CALL ptest1('a');  -- ok
+CALL ptest1('xy' || 'zzy');  -- ok, constant-folded arg
+CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1));  -- ok, volatile arg
 SELECT * FROM cp_test ORDER BY b COLLATE "C";
  a |   b   
 ---+-------
index 0a9af8c906322e4b83150ebbe62751e6201e0252..b64293ed669416acab761ee90cdd3b25fff80e7d 100644 (file)
@@ -11,14 +11,20 @@ AS $$
 INSERT INTO cp_test VALUES (1, x);
 $$;
 
+\df ptest1
+SELECT pg_get_functiondef('ptest1'::regproc);
+
+-- show only normal functions
+\dfn public.*test*1
+
+-- show only procedures
+\dfp public.*test*1
+
 SELECT ptest1('x');  -- error
 CALL ptest1('a');  -- ok
 CALL ptest1('xy' || 'zzy');  -- ok, constant-folded arg
 CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1));  -- ok, volatile arg
 
-\df ptest1
-SELECT pg_get_functiondef('ptest1'::regproc);
-
 SELECT * FROM cp_test ORDER BY b COLLATE "C";