Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ckrzs-0002QX-2B for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Mar 2017 12:44:16 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1ckrzr-0003O0-K0 for pgsql-hackers@arkaria.postgresql.org; Mon, 06 Mar 2017 12:44:15 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1ckryK-0000i6-JA for pgsql-hackers@postgresql.org; Mon, 06 Mar 2017 12:42:40 +0000 Received: from gauss.credativ.com ([93.94.130.89]) by makus.postgresql.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84_2) (envelope-from ) id 1ckryH-0007l2-5c for pgsql-hackers@postgresql.org; Mon, 06 Mar 2017 12:42:39 +0000 Received: from gauss.credativ.com (localhost [127.0.0.1]) by gauss.credativ.com (Postfix) with ESMTP id D0CAF1E1986; Mon, 6 Mar 2017 13:42:33 +0100 (CET) Received: from msg.credativ.de (fw-front.credativ.com [62.154.226.94]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: cbe@gauss.credativ.com) by gauss.credativ.com (Postfix) with ESMTPSA id B65F21E18B2; Mon, 6 Mar 2017 13:42:33 +0100 (CET) Date: Mon, 6 Mar 2017 13:42:33 +0100 From: Christoph Berg To: Daniel Verite Cc: David Fetter , PostgreSQL Hackers Subject: Re: One-shot expanded output in psql using \gx Message-ID: <20170306124233.c64cylgyot7ipeix@msg.credativ.de> Mail-Followup-To: Christoph Berg , Daniel Verite , David Fetter , PostgreSQL Hackers References: <20170208145240.corb3zkmypn6snj2@msg.credativ.de> <4d84079e-325b-48c5-83e6-bb54bb567bb1@manitou-mail.org> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="nvgko7iighz26qmn" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <4d84079e-325b-48c5-83e6-bb54bb567bb1@manitou-mail.org> User-Agent: NeoMutt/20170113 (1.7.2) X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org --nvgko7iighz26qmn Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Re: Daniel Verite 2017-03-03 <4d84079e-325b-48c5-83e6-bb54bb567bb1@manitou-mail.org> > - tab-completion: works but the list in tab-complete.c:backslash_commands[] > is sorted alphabetically so "\\gx" should come after "\\gset" Good catch, it was still in that place from when it was named \G. In the \? output I left it directly after \g because the help text starts with "as \g ..." and it is IMHO more closely related to \g than \gexec and \gset which differ more in functionality. > unsigned short int expanded; /* expanded/vertical output (if supported > by > * output format); 0=no, 1=yes, 2=auto */ > Although there is still code that puts true/false in this variable > (probably because it was a bool before?), I assume that for new > code, assigning 0/1/2 should be preferred. Right. I had seen both being used and went with "true", but "1" is better style. Both fixed, thanks for the review! Version 3 attached. Christoph -- Senior Berater, Tel.: +49 2166 9901 187 credativ GmbH, HRB Mönchengladbach 12080, USt-ID-Nummer: DE204566209 Trompeterallee 108, 41189 Mönchengladbach Geschäftsführung: Dr. Michael Meskes, Jörg Folz, Sascha Heuer pgp fingerprint: 5C48 FE61 57F4 9179 5970 87C6 4C5A 6BAB 12D2 A7AE --nvgko7iighz26qmn Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="expanded-mode-gx-3.patch" diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml new file mode 100644 index ae58708..e0302ea *** a/doc/src/sgml/ref/psql-ref.sgml --- b/doc/src/sgml/ref/psql-ref.sgml *************** Tue Oct 26 21:40:57 CEST 1999 *** 1891,1896 **** --- 1891,1908 ---- + \gx [ filename ] + \gx [ |command ] + + + \gx is equivalent to \g, but + forces expanded output mode for this query. + + + + + + \gexec diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c new file mode 100644 index a52adc8..07efc27 *** a/src/bin/psql/command.c --- b/src/bin/psql/command.c *************** exec_command(const char *cmd, *** 906,913 **** free(fname); } ! /* \g [filename] -- send query, optionally with output to file/pipe */ ! else if (strcmp(cmd, "g") == 0) { char *fname = psql_scan_slash_option(scan_state, OT_FILEPIPE, NULL, false); --- 906,916 ---- free(fname); } ! /* ! * \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); *************** exec_command(const char *cmd, *** 920,925 **** --- 923,930 ---- 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 new file mode 100644 index 5349c39..1aa56ab *** a/src/bin/psql/common.c --- b/src/bin/psql/common.c *************** PrintQueryTuples(const PGresult *results *** 770,775 **** --- 770,779 ---- { 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) { *************** sendquery_cleanup: *** 1410,1415 **** --- 1414,1422 ---- 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 new file mode 100644 index 91cf0be..c390f87 *** a/src/bin/psql/help.c --- b/src/bin/psql/help.c *************** slashUsage(unsigned short int pager) *** 173,178 **** --- 173,179 ---- 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 force expanded output\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 new file mode 100644 index 195f5a1..70ff181 *** a/src/bin/psql/settings.h --- b/src/bin/psql/settings.h *************** typedef struct _psqlSettings *** 91,96 **** --- 91,97 ---- 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 new file mode 100644 index 4a65ff5..186d07e *** a/src/bin/psql/tab-complete.c --- b/src/bin/psql/tab-complete.c *************** psql_completion(const char *text, int st *** 1375,1381 **** "\\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", --- 1375,1381 ---- "\\dm", "\\dn", "\\do", "\\dO", "\\dp", "\\drds", "\\ds", "\\dS", "\\dt", "\\dT", "\\dv", "\\du", "\\dx", "\\dy", "\\e", "\\echo", "\\ef", "\\encoding", "\\errverbose", "\\ev", ! "\\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", diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out new file mode 100644 index 026a4f0..eb7f197 *** a/src/test/regress/expected/psql.out --- b/src/test/regress/expected/psql.out *************** on *** 28,33 **** --- 28,56 ---- \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 new file mode 100644 index d823d11..8f8e17a *** a/src/test/regress/sql/psql.sql --- b/src/test/regress/sql/psql.sql *************** *** 21,26 **** --- 21,33 ---- \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_ --nvgko7iighz26qmn Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers --nvgko7iighz26qmn--