diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index c5c7fc7e81..44d34c251a 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -1,5 +1,5 @@
@@ -1039,18 +1039,22 @@ testdb=>
\df[S+] [ pattern ]
+ \df[antw][S+] [ pattern ]
- Lists available functions, together with their argument and
- return types. If pattern
- is specified, only functions whose names match the pattern are shown.
- If the form \df+ 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 S 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 a>,
+ n>, t>, or w>. If pattern is specified, only
+ functions whose names match the pattern are shown. If the
+ form \df+ 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 S
+ modifier to include system objects.
@@ -1064,7 +1068,6 @@ testdb=>
-
\dF[+] [ pattern ]
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index b92f68848b..f27c0bc60b 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -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 */
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 83858f327d..355a35d92a 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -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);
diff --git a/src/bin/psql/describe.h b/src/bin/psql/describe.h
index 95c70a842d..769ee9e975 100644
--- a/src/bin/psql/describe.h
+++ b/src/bin/psql/describe.h
@@ -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);
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index a0ca95c3b7..a3da9e2ca0 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -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"));
diff --git a/src/test/regress/expected/polymorphism.out b/src/test/regress/expected/polymorphism.out
index 7648ad610b..77f693c2b1 100644
--- a/src/test/regress/expected/polymorphism.out
+++ b/src/test/regress/expected/polymorphism.out
@@ -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[]);