mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	psql: Add option for procedures to \df
This commit is contained in:
		@@ -1423,16 +1423,16 @@ testdb=>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      <varlistentry>
 | 
					      <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>
 | 
					        <listitem>
 | 
				
			||||||
        <para>
 | 
					        <para>
 | 
				
			||||||
        Lists functions, together with their result data types, argument data
 | 
					        Lists functions, together with their result data types, argument data
 | 
				
			||||||
        types, and function types, which are classified as <quote>agg</quote>
 | 
					        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
 | 
					        To display only functions
 | 
				
			||||||
        of specific type(s), add the corresponding letters <literal>a</literal>,
 | 
					        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
 | 
					        If <replaceable
 | 
				
			||||||
        class="parameter">pattern</replaceable> is specified, only
 | 
					        class="parameter">pattern</replaceable> is specified, only
 | 
				
			||||||
        functions whose names match the pattern are shown.
 | 
					        functions whose names match the pattern are shown.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -754,6 +754,7 @@ exec_command_d(PsqlScanState scan_state, bool active_branch, const char *cmd)
 | 
				
			|||||||
					case 'S':
 | 
										case 'S':
 | 
				
			||||||
					case 'a':
 | 
										case 'a':
 | 
				
			||||||
					case 'n':
 | 
										case 'n':
 | 
				
			||||||
 | 
										case 'p':
 | 
				
			||||||
					case 't':
 | 
										case 't':
 | 
				
			||||||
					case 'w':
 | 
										case 'w':
 | 
				
			||||||
						success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
 | 
											success = describeFunctions(&cmd[2], pattern, show_verbose, show_system);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -312,6 +312,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	bool		showAggregate = strchr(functypes, 'a') != NULL;
 | 
						bool		showAggregate = strchr(functypes, 'a') != NULL;
 | 
				
			||||||
	bool		showNormal = strchr(functypes, 'n') != NULL;
 | 
						bool		showNormal = strchr(functypes, 'n') != NULL;
 | 
				
			||||||
 | 
						bool		showProcedure = strchr(functypes, 'p') != NULL;
 | 
				
			||||||
	bool		showTrigger = strchr(functypes, 't') != NULL;
 | 
						bool		showTrigger = strchr(functypes, 't') != NULL;
 | 
				
			||||||
	bool		showWindow = strchr(functypes, 'w') != NULL;
 | 
						bool		showWindow = strchr(functypes, 'w') != NULL;
 | 
				
			||||||
	bool		have_where;
 | 
						bool		have_where;
 | 
				
			||||||
@@ -323,9 +324,20 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 | 
				
			|||||||
	/* No "Parallel" column before 9.6 */
 | 
						/* 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};
 | 
						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;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -333,15 +345,18 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		char		sverbuf[32];
 | 
							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,
 | 
									   formatPGVersionNumber(pset.sversion, false,
 | 
				
			||||||
										 sverbuf, sizeof(sverbuf)));
 | 
															 sverbuf, sizeof(sverbuf)));
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!showAggregate && !showNormal && !showTrigger && !showWindow)
 | 
						if (!showAggregate && !showNormal && !showProcedure && !showTrigger && !showWindow)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		showAggregate = showNormal = showTrigger = true;
 | 
							showAggregate = showNormal = showTrigger = true;
 | 
				
			||||||
 | 
							if (pset.sversion >= 110000)
 | 
				
			||||||
 | 
								showProcedure = true;
 | 
				
			||||||
		if (pset.sversion >= 80400)
 | 
							if (pset.sversion >= 80400)
 | 
				
			||||||
			showWindow = true;
 | 
								showWindow = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -505,7 +520,7 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 | 
				
			|||||||
	have_where = false;
 | 
						have_where = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* filter by function type, if requested */
 | 
						/* filter by function type, if requested */
 | 
				
			||||||
	if (showNormal && showAggregate && showTrigger && showWindow)
 | 
						if (showNormal && showAggregate && showProcedure && showTrigger && showWindow)
 | 
				
			||||||
		 /* Do nothing */ ;
 | 
							 /* Do nothing */ ;
 | 
				
			||||||
	else if (showNormal)
 | 
						else if (showNormal)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
