From a670c24c382693c4f75e99c9292b2ed0f0d40a72 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 11 Jul 2016 12:35:03 -0400 Subject: [PATCH] Improve output of psql's \df+ command. Add display of proparallel (parallel-safety) when the server is >= 9.6, and display of proacl (access privileges) for all server versions. Minor tweak of column ordering to keep related columns together. Michael Paquier Discussion: --- doc/src/sgml/ref/psql-ref.sgml | 13 ++++---- src/bin/psql/describe.c | 54 ++++++++++++++++++++++++++-------- 2 files changed, 48 insertions(+), 19 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index aeffd63960..ee525f5833 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1367,9 +1367,9 @@ testdb=> - Lists functions, together with their arguments, return types, and - function types, which are classified as agg (aggregate), - normal, trigger, or window. + Lists functions, together with their result data types, argument data + types, and function types, which are classified as agg + (aggregate), normal, trigger, or window. To display only functions of specific type(s), add the corresponding letters a, n, t, or w to the command. @@ -1380,14 +1380,15 @@ testdb=> objects are shown; supply a pattern or the S modifier to include system objects. If the form \df+ is used, additional information - about each function is shown, including security classification, - volatility, owner, language, source code and description. + about each function is shown, including volatility, + parallel safety, owner, security classification, access privileges, + language, source code and description. To look up functions taking arguments or returning values of a specific - type, use your pager's search capability to scroll through the + data type, use your pager's search capability to scroll through the \df output. diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c index 2cdc5acf30..27be10215b 100644 --- a/src/bin/psql/describe.c +++ b/src/bin/psql/describe.c @@ -298,7 +298,10 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool PQExpBufferData buf; PGresult *res; printQueryOpt myopt = pset.popt; - static const bool translate_columns[] = {false, false, false, false, true, true, true, false, false, false, false}; + static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, false, false, false, false}; + + /* 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+")) { @@ -410,28 +413,45 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool gettext_noop("Type")); if (verbose) + { appendPQExpBuffer(&buf, - ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"" ",\n CASE\n" " WHEN p.provolatile = 'i' THEN '%s'\n" " WHEN p.provolatile = 's' THEN '%s'\n" " WHEN p.provolatile = 'v' THEN '%s'\n" - " END as \"%s\"" - ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\",\n" - " l.lanname as \"%s\",\n" - " p.prosrc as \"%s\",\n" - " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"", - gettext_noop("definer"), - gettext_noop("invoker"), - gettext_noop("Security"), + " END as \"%s\"", gettext_noop("immutable"), gettext_noop("stable"), gettext_noop("volatile"), - gettext_noop("Volatility"), + gettext_noop("Volatility")); + if (pset.sversion >= 90600) + appendPQExpBuffer(&buf, + ",\n CASE\n" + " WHEN p.proparallel = 'r' THEN '%s'\n" + " WHEN p.proparallel = 's' THEN '%s'\n" + " WHEN p.proparallel = 'u' THEN '%s'\n" + " END as \"%s\"", + gettext_noop("restricted"), + gettext_noop("safe"), + gettext_noop("unsafe"), + gettext_noop("Parallel")); + appendPQExpBuffer(&buf, + ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\"" + ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"", gettext_noop("Owner"), + gettext_noop("definer"), + gettext_noop("invoker"), + gettext_noop("Security")); + appendPQExpBufferStr(&buf, ",\n "); + printACLColumn(&buf, "p.proacl"); + appendPQExpBuffer(&buf, + ",\n l.lanname as \"%s\"" + ",\n p.prosrc as \"%s\"" + ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"", gettext_noop("Language"), gettext_noop("Source code"), gettext_noop("Description")); + } appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_proc p" @@ -530,8 +550,16 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool myopt.nullPrint = NULL; myopt.title = _("List of functions"); myopt.translate_header = true; - myopt.translate_columns = translate_columns; - myopt.n_translate_columns = lengthof(translate_columns); + if (pset.sversion >= 90600) + { + myopt.translate_columns = translate_columns; + myopt.n_translate_columns = lengthof(translate_columns); + } + else + { + myopt.translate_columns = translate_columns_pre_96; + myopt.n_translate_columns = lengthof(translate_columns_pre_96); + } printQuery(res, &myopt, pset.queryFout, false, pset.logfile);