Commit 02e95a50 authored by Tom Lane's avatar Tom Lane

Add \warn command to psql.

This is like \echo except that the text is sent to stderr not stdout.

In passing, fix a pre-existing bug in \echo and \qecho: per documentation
the -n switch should only be recognized when it is the first argument,
but actually any argument matching "-n" was treated as a switch.
(Should we back-patch that?)

David Fetter (bug fix by me), reviewed by Fabien Coelho

Discussion: https://postgr.es/m/20190421183115.GA4311@fetter.org
parent e8fdcacc
...@@ -1863,22 +1863,22 @@ testdb=> ...@@ -1863,22 +1863,22 @@ testdb=>
<term><literal>\echo <replaceable class="parameter">text</replaceable> [ ... ]</literal></term> <term><literal>\echo <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
<listitem> <listitem>
<para> <para>
Prints the arguments to the standard output, separated by one Prints the evaluated arguments to standard output, separated by
space and followed by a newline. This can be useful to spaces and followed by a newline. This can be useful to
intersperse information in the output of scripts. For example: intersperse information in the output of scripts. For example:
<programlisting> <programlisting>
=&gt; <userinput>\echo `date`</userinput> =&gt; <userinput>\echo `date`</userinput>
Tue Oct 26 21:40:57 CEST 1999 Tue Oct 26 21:40:57 CEST 1999
</programlisting> </programlisting>
If the first argument is an unquoted <literal>-n</literal> the trailing If the first argument is an unquoted <literal>-n</literal> the trailing
newline is not written. newline is not written (nor is the first argument).
</para> </para>
<tip> <tip>
<para> <para>
If you use the <command>\o</command> command to redirect your If you use the <command>\o</command> command to redirect your
query output you might wish to use <command>\qecho</command> query output you might wish to use <command>\qecho</command>
instead of this command. instead of this command. See also <command>\warn</command>.
</para> </para>
</tip> </tip>
</listitem> </listitem>
...@@ -3226,6 +3226,18 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput> ...@@ -3226,6 +3226,18 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
</varlistentry> </varlistentry>
<varlistentry>
<term><literal>\warn <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
<listitem>
<para>
This command is identical to <command>\echo</command> except
that the output will be written to <application>psql</application>'s
standard error channel, rather than standard output.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term> <term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term>
<listitem> <listitem>
......
...@@ -319,7 +319,8 @@ exec_command(const char *cmd, ...@@ -319,7 +319,8 @@ exec_command(const char *cmd,
status = exec_command_ef_ev(scan_state, active_branch, query_buf, true); status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
else if (strcmp(cmd, "ev") == 0) else if (strcmp(cmd, "ev") == 0)
status = exec_command_ef_ev(scan_state, active_branch, query_buf, false); status = exec_command_ef_ev(scan_state, active_branch, query_buf, false);
else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0) else if (strcmp(cmd, "echo") == 0 || strcmp(cmd, "qecho") == 0 ||
strcmp(cmd, "warn") == 0)
status = exec_command_echo(scan_state, active_branch, cmd); status = exec_command_echo(scan_state, active_branch, cmd);
else if (strcmp(cmd, "elif") == 0) else if (strcmp(cmd, "elif") == 0)
status = exec_command_elif(scan_state, cstack, query_buf); status = exec_command_elif(scan_state, cstack, query_buf);
...@@ -1114,7 +1115,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch, ...@@ -1114,7 +1115,7 @@ exec_command_ef_ev(PsqlScanState scan_state, bool active_branch,
} }
/* /*
* \echo and \qecho -- echo arguments to stdout or query output * \echo, \qecho, and \warn -- echo arguments to stdout, query output, or stderr
*/ */
static backslashResult static backslashResult
exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd) exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
...@@ -1129,13 +1130,15 @@ exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd) ...@@ -1129,13 +1130,15 @@ exec_command_echo(PsqlScanState scan_state, bool active_branch, const char *cmd)
if (strcmp(cmd, "qecho") == 0) if (strcmp(cmd, "qecho") == 0)
fout = pset.queryFout; fout = pset.queryFout;
else if (strcmp(cmd, "warn") == 0)
fout = stderr;
else else
fout = stdout; fout = stdout;
while ((value = psql_scan_slash_option(scan_state, while ((value = psql_scan_slash_option(scan_state,
OT_NORMAL, &quoted, false))) OT_NORMAL, &quoted, false)))
{ {
if (!quoted && strcmp(value, "-n") == 0) if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
no_newline = true; no_newline = true;
else else
{ {
......
...@@ -169,7 +169,7 @@ slashUsage(unsigned short int pager) ...@@ -169,7 +169,7 @@ slashUsage(unsigned short int pager)
* Use "psql --help=commands | wc" to count correctly. It's okay to count * Use "psql --help=commands | wc" to count correctly. It's okay to count
* the USE_READLINE line even in builds without that. * the USE_READLINE line even in builds without that.
*/ */
output = PageOutput(127, pager ? &(pset.popt.topt) : NULL); output = PageOutput(128, pager ? &(pset.popt.topt) : NULL);
fprintf(output, _("General\n")); fprintf(output, _("General\n"));
fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n")); fprintf(output, _(" \\copyright show PostgreSQL usage and distribution terms\n"));
...@@ -206,11 +206,12 @@ slashUsage(unsigned short int pager) ...@@ -206,11 +206,12 @@ slashUsage(unsigned short int pager)
fprintf(output, _("Input/Output\n")); fprintf(output, _("Input/Output\n"));
fprintf(output, _(" \\copy ... perform SQL COPY with data stream to the client host\n")); fprintf(output, _(" \\copy ... perform SQL COPY with data stream to the client host\n"));
fprintf(output, _(" \\echo [STRING] write string to standard output\n")); fprintf(output, _(" \\echo [-n] [STRING] write string to standard output (-n for no newline)\n"));
fprintf(output, _(" \\i FILE execute commands from file\n")); fprintf(output, _(" \\i FILE execute commands from file\n"));
fprintf(output, _(" \\ir FILE as \\i, but relative to location of current script\n")); fprintf(output, _(" \\ir FILE as \\i, but relative to location of current script\n"));
fprintf(output, _(" \\o [FILE] send all query results to file or |pipe\n")); fprintf(output, _(" \\o [FILE] send all query results to file or |pipe\n"));
fprintf(output, _(" \\qecho [STRING] write string to query output stream (see \\o)\n")); fprintf(output, _(" \\qecho [-n] [STRING] write string to \\o output stream (-n for no newline)\n"));
fprintf(output, _(" \\warn [-n] [STRING] write string to standard error (-n for no newline)\n"));
fprintf(output, "\n"); fprintf(output, "\n");
fprintf(output, _("Conditional\n")); fprintf(output, _("Conditional\n"));
......
...@@ -1438,7 +1438,7 @@ psql_completion(const char *text, int start, int end) ...@@ -1438,7 +1438,7 @@ psql_completion(const char *text, int start, int end)
"\\t", "\\T", "\\timing", "\\t", "\\T", "\\timing",
"\\unset", "\\unset",
"\\x", "\\x",
"\\w", "\\watch", "\\w", "\\warn", "\\watch",
"\\z", "\\z",
"\\!", "\\?", "\\!", "\\?",
NULL NULL
......
...@@ -4180,6 +4180,25 @@ drop table psql_serial_tab; ...@@ -4180,6 +4180,25 @@ drop table psql_serial_tab;
\pset format aligned \pset format aligned
\pset expanded off \pset expanded off
\pset border 1 \pset border 1
-- \echo and allied features
\echo this is a test
this is a test
\echo -n without newline
without newline\echo with -n newline
with -n newline
\echo '-n' with newline
-n with newline
\set foo bar
\echo foo = :foo
foo = bar
\qecho this is a test
this is a test
\qecho foo = :foo
foo = bar
\warn this is a test
this is a test
\warn foo = :foo
foo = bar
-- tests for \if ... \endif -- tests for \if ... \endif
\if true \if true
select 'okay'; select 'okay';
......
...@@ -771,6 +771,22 @@ drop table psql_serial_tab; ...@@ -771,6 +771,22 @@ drop table psql_serial_tab;
\pset expanded off \pset expanded off
\pset border 1 \pset border 1
-- \echo and allied features
\echo this is a test
\echo -n without newline
\echo with -n newline
\echo '-n' with newline
\set foo bar
\echo foo = :foo
\qecho this is a test
\qecho foo = :foo
\warn this is a test
\warn foo = :foo
-- tests for \if ... \endif -- tests for \if ... \endif
\if true \if true
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment