From b2678efd43f17db7dfa04e0ca076ea01275cd9bc Mon Sep 17 00:00:00 2001 From: Stephen Frost Date: Tue, 7 Mar 2017 09:31:52 -0500 Subject: [PATCH] psql: Add \gx command 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 | 12 ++++++++++++ src/bin/psql/command.c | 9 +++++++-- src/bin/psql/common.c | 7 +++++++ src/bin/psql/help.c | 1 + src/bin/psql/settings.h | 1 + src/bin/psql/tab-complete.c | 11 ++++++----- src/test/regress/expected/psql.out | 23 +++++++++++++++++++++++ src/test/regress/sql/psql.sql | 7 +++++++ 8 files changed, 64 insertions(+), 7 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index ae58708aae..2a9c412020 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1890,6 +1890,18 @@ Tue Oct 26 21:40:57 CEST 1999 + + \gx [ filename ] + \gx [ |command ] + + + \gx is equivalent to \g, but + forces expanded output mode for this query. See \x. + + + + + \gexec diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index a52adc8186..07efc27a69 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -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; } diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 5349c39411..1aa56ab3a2 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -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) { diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 91cf0be46a..ba14df0344 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -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")); diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index 195f5a1184..70ff1812c8 100644 --- a/src/bin/psql/settings.h +++ b/src/bin/psql/settings.h @@ -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 */ diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 4a65ff5b62..121a492e6d 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -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 */ diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 026a4f0c83..eb7f197b12 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -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 diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index d823d11b95..8f8e17a87c 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -21,6 +21,13 @@ \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_