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: <CAB7nPqTR3Vu3xKOZOYqSm-+bSZV0kqgeGAXD6w5GLbkbfd5Q6w@mail.gmail.com>
This commit is contained in:
Tom Lane 2016-07-11 12:35:03 -04:00
parent 740bf396a1
commit a670c24c38
2 changed files with 48 additions and 19 deletions

View File

@ -1367,9 +1367,9 @@ testdb=&gt;
<listitem>
<para>
Lists functions, together with their arguments, return types, and
function types, which are classified as <quote>agg</> (aggregate),
<quote>normal</>, <quote>trigger</>, or <quote>window</>.
Lists functions, together with their result data types, argument data
types, and function types, which are classified as <quote>agg</>
(aggregate), <quote>normal</>, <quote>trigger</>, or <quote>window</>.
To display only functions
of specific type(s), add the corresponding letters <literal>a</>,
<literal>n</>, <literal>t</>, or <literal>w</> to the command.
@ -1380,14 +1380,15 @@ testdb=&gt;
objects are shown; supply a pattern or the <literal>S</literal>
modifier to include system objects.
If the form <literal>\df+</literal> 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.
</para>
<tip>
<para>
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
<literal>\df</> output.
</para>
</tip>

View File

@ -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);