Add psql expanded auto mode
authorPeter Eisentraut <peter_e@gmx.net>
Sat, 12 Nov 2011 15:03:10 +0000 (17:03 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Sat, 12 Nov 2011 15:03:10 +0000 (17:03 +0200)
This adds the "auto" option to the \x command, which switches to the
expanded mode when the normal output would be wider than the screen.

reviewed by Noah Misch

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/help.c
src/bin/psql/print.c
src/bin/psql/print.h

index d6941e0bd338782a5dbde564cd795858b7cadb8d..01f57c4eeb9febf6bfe8c9b82adf26fd711b35e6 100644 (file)
@@ -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>
index 5970ab32c15b34cbc35e4929c0fc0669f1fa028d..9cc73beabff615430393456d093c8880e322d4fb 100644 (file)
@@ -1355,7 +1355,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,
@@ -2189,14 +2189,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 */
@@ -2356,7 +2363,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
index 53e4cd0c0e22552245f3fc2f9c1e06ee0fc6a317..4649e944755a5edd5b53f3a8143e4d7656b3a345 100644 (file)
@@ -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"));
index 0d18665566f4f50c3a5aee2c3ba3bf4736de8a60..b19159d543b8b5ea100051266aa0e98ba2a2b890 100644 (file)
@@ -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);
index 35bb4cde1d9be1ded49c99d9237bee4b6f1d4efa..bb206136294efe701703daae1c3933108b35ef9d 100644 (file)
@@ -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