]> granicus.if.org Git - postgresql/commitdiff
psql: Add \gx command
authorStephen Frost <sfrost@snowman.net>
Tue, 7 Mar 2017 14:31:52 +0000 (09:31 -0500)
committerStephen Frost <sfrost@snowman.net>
Tue, 7 Mar 2017 14:31:52 +0000 (09:31 -0500)
It can often be useful to use expanded mode output (\x) for just a
single query.  Introduce a \gx which acts exactly like \g except that it
will force expanded output mode for that one \gx call.  This is simpler
than having to use \x as a toggle and also means that the user doesn't
have to worry about the current state of the expanded variable, or
resetting it later, to ensure a given query is always returned in
expanded mode.

Primairly Christoph's patch, though I did tweak the documentation and help
text a bit, and re-indented the tab completion section.

Author: Christoph Berg
Reviewed By: Daniel Verite
Discussion: https://postgr.es/m/20170127132737.6skslelaf4txs6iw%40msg.credativ.de

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

index ae58708aaeafbc1db1c561d7b355c09f91567cfe..2a9c4120205a0c4633a52fa5d81354110a28369f 100644 (file)
@@ -1890,6 +1890,18 @@ Tue Oct 26 21:40:57 CEST 1999
       </varlistentry>
 
 
+      <varlistentry>
+        <term><literal>\gx [ <replaceable class="parameter">filename</replaceable> ]</literal></term>
+        <term><literal>\gx [ |<replaceable class="parameter">command</replaceable> ]</literal></term>
+        <listitem>
+        <para>
+        <literal>\gx</literal> is equivalent to <literal>\g</literal>, but
+        forces expanded output mode for this query.  See <literal>\x</literal>.
+        </para>
+        </listitem>
+      </varlistentry>
+
+
       <varlistentry>
         <term><literal>\gexec</literal></term>
 
index a52adc8186f1cf44a18b02e1282a6eeaf1a765d6..07efc27a697cd78a9427e2d6a0f240414e676df4 100644 (file)
@@ -906,8 +906,11 @@ exec_command(const char *cmd,
                free(fname);
        }
 
-       /* \g [filename] -- send query, optionally with output to file/pipe */
-       else if (strcmp(cmd, "g") == 0)
+       /*
+        * \g [filename] -- send query, optionally with output to file/pipe
+        * \gx [filename] -- same as \g, with expanded mode forced
+        */
+       else if (strcmp(cmd, "g") == 0 || strcmp(cmd, "gx") == 0)
        {
                char       *fname = psql_scan_slash_option(scan_state,
                                                                                                   OT_FILEPIPE, NULL, false);
@@ -920,6 +923,8 @@ exec_command(const char *cmd,
                        pset.gfname = pg_strdup(fname);
                }
                free(fname);
+               if (strcmp(cmd, "gx") == 0)
+                       pset.g_expanded = true;
                status = PSQL_CMD_SEND;
        }
 
index 5349c394115db2f5bd73f83bdf2d493eecdd0e0d..1aa56ab3a2fd403373513202008292f1d879823e 100644 (file)
@@ -770,6 +770,10 @@ PrintQueryTuples(const PGresult *results)
 {
        printQueryOpt my_popt = pset.popt;
 
+       /* one-shot expanded output requested via \gx */
+       if (pset.g_expanded)
+               my_popt.topt.expanded = 1;
+
        /* write output to \g argument, if any */
        if (pset.gfname)
        {
@@ -1410,6 +1414,9 @@ sendquery_cleanup:
                pset.gfname = NULL;
        }
 
+       /* reset \gx's expanded-mode flag */
+       pset.g_expanded = false;
+
        /* reset \gset trigger */
        if (pset.gset_prefix)
        {
index 91cf0be46a6537e599ca1c1a5332bfdb822471ad..ba14df0344df735eb17283fc0877ce7b58d2cec5 100644 (file)
@@ -173,6 +173,7 @@ slashUsage(unsigned short int pager)
        fprintf(output, _("  \\copyright             show PostgreSQL usage and distribution terms\n"));
        fprintf(output, _("  \\errverbose            show most recent error message at maximum verbosity\n"));
        fprintf(output, _("  \\g [FILE] or ;         execute query (and send results to file or |pipe)\n"));
+       fprintf(output, _("  \\gx [FILE]             as \\g, but forces expanded output mode\n"));
        fprintf(output, _("  \\gexec                 execute query, then execute each value in its result\n"));
        fprintf(output, _("  \\gset [PREFIX]         execute query and store results in psql variables\n"));
        fprintf(output, _("  \\q                     quit psql\n"));
index 195f5a118438b4a2e8d02df5ed38c56e60bd827a..70ff1812c8fc67f1dc42da15b532c298464f01cc 100644 (file)
@@ -91,6 +91,7 @@ typedef struct _psqlSettings
        printQueryOpt popt;
 
        char       *gfname;                     /* one-shot file output argument for \g */
+       bool            g_expanded;             /* one-shot expanded output requested via \gx */
        char       *gset_prefix;        /* one-shot prefix argument for \gset */
        bool            gexec_flag;             /* one-shot flag to execute query's results */
        bool            crosstab_flag;  /* one-shot request to crosstab results */
index 4a65ff5b6200169a502006fadbb3a9cdb66110eb..121a492e6d8517ce1df4dfe4faef79131344e16f 100644 (file)
@@ -1375,11 +1375,12 @@ psql_completion(const char *text, int start, int end)
                "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS",
                "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy",
                "\\e", "\\echo", "\\ef", "\\encoding", "\\errverbose", "\\ev",
-               "\\f", "\\g", "\\gexec", "\\gset", "\\h", "\\help", "\\H", "\\i", "\\ir", "\\l",
-               "\\lo_import", "\\lo_export", "\\lo_list", "\\lo_unlink",
-               "\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q", "\\qecho", "\\r",
-               "\\s", "\\set", "\\setenv", "\\sf", "\\sv", "\\t", "\\T",
-               "\\timing", "\\unset", "\\x", "\\w", "\\watch", "\\z", "\\!", NULL
+               "\\f", "\\g", "\\gexec", "\\gset", "\\gx", "\\h", "\\help", "\\H",
+               "\\i", "\\ir", "\\l", "\\lo_import", "\\lo_export", "\\lo_list",
+               "\\lo_unlink", "\\o", "\\p", "\\password", "\\prompt", "\\pset", "\\q",
+               "\\qecho", "\\r", "\\s", "\\set", "\\setenv", "\\sf", "\\sv", "\\t",
+               "\\T", "\\timing", "\\unset", "\\x", "\\w", "\\watch", "\\z", "\\!",
+               NULL
        };
 
        (void) end;                                     /* "end" is not used */
index 026a4f0c83351ff2e397d0ce6c0b2feb8b6b2321..eb7f197b122040c99683f231c97196ec92780127 100644 (file)
@@ -28,6 +28,29 @@ on
 \unset ON_ERROR_ROLLBACK
 \echo :ON_ERROR_ROLLBACK
 off
+-- \g and \gx
+SELECT 1 as one, 2 as two \g
+ one | two 
+-----+-----
+   1 |   2
+(1 row)
+
+\gx
+-[ RECORD 1 ]
+one | 1
+two | 2
+
+SELECT 3 as three, 4 as four \gx
+-[ RECORD 1 ]
+three | 3
+four  | 4
+
+\g
+ three | four 
+-------+------
+     3 |    4
+(1 row)
+
 -- \gset
 select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_
 \echo :pref01_test01 :pref01_test02 :pref01_test03
index d823d11b958b96a60195ceedcd06aba1f3f8711b..8f8e17a87cd94537eaeba9860203077eb0df6bcb 100644 (file)
 \unset ON_ERROR_ROLLBACK
 \echo :ON_ERROR_ROLLBACK
 
+-- \g and \gx
+
+SELECT 1 as one, 2 as two \g
+\gx
+SELECT 3 as three, 4 as four \gx
+\g
+
 -- \gset
 
 select 10 as test01, 20 as test02, 'Hello' as test03 \gset pref01_