@@ -44,6 +44,9 @@ static char *decimal_point;
4444static char * grouping ;
4545static char * thousands_sep ;
4646
47+ static char default_footer [100 ];
48+ static printTableFooter default_footer_cell = {default_footer ,NULL };
49+
4750/* Line style control structures */
4851const printTextFormat pg_asciiformat =
4952{
@@ -278,6 +281,34 @@ print_separator(struct separator sep, FILE *fout)
278281}
279282
280283
284+ /*
285+ * Return the list of explicitly-requested footers or, when applicable, the
286+ * default "(xx rows)" footer. Always omit the default footer when given
287+ * non-default footers, "\pset footer off", or a specific instruction to that
288+ * effect from a calling backslash command. Vertical formats number each row,
289+ * making the default footer redundant; they do not call this function.
290+ *
291+ * The return value may point to static storage; do not keep it across calls.
292+ */
293+ static printTableFooter *
294+ footers_with_default (const printTableContent * cont )
295+ {
296+ if (cont -> footers == NULL && cont -> opt -> default_footer )
297+ {
298+ unsigned long total_records ;
299+
300+ total_records = cont -> opt -> prior_records + cont -> nrows ;
301+ snprintf (default_footer ,sizeof (default_footer ),
302+ ngettext ("(%lu row)" ,"(%lu rows)" ,total_records ),
303+ total_records );
304+
305+ return & default_footer_cell ;
306+ }
307+ else
308+ return cont -> footers ;
309+ }
310+
311+
281312/*************************/
282313/* Unaligned text */
283314/*************************/
@@ -340,11 +371,13 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
340371/* print footers */
341372if (cont -> opt -> stop_table )
342373{
343- if (!opt_tuples_only && cont -> footers != NULL && !cancel_pressed )
374+ printTableFooter * footers = footers_with_default (cont );
375+
376+ if (!opt_tuples_only && footers != NULL && !cancel_pressed )
344377{
345378printTableFooter * f ;
346379
347- for (f = cont -> footers ;f ;f = f -> next )
380+ for (f = footers ;f ;f = f -> next )
348381{
349382if (need_recordsep )
350383{
@@ -1034,16 +1067,18 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
10341067
10351068if (cont -> opt -> stop_table )
10361069{
1070+ printTableFooter * footers = footers_with_default (cont );
1071+
10371072if (opt_border == 2 && !cancel_pressed )
10381073_print_horizontal_line (col_count ,width_wrap ,opt_border ,
10391074PRINT_RULE_BOTTOM ,format ,fout );
10401075
10411076/* print footers */
1042- if (cont -> footers && !opt_tuples_only && !cancel_pressed )
1077+ if (footers && !opt_tuples_only && !cancel_pressed )
10431078{
10441079printTableFooter * f ;
10451080
1046- for (f = cont -> footers ;f ;f = f -> next )
1081+ for (f = footers ;f ;f = f -> next )
10471082fprintf (fout ,"%s\n" ,f -> data );
10481083}
10491084
@@ -1447,15 +1482,17 @@ print_html_text(const printTableContent *cont, FILE *fout)
14471482
14481483if (cont -> opt -> stop_table )
14491484{
1485+ printTableFooter * footers = footers_with_default (cont );
1486+
14501487fputs ("</table>\n" ,fout );
14511488
14521489/* print footers */
1453- if (!opt_tuples_only && cont -> footers != NULL && !cancel_pressed )
1490+ if (!opt_tuples_only && footers != NULL && !cancel_pressed )
14541491{
14551492printTableFooter * f ;
14561493
14571494fputs ("<p>" ,fout );
1458- for (f = cont -> footers ;f ;f = f -> next )
1495+ for (f = footers ;f ;f = f -> next )
14591496{
14601497html_escaped_print (f -> data ,fout );
14611498fputs ("<br />\n" ,fout );
@@ -1668,17 +1705,19 @@ print_latex_text(const printTableContent *cont, FILE *fout)
16681705
16691706if (cont -> opt -> stop_table )
16701707{
1708+ printTableFooter * footers = footers_with_default (cont );
1709+
16711710if (opt_border == 2 )
16721711fputs ("\\hline\n" ,fout );
16731712
16741713fputs ("\\end{tabular}\n\n\\noindent " ,fout );
16751714
16761715/* print footers */
1677- if (cont -> footers && !opt_tuples_only && !cancel_pressed )
1716+ if (footers && !opt_tuples_only && !cancel_pressed )
16781717{
16791718printTableFooter * f ;
16801719
1681- for (f = cont -> footers ;f ;f = f -> next )
1720+ for (f = footers ;f ;f = f -> next )
16821721{
16831722latex_escaped_print (f -> data ,fout );
16841723fputs (" \\\\\n" ,fout );
@@ -1871,14 +1910,16 @@ print_troff_ms_text(const printTableContent *cont, FILE *fout)
18711910
18721911if (cont -> opt -> stop_table )
18731912{
1913+ printTableFooter * footers = footers_with_default (cont );
1914+
18741915fputs (".TE\n.DS L\n" ,fout );
18751916
18761917/* print footers */
1877- if (cont -> footers && !opt_tuples_only && !cancel_pressed )
1918+ if (footers && !opt_tuples_only && !cancel_pressed )
18781919{
18791920printTableFooter * f ;
18801921
1881- for (f = cont -> footers ;f ;f = f -> next )
1922+ for (f = footers ;f ;f = f -> next )
18821923{
18831924troff_ms_escaped_print (f -> data ,fout );
18841925fputc ('\n' ,fout );
@@ -2481,18 +2522,6 @@ printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f
24812522for (footer = opt -> footers ;* footer ;footer ++ )
24822523printTableAddFooter (& cont ,* footer );
24832524}
2484- else if (!opt -> topt .expanded && opt -> default_footer )
2485- {
2486- unsigned long total_records ;
2487- char default_footer [100 ];
2488-
2489- total_records = opt -> topt .prior_records + cont .nrows ;
2490- snprintf (default_footer ,sizeof (default_footer ),
2491- ngettext ("(%lu row)" ,"(%lu rows)" ,total_records ),
2492- total_records );
2493-
2494- printTableAddFooter (& cont ,default_footer );
2495- }
24962525
24972526printTable (& cont ,fout ,flog );
24982527printTableCleanup (& cont );