@@ -523,6 +538,17 @@ describeFunctions(const char *functypes, const char *pattern, bool verbose, bool
 | 
				
			|||||||
			else
 | 
								else
 | 
				
			||||||
				appendPQExpBufferStr(&buf, "NOT p.proisagg\n");
 | 
									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 (!showTrigger)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (have_where)
 | 
								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");
 | 
													 "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n");
 | 
				
			||||||
			needs_or = true;
 | 
								needs_or = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							if (showProcedure)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (needs_or)
 | 
				
			||||||
 | 
									appendPQExpBufferStr(&buf, "       OR ");
 | 
				
			||||||
 | 
								appendPQExpBufferStr(&buf, "p.prokind = 'p'\n");
 | 
				
			||||||
 | 
								needs_or = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (showWindow)
 | 
							if (showWindow)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (needs_or)
 | 
								if (needs_or)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -235,7 +235,7 @@ slashUsage(unsigned short int pager)
 | 
				
			|||||||
	fprintf(output, _("  \\des[+] [PATTERN]      list foreign servers\n"));
 | 
						fprintf(output, _("  \\des[+] [PATTERN]      list foreign servers\n"));
 | 
				
			||||||
	fprintf(output, _("  \\deu[+] [PATTERN]      list user mappings\n"));
 | 
						fprintf(output, _("  \\deu[+] [PATTERN]      list user mappings\n"));
 | 
				
			||||||
	fprintf(output, _("  \\dew[+] [PATTERN]      list foreign-data wrappers\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, _("  \\dF[+]  [PATTERN]      list text search configurations\n"));
 | 
				
			||||||
	fprintf(output, _("  \\dFd[+] [PATTERN]      list text search dictionaries\n"));
 | 
						fprintf(output, _("  \\dFd[+] [PATTERN]      list text search dictionaries\n"));
 | 
				
			||||||
	fprintf(output, _("  \\dFp[+] [PATTERN]      list text search parsers\n"));
 | 
						fprintf(output, _("  \\dFp[+] [PATTERN]      list text search parsers\n"));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,14 +15,6 @@ LANGUAGE SQL
 | 
				
			|||||||
AS $$
 | 
					AS $$
 | 
				
			||||||
INSERT INTO cp_test VALUES (1, x);
 | 
					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
 | 
					\df ptest1
 | 
				
			||||||
                        List of functions
 | 
					                        List of functions
 | 
				
			||||||
 Schema |  Name  | Result data type | Argument data types | Type 
 | 
					 Schema |  Name  | Result data type | Argument data types | Type 
 | 
				
			||||||
@@ -41,6 +33,30 @@ SELECT pg_get_functiondef('ptest1'::regproc);
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
(1 row)
 | 
					(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";
 | 
					SELECT * FROM cp_test ORDER BY b COLLATE "C";
 | 
				
			||||||
 a |   b   
 | 
					 a |   b   
 | 
				
			||||||
---+-------
 | 
					---+-------
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,14 +11,20 @@ AS $$
 | 
				
			|||||||
INSERT INTO cp_test VALUES (1, x);
 | 
					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
 | 
					SELECT ptest1('x');  -- error
 | 
				
			||||||
CALL ptest1('a');  -- ok
 | 
					CALL ptest1('a');  -- ok
 | 
				
			||||||
CALL ptest1('xy' || 'zzy');  -- ok, constant-folded arg
 | 
					CALL ptest1('xy' || 'zzy');  -- ok, constant-folded arg
 | 
				
			||||||
CALL ptest1(substring(random()::numeric(20,15)::text, 1, 1));  -- ok, volatile 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";
 | 
					SELECT * FROM cp_test ORDER BY b COLLATE "C";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user