On lör, 2011-11-05 at 12:26 -0400, Noah Misch wrote: > On Sat, Nov 05, 2011 at 04:53:56PM +0200, Peter Eisentraut wrote: > > On fre, 2011-11-04 at 07:34 -0400, Noah Misch wrote: > > > For "\pset format wrapped", we only use $COLUMNS when the output is a > > > tty. I'm thinking it's best, although not terribly important, to > > > apply the same rule to this feature. > > > > I think it does work that way. There is only one place where the > > environment variable is queries, and it's used for both wrapped format > > and expanded auto format. > > You're correct; given output to a non-tty and no use of \pset columns, > output_columns always becomes zero. This makes wrapped format never wrap, but > it makes expanded auto mode always expand. Would it be more consistent to > never > expand when output_columns == 0? That is, make these give the same output: > > psql -X -P expanded=auto -c "select 'a' as a" > psql -X -P expanded=auto -c "select 'a' as a" | cat > > I just noticed: the help text for \x in slashUsage() will also need an update.
Here is an updated patch that addresses all the issues you pointed out.
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index d6941e0..01f57c4 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -1860,7 +1860,8 @@ lo_import 152801 <para> Sets the target width for the <literal>wrapped</> format, and also the width limit for determining whether output is wide enough to - require the pager. + require the pager or switch to the vertical display in expanded auto + mode. Zero (the default) causes the target width to be controlled by the environment variable <envar>COLUMNS</>, or the detected screen width if <envar>COLUMNS</> is not set. @@ -1876,15 +1877,19 @@ lo_import 152801 <term><literal>expanded</literal> (or <literal>x</literal>)</term> <listitem> <para> - If <replaceable class="parameter">value</replaceable> is specified - it must be either <literal>on</literal> or <literal>off</literal> - which will enable or disable expanded mode. If <replaceable - class="parameter">value</replaceable> is omitted the command toggles - between regular and expanded mode. - When expanded mode is enabled, query results - are displayed in two columns, with the column name on the left and - the data on the right. This mode is useful if the data wouldn't fit - on the screen in the normal <quote>horizontal</quote> mode. + If <replaceable class="parameter">value</replaceable> is specified it + must be either <literal>on</literal> or <literal>off</literal>, which + will enable or disable expanded mode, or <literal>auto</literal>. + If <replaceable class="parameter">value</replaceable> is omitted the + command toggles between the on and off settings. When expanded mode + is enabled, query results are displayed in two columns, with the + column name on the left and the data on the right. This mode is + useful if the data wouldn't fit on the screen in the + normal <quote>horizontal</quote> mode. In the auto setting, the + expanded mode is used whenever the query output is wider than the + screen, otherwise the regular mode is used. The auto setting is only + effective in the aligned and wrapped formats. In other formats, it + always behaves as if the expanded mode is off. </para> </listitem> </varlistentry> @@ -2326,10 +2331,10 @@ lo_import 152801 <varlistentry> - <term><literal>\x</literal></term> + <term><literal>\x [ <replaceable class="parameter">on</replaceable> | <replaceable class="parameter">off</replaceable> | <replaceable class="parameter">auto</replaceable> ]</literal></term> <listitem> <para> - Toggles expanded table formatting mode. As such it is equivalent to + Sets or toggles expanded table formatting mode. As such it is equivalent to <literal>\pset expanded</literal>. </para> </listitem> @@ -3197,7 +3202,8 @@ $endif <para> If <literal>\pset columns</> is zero, controls the width for the <literal>wrapped</> format and width for determining - if wide output requires the pager. + if wide output requires the pager or should be switched to the + vertical format in expanded auto mode. </para> </listitem> </varlistentry> diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 2c38902..daaed66 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1343,7 +1343,7 @@ exec_command(const char *cmd, free(fname); } - /* \x -- toggle expanded table representation */ + /* \x -- set or toggle expanded table representation */ else if (strcmp(cmd, "x") == 0) { char *opt = psql_scan_slash_option(scan_state, @@ -2177,14 +2177,21 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) /* set expanded/vertical mode */ else if (strcmp(param, "x") == 0 || strcmp(param, "expanded") == 0 || strcmp(param, "vertical") == 0) { - if (value) + if (value && pg_strcasecmp(value, "auto") == 0) + popt->topt.expanded = 2; + else if (value) popt->topt.expanded = ParseVariableBool(value); else popt->topt.expanded = !popt->topt.expanded; if (!quiet) - printf(popt->topt.expanded - ? _("Expanded display is on.\n") - : _("Expanded display is off.\n")); + { + if (popt->topt.expanded == 1) + printf(_("Expanded display is on.\n")); + else if (popt->topt.expanded == 2) + printf(_("Expanded display is used automatically.\n")); + else + printf(_("Expanded display is off.\n")); + } } /* locale-aware numeric output */ @@ -2344,7 +2351,7 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.columns = atoi(value); if (!quiet) - printf(_("Target width for \"wrapped\" format is %d.\n"), popt->topt.columns); + printf(_("Target width is %d.\n"), popt->topt.columns); } else diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index 53e4cd0..4649e94 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -242,8 +242,8 @@ slashUsage(unsigned short int pager) fprintf(output, _(" \\t [on|off] show only rows (currently %s)\n"), ON(pset.popt.topt.tuples_only)); fprintf(output, _(" \\T [STRING] set HTML <table> tag attributes, or unset if none\n")); - fprintf(output, _(" \\x [on|off] toggle expanded output (currently %s)\n"), - ON(pset.popt.topt.expanded)); + fprintf(output, _(" \\x [on|off|auto] toggle expanded output (currently %s)\n"), + pset.popt.topt.expanded == 2 ? "auto" : ON(pset.popt.topt.expanded)); fprintf(output, "\n"); fprintf(output, _("Connection\n")); diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 0d18665..b19159d 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -122,9 +122,11 @@ const printTextFormat pg_utf8format = /* Local functions */ static int strlen_max_width(unsigned char *str, int *target_width, int encoding); -static void IsPagerNeeded(const printTableContent *cont, const int extra_lines, +static void IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expanded, FILE **fout, bool *is_pager); +static void print_aligned_vertical(const printTableContent *cont, FILE *fout); + static void * pg_local_malloc(size_t size) @@ -713,6 +715,17 @@ print_aligned_text(const printTableContent *cont, FILE *fout) } } + /* + * If in expanded auto mode, we have now calculated the expected width, so + * we can now escape to vertical mode if necessary. + */ + if (cont->opt->expanded == 2 && output_columns > 0 && + (output_columns < total_header_width || output_columns < width_total)) + { + print_aligned_vertical(cont, fout); + return; + } + /* If we wrapped beyond the display width, use the pager */ if (!is_pager && fout == stdout && output_columns > 0 && (output_columns < total_header_width || output_columns < width_total)) @@ -756,7 +769,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) extra_row_output_lines = 0; } } - IsPagerNeeded(cont, extra_output_lines, &fout, &is_pager); + IsPagerNeeded(cont, extra_output_lines, false, &fout, &is_pager); } /* time to output */ @@ -1125,6 +1138,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) dformatsize = 0; struct lineptr *hlineptr, *dlineptr; + bool is_pager = false; if (cancel_pressed) return; @@ -1139,6 +1153,13 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) return; } + /* + * Deal with the pager here instead of in printTable(), because we could + * get here via print_aligned_text() in expanded auto mode, and so we have + * to recalcuate the pager requirement based on vertical output. + */ + IsPagerNeeded(cont, 0, true, &fout, &is_pager); + /* Find the maximum dimensions for the headers */ for (i = 0; i < cont->ncolumns; i++) { @@ -1295,6 +1316,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) free(dlineptr->ptr); free(hlineptr); free(dlineptr); + + if (is_pager) + ClosePager(fout); } @@ -2265,14 +2289,14 @@ printTableCleanup(printTableContent *const content) * Setup pager if required */ static void -IsPagerNeeded(const printTableContent *cont, const int extra_lines, FILE **fout, +IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expanded, FILE **fout, bool *is_pager) { if (*fout == stdout) { int lines; - if (cont->opt->expanded) + if (expanded) lines = (cont->ncolumns + 1) * cont->nrows; else lines = cont->nrows + 1; @@ -2310,11 +2334,10 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog) if (cont->opt->format == PRINT_NOTHING) return; - /* print_aligned_text() handles the pager itself */ - if ((cont->opt->format != PRINT_ALIGNED && - cont->opt->format != PRINT_WRAPPED) || - cont->opt->expanded) - IsPagerNeeded(cont, 0, &fout, &is_pager); + /* print_aligned_*() handles the pager themselves */ + if (cont->opt->format != PRINT_ALIGNED && + cont->opt->format != PRINT_WRAPPED) + IsPagerNeeded(cont, 0, (cont->opt->expanded == 1), &fout, &is_pager); /* print the stuff */ @@ -2324,32 +2347,32 @@ printTable(const printTableContent *cont, FILE *fout, FILE *flog) switch (cont->opt->format) { case PRINT_UNALIGNED: - if (cont->opt->expanded) + if (cont->opt->expanded == 1) print_unaligned_vertical(cont, fout); else print_unaligned_text(cont, fout); break; case PRINT_ALIGNED: case PRINT_WRAPPED: - if (cont->opt->expanded) + if (cont->opt->expanded == 1) print_aligned_vertical(cont, fout); else print_aligned_text(cont, fout); break; case PRINT_HTML: - if (cont->opt->expanded) + if (cont->opt->expanded == 1) print_html_vertical(cont, fout); else print_html_text(cont, fout); break; case PRINT_LATEX: - if (cont->opt->expanded) + if (cont->opt->expanded == 1) print_latex_vertical(cont, fout); else print_latex_text(cont, fout); break; case PRINT_TROFF_MS: - if (cont->opt->expanded) + if (cont->opt->expanded == 1) print_troff_ms_vertical(cont, fout); else print_troff_ms_text(cont, fout); diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index 35bb4cd..bb20613 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -70,8 +70,8 @@ typedef struct printTextFormat typedef struct printTableOpt { enum printFormat format; /* see enum above */ - bool expanded; /* expanded/vertical output (if supported by - * output format) */ + unsigned short int expanded;/* expanded/vertical output (if supported by + * output format); 0=no, 1=yes, 2=auto */ unsigned short int border; /* Print a border around the table. 0=none, * 1=dividing lines, 2=full */ unsigned short int pager; /* use pager for output (if to stdout and
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers