]> granicus.if.org Git - postgresql/commitdiff
Add \warn command to psql.
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 5 Jul 2019 16:32:36 +0000 (12:32 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 5 Jul 2019 16:32:36 +0000 (12:32 -0400)
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

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/help.c
src/bin/psql/tab-complete.c
src/test/regress/expected/psql.out
src/test/regress/sql/psql.sql

index 3cd0a99d0793fdb203327007beecee72f13b11b0..7789fc6177699618bc256f21bffe3e529b12f086 100644 (file)
@@ -1863,22 +1863,22 @@ testdb=&gt;
         <term><literal>\echo <replaceable class="parameter">text</replaceable> [ ... ]</literal></term>
         <listitem>
         <para>
-        Prints the arguments to the standard output, separated by one
-        space and followed by a newline. This can be useful to
+        Prints the evaluated arguments to standard output, separated by
+        spaces and followed by a newline. This can be useful to
         intersperse information in the output of scripts. For example:
 <programlisting>
 =&gt; <userinput>\echo `date`</userinput>
 Tue Oct 26 21:40:57 CEST 1999
 </programlisting>
         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>
 
         <tip>
         <para>
         If you use the <command>\o</command> command to redirect your
         query output you might wish to use <command>\qecho</command>
-        instead of this command.
+        instead of this command.  See also <command>\warn</command>.
         </para>
         </tip>
         </listitem>
@@ -3226,6 +3226,18 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
       </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>
         <term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term>
         <listitem>
index 66e1aec011a34fae9c1e5a7f16f5b11d4ae775d6..c0a7a5566eb2a3c81a543c727591c2822f871fb5 100644 (file)
@@ -319,7 +319,8 @@ exec_command(const char *cmd,
                status = exec_command_ef_ev(scan_state, active_branch, query_buf, true);
        else if (strcmp(cmd, "ev") == 0)
                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);
        else if (strcmp(cmd, "elif") == 0)
                status = exec_command_elif(scan_state, cstack, query_buf);
@@ -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
 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)
                        fout = pset.queryFout;
+               else if (strcmp(cmd, "warn") == 0)
+                       fout = stderr;
                else
                        fout = stdout;
 
                while ((value = psql_scan_slash_option(scan_state,
                                                                                           OT_NORMAL, &quoted, false)))
                {
-                       if (!quoted && strcmp(value, "-n") == 0)
+                       if (first && !no_newline && !quoted && strcmp(value, "-n") == 0)
                                no_newline = true;
                        else
                        {
index 5fb1baadc574dd8524a97c41a123f53898690523..d9b982d3a0b71a0ba91b1f287747460d1ab09eff 100644 (file)
@@ -169,7 +169,7 @@ slashUsage(unsigned short int pager)
         * Use "psql --help=commands | wc" to count correctly.  It's okay to count
         * 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, _("  \\copyright             show PostgreSQL usage and distribution terms\n"));
@@ -206,11 +206,12 @@ slashUsage(unsigned short int pager)
 
        fprintf(output, _("Input/Output\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, _("  \\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, _("  \\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, _("Conditional\n"));
index 12355348c953f2fff6e9c15e34c57f15c6528fbc..9009b05e122d773ab8da370cae025a5b2d3d0b77 100644 (file)
@@ -1438,7 +1438,7 @@ psql_completion(const char *text, int start, int end)
                "\\t", "\\T", "\\timing",
                "\\unset",
                "\\x",
-               "\\w", "\\watch",
+               "\\w", "\\warn", "\\watch",
                "\\z",
                "\\!", "\\?",
                NULL
index 4bcf0cc5dfd578a31ea476f4fba0521ba57b82e4..9021c808dcfe086aea9d995ae67b5a3c9e871084 100644 (file)
@@ -4180,6 +4180,25 @@ drop table psql_serial_tab;
 \pset format aligned
 \pset expanded off
 \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
 \if true
   select 'okay';
index 26f436ae4036b8520a5d8261916c3f4b05b4625e..cefe41bdc2e997d244faefb33c61f4dc59c70209 100644 (file)
@@ -771,6 +771,22 @@ drop table psql_serial_tab;
 \pset expanded off
 \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
 
 \if true