]> granicus.if.org Git - postgresql/commitdiff
Tweak psql to print row counts when \x auto chooses non-expanded output.
authorRobert Haas <rhaas@postgresql.org>
Tue, 1 May 2012 20:03:45 +0000 (16:03 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 1 May 2012 20:05:01 +0000 (16:05 -0400)
Noah Misch

src/bin/psql/command.c
src/bin/psql/describe.c
src/bin/psql/print.c
src/bin/psql/print.h
src/bin/psql/startup.c

index dd59aa116c2352b9e5822465f760a196548ec7fe..7f91ff9fcef86b4a50e58670d011e0929d215556 100644 (file)
@@ -2407,12 +2407,12 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
        else if (strcmp(param, "footer") == 0)
        {
                if (value)
-                       popt->default_footer = ParseVariableBool(value);
+                       popt->topt.default_footer = ParseVariableBool(value);
                else
-                       popt->default_footer = !popt->default_footer;
+                       popt->topt.default_footer = !popt->topt.default_footer;
                if (!quiet)
                {
-                       if (popt->default_footer)
+                       if (popt->topt.default_footer)
                                puts(_("Default footer is on."));
                        else
                                puts(_("Default footer is off."));
index ffaaf4049f30fcc8f9dae8738234ad2444a1f9aa..8dfb5705ce4564753c6689b455971d7e1abbe410 100644 (file)
@@ -1130,6 +1130,7 @@ describeOneTableDetails(const char *schemaname,
 
        retval = false;
 
+       myopt.default_footer = false;
        /* This output looks confusing in expanded mode. */
        myopt.expanded = false;
 
@@ -2363,6 +2364,8 @@ describeRoles(const char *pattern, bool verbose)
        const char      align = 'l';
        char      **attr;
 
+       myopt.default_footer = false;
+
        initPQExpBuffer(&buf);
 
        if (pset.sversion >= 80100)
@@ -3362,7 +3365,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
                sprintf(title, _("Text search parser \"%s\""), prsname);
        myopt.title = title;
        myopt.footers = NULL;
-       myopt.default_footer = false;
+       myopt.topt.default_footer = false;
        myopt.translate_header = true;
        myopt.translate_columns = translate_columns;
 
@@ -3393,7 +3396,7 @@ describeOneTSParser(const char *oid, const char *nspname, const char *prsname)
                sprintf(title, _("Token types for parser \"%s\""), prsname);
        myopt.title = title;
        myopt.footers = NULL;
-       myopt.default_footer = true;
+       myopt.topt.default_footer = true;
        myopt.translate_header = true;
        myopt.translate_columns = NULL;
 
@@ -3725,7 +3728,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
        myopt.nullPrint = NULL;
        myopt.title = title.data;
        myopt.footers = NULL;
-       myopt.default_footer = false;
+       myopt.topt.default_footer = false;
        myopt.translate_header = true;
 
        printQuery(res, &myopt, pset.queryFout, pset.logfile);
index d2474716dbc03aff539d3342ba82825a8d93336b..c431f6a437a3a052af4784f7701bc66c8b684feb 100644 (file)
@@ -44,6 +44,9 @@ static char *decimal_point;
 static char *grouping;
 static char *thousands_sep;
 
+static char    default_footer[100];
+static printTableFooter default_footer_cell = { default_footer, NULL };
+
 /* Line style control structures */
 const printTextFormat pg_asciiformat =
 {
@@ -278,6 +281,34 @@ print_separator(struct separator sep, FILE *fout)
 }
 
 
+/*
+ * Return the list of explicitly-requested footers or, when applicable, the
+ * default "(xx rows)" footer.  Always omit the default footer when given
+ * non-default footers, "\pset footer off", or a specific instruction to that
+ * effect from a calling backslash command.  Vertical formats number each row,
+ * making the default footer redundant; they do not call this function.
+ *
+ * The return value may point to static storage; do not keep it across calls.
+ */
+static printTableFooter *
+footers_with_default(const printTableContent *cont)
+{
+       if (cont->footers == NULL && cont->opt->default_footer)
+       {
+               unsigned long total_records;
+
+               total_records = cont->opt->prior_records + cont->nrows;
+               snprintf(default_footer, sizeof(default_footer),
+                                ngettext("(%lu row)", "(%lu rows)", total_records),
+                                total_records);
+
+               return &default_footer_cell;
+       }
+       else
+               return cont->footers;
+}
+
+
 /*************************/
 /* Unaligned text               */
 /*************************/
@@ -340,11 +371,13 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
        /* print footers */
        if (cont->opt->stop_table)
        {
-               if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
+               printTableFooter *footers = footers_with_default(cont);
+
+               if (!opt_tuples_only && footers != NULL && !cancel_pressed)
                {
                        printTableFooter *f;
 
-                       for (f = cont->footers; f; f = f->next)
+                       for (f = footers; f; f = f->next)
                        {
                                if (need_recordsep)
                                {
@@ -1034,16 +1067,18 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
 
        if (cont->opt->stop_table)
        {
+               printTableFooter *footers = footers_with_default(cont);
+
                if (opt_border == 2 && !cancel_pressed)
                        _print_horizontal_line(col_count, width_wrap, opt_border,
                                                                   PRINT_RULE_BOTTOM, format, fout);
 
                /* print footers */
-               if (cont->footers && !opt_tuples_only && !cancel_pressed)
+               if (footers && !opt_tuples_only && !cancel_pressed)
                {
                        printTableFooter *f;
 
-                       for (f = cont->footers; f; f = f->next)
+                       for (f = footers; f; f = f->next)
                                fprintf(fout, "%s\n", f->data);
                }
 
@@ -1447,15 +1482,17 @@ print_html_text(const printTableContent *cont, FILE *fout)
 
        if (cont->opt->stop_table)
        {
+               printTableFooter *footers = footers_with_default(cont);
+
                fputs("</table>\n", fout);
 
                /* print footers */
-               if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
+               if (!opt_tuples_only && footers != NULL && !cancel_pressed)
                {
                        printTableFooter *f;
 
                        fputs("<p>", fout);
-                       for (f = cont->footers; f; f = f->next)
+                       for (f = footers; f; f = f->next)
                        {
                                html_escaped_print(f->data, fout);
                                fputs("<br />\n", fout);
@@ -1668,17 +1705,19 @@ print_latex_text(const printTableContent *cont, FILE *fout)
 
        if (cont->opt->stop_table)
        {
+               printTableFooter *footers = footers_with_default(cont);
+
                if (opt_border == 2)
                        fputs("\\hline\n", fout);
 
                fputs("\\end{tabular}\n\n\\noindent ", fout);
 
                /* print footers */
-               if (cont->footers && !opt_tuples_only && !cancel_pressed)
+               if (footers && !opt_tuples_only && !cancel_pressed)
                {
                        printTableFooter *f;
 
-                       for (f = cont->footers; f; f = f->next)
+                       for (f = footers; f; f = f->next)
                        {
                                latex_escaped_print(f->data, fout);
                                fputs(" \\\\\n", fout);
@@ -1871,14 +1910,16 @@ print_troff_ms_text(const printTableContent *cont, FILE *fout)
 
        if (cont->opt->stop_table)
        {
+               printTableFooter *footers = footers_with_default(cont);
+
                fputs(".TE\n.DS L\n", fout);
 
                /* print footers */
-               if (cont->footers && !opt_tuples_only && !cancel_pressed)
+               if (footers && !opt_tuples_only && !cancel_pressed)
                {
                        printTableFooter *f;
 
-                       for (f = cont->footers; f; f = f->next)
+                       for (f = footers; f; f = f->next)
                        {
                                troff_ms_escaped_print(f->data, fout);
                                fputc('\n', fout);
@@ -2481,18 +2522,6 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
                for (footer = opt->footers; *footer; footer++)
                        printTableAddFooter(&cont, *footer);
        }
-       else if (!opt->topt.expanded && opt->default_footer)
-       {
-               unsigned long total_records;
-               char            default_footer[100];
-
-               total_records = opt->topt.prior_records + cont.nrows;
-               snprintf(default_footer, sizeof(default_footer),
-                                ngettext("(%lu row)", "(%lu rows)", total_records),
-                                total_records);
-
-               printTableAddFooter(&cont, default_footer);
-       }
 
        printTable(&cont, fout, flog);
        printTableCleanup(&cont);
index c7377562c505fc3cbfebfbf0d2fa5666baf6e6ec..25adfc58138852374daf23f82b56177554bdee02 100644 (file)
@@ -85,6 +85,7 @@ typedef struct printTableOpt
        bool            tuples_only;    /* don't output headers, row counts, etc. */
        bool            start_table;    /* print start decoration, eg <table> */
        bool            stop_table;             /* print stop decoration, eg </table> */
+       bool            default_footer; /* allow "(xx rows)" default footer */
        unsigned long prior_records;    /* start offset for record counters */
        const printTextFormat *line_style;      /* line style (NULL for default) */
        struct separator fieldSep;      /* field separator for unaligned text mode */
@@ -141,7 +142,6 @@ typedef struct printQueryOpt
        bool            quote;                  /* quote all values as much as possible */
        char       *title;                      /* override title */
        char      **footers;            /* override footer (default is "(xx rows)") */
-       bool            default_footer; /* print default footer if footers==NULL */
        bool            translate_header;               /* do gettext on column headers */
        const bool *translate_columns;          /* translate_columns[i-1] => do
                                                                                 * gettext on col i */
index b5664dfd1d375b04676f02e95b827cfbf85880ec..9e6917cbe4bbfc8e2d931af9e58fe8e5f1f041cf 100644 (file)
@@ -129,7 +129,7 @@ main(int argc, char *argv[])
        pset.popt.topt.pager = 1;
        pset.popt.topt.start_table = true;
        pset.popt.topt.stop_table = true;
-       pset.popt.default_footer = true;
+       pset.popt.topt.default_footer = true;
        /* We must get COLUMNS here before readline() sets it */
        pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;