Skip to content

Commit a3027e1

Browse files
committed
Allow psql's \df and \do commands to specify argument types.
When dealing with overloaded function or operator names, having to look through a long list of matches is tedious. Let's extend these commands to allow specification of (input) argument types to let such results be trimmed down. Each additional argument is treated the same as the pattern argument of \dT and matched against the appropriate argument's type name. While at it, fix \dT (and these new options) to recognize the usual notation of "foo[]" for "the array type over foo", and to handle the special abbreviations allowed by the backend grammar, such as "int" for "integer". Greg Sabino Mullane, revised rather significantly by me Discussion: https://postgr.es/m/CAKAnmmLF9Hhu02N+s7uAyLc5J1xZReg72HQUoiKhNiJV3_jACQ@mail.gmail.com
1 parent f57a2f5 commit a3027e1

File tree

8 files changed

+374
-30
lines changed

8 files changed

+374
-30
lines changed

doc/src/sgml/ref/psql-ref.sgml

+30-10
Original file line numberDiff line numberDiff line change
@@ -1567,7 +1567,7 @@ testdb=>
15671567

15681568

15691569
<varlistentry>
1570-
<term><literal>\df[anptwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
1570+
<term><literal>\df[anptwS+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> [ <replaceable class="parameter">arg_pattern</replaceable> ... ] ]</literal></term>
15711571

15721572
<listitem>
15731573
<para>
@@ -1580,6 +1580,11 @@ testdb=&gt;
15801580
If <replaceable
15811581
class="parameter">pattern</replaceable> is specified, only
15821582
functions whose names match the pattern are shown.
1583+
Any additional arguments are type-name patterns, which are matched
1584+
to the type names of the first, second, and so on arguments of the
1585+
function. (Matching functions can have more arguments than what
1586+
you specify. To prevent that, write a dash <literal>-</literal> as
1587+
the last <replaceable class="parameter">arg_pattern</replaceable>.)
15831588
By default, only user-created
15841589
objects are shown; supply a pattern or the <literal>S</literal>
15851590
modifier to include system objects.
@@ -1589,14 +1594,6 @@ testdb=&gt;
15891594
language, source code and description.
15901595
</para>
15911596

1592-
<tip>
1593-
<para>
1594-
To look up functions taking arguments or returning values of a specific
1595-
data type, use your pager's search capability to scroll through the
1596-
<literal>\df</literal> output.
1597-
</para>
1598-
</tip>
1599-
16001597
</listitem>
16011598
</varlistentry>
16021599

@@ -1721,12 +1718,19 @@ testdb=&gt;
17211718

17221719

17231720
<varlistentry>
1724-
<term><literal>\do[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> ]</literal></term>
1721+
<term><literal>\do[S+] [ <link linkend="app-psql-patterns"><replaceable class="parameter">pattern</replaceable></link> [ <replaceable class="parameter">arg_pattern</replaceable> [ <replaceable class="parameter">arg_pattern</replaceable> ] ] ]</literal></term>
17251722
<listitem>
17261723
<para>
17271724
Lists operators with their operand and result types.
17281725
If <replaceable class="parameter">pattern</replaceable> is
17291726
specified, only operators whose names match the pattern are listed.
1727+
If one <replaceable class="parameter">arg_pattern</replaceable> is
1728+
specified, only prefix operators whose right argument's type name
1729+
matches that pattern are listed.
1730+
If two <replaceable class="parameter">arg_pattern</replaceable>s
1731+
are specified, only binary operators whose argument type names match
1732+
those patterns are listed. (Alternatively, write <literal>-</literal>
1733+
for the unused argument of a unary operator.)
17301734
By default, only user-created objects are shown; supply a
17311735
pattern or the <literal>S</literal> modifier to include system
17321736
objects.
@@ -4986,6 +4990,22 @@ second | four
49864990
</programlisting>
49874991
</para>
49884992

4993+
<para>
4994+
Here is an example of using the <command>\df</command> command to
4995+
find only functions with names matching <literal>int*pl</literal>
4996+
and whose second argument is of type <type>bigint</type>:
4997+
<programlisting>
4998+
testdb=&gt; <userinput>\df int*pl * bigint</userinput>
4999+
List of functions
5000+
Schema | Name | Result data type | Argument data types | Type
5001+
------------+---------+------------------+---------------------+------
5002+
pg_catalog | int28pl | bigint | smallint, bigint | func
5003+
pg_catalog | int48pl | bigint | integer, bigint | func
5004+
pg_catalog | int8pl | bigint | bigint, bigint | func
5005+
(3 rows)
5006+
</programlisting>
5007+
</para>
5008+
49895009
<para>
49905010
When suitable, query results can be shown in a crosstab representation
49915011
with the <command>\crosstabview</command> command:

src/bin/psql/command.c

+46-2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ static backslashResult exec_command_copyright(PsqlScanState scan_state, bool act
7272
static backslashResult exec_command_crosstabview(PsqlScanState scan_state, bool active_branch);
7373
static backslashResult exec_command_d(PsqlScanState scan_state, bool active_branch,
7474
const char *cmd);
75+
static bool exec_command_dfo(PsqlScanState scan_state, const char *cmd,
76+
const char *pattern,
77+
bool show_verbose, bool show_system);
7578
static backslashResult exec_command_edit(PsqlScanState scan_state, bool active_branch,
7679
PQExpBuffer query_buf, PQExpBuffer previous_buf);
7780
static backslashResult exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
@@ -790,7 +793,8 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
790793
case 'p':
791794
case 't':
792795
case 'w':
793-
success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
796+
success = exec_command_dfo(scan_state, cmd, pattern,
797+
show_verbose, show_system);
794798
break;
795799
default:
796800
status = PSQL_CMD_UNKNOWN;
@@ -811,7 +815,8 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
811815
success = listSchemas(pattern, show_verbose, show_system);
812816
break;
813817
case 'o':
814-
success = describeOperators(pattern, show_verbose, show_system);
818+
success = exec_command_dfo(scan_state, cmd, pattern,
819+
show_verbose, show_system);
815820
break;
816821
case 'O':
817822
success = listCollations(pattern, show_verbose, show_system);
@@ -951,6 +956,45 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
951956
return status;
952957
}
953958

959+
/* \df and \do; messy enough to split out of exec_command_d */
960+
static bool
961+
exec_command_dfo(PsqlScanState scan_state, const char *cmd,
962+
const char *pattern,
963+
bool show_verbose, bool show_system)
964+
{
965+
bool success;
966+
char *arg_patterns[FUNC_MAX_ARGS];
967+
int num_arg_patterns = 0;
968+
969+
/* Collect argument-type patterns too */
970+
if (pattern) /* otherwise it was just \df or \do */
971+
{
972+
char *ap;
973+
974+
while ((ap = psql_scan_slash_option(scan_state,
975+
OT_NORMAL, NULL, true)) != NULL)
976+
{
977+
arg_patterns[num_arg_patterns++] = ap;
978+
if (num_arg_patterns >= FUNC_MAX_ARGS)
979+
break; /* protect limited-size array */
980+
}
981+
}
982+
983+
if (cmd[1] == 'f')
984+
success = describeFunctions(&cmd[2], pattern,
985+
arg_patterns, num_arg_patterns,
986+
show_verbose, show_system);
987+
else
988+
success = describeOperators(pattern,
989+
arg_patterns, num_arg_patterns,
990+
show_verbose, show_system);
991+
992+
while (--num_arg_patterns >= 0)
993+
free(arg_patterns[num_arg_patterns]);
994+
995+
return success;
996+
}
997+
954998
/*
955999
* \e or \edit -- edit the current query buffer, or edit a file and
9561000
* make it the query buffer

0 commit comments

Comments
 (0)