mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Tweak psql to print row counts when \x auto chooses non-expanded output.
Noah Misch
This commit is contained in:
@ -2407,12 +2407,12 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
|
|||||||
else if (strcmp(param, "footer") == 0)
|
else if (strcmp(param, "footer") == 0)
|
||||||
{
|
{
|
||||||
if (value)
|
if (value)
|
||||||
popt->default_footer = ParseVariableBool(value);
|
popt->topt.default_footer = ParseVariableBool(value);
|
||||||
else
|
else
|
||||||
popt->default_footer = !popt->default_footer;
|
popt->topt.default_footer = !popt->topt.default_footer;
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
{
|
{
|
||||||
if (popt->default_footer)
|
if (popt->topt.default_footer)
|
||||||
puts(_("Default footer is on."));
|
puts(_("Default footer is on."));
|
||||||
else
|
else
|
||||||
puts(_("Default footer is off."));
|
puts(_("Default footer is off."));
|
||||||
|
@ -1130,6 +1130,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
|
|
||||||
retval = false;
|
retval = false;
|
||||||
|
|
||||||
|
myopt.default_footer = false;
|
||||||
/* This output looks confusing in expanded mode. */
|
/* This output looks confusing in expanded mode. */
|
||||||
myopt.expanded = false;
|
myopt.expanded = false;
|
||||||
|
|
||||||
@ -2363,6 +2364,8 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
const char align = 'l';
|
const char align = 'l';
|
||||||
char **attr;
|
char **attr;
|
||||||
|
|
||||||
|
myopt.default_footer = false;
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
if (pset.sversion >= 80100)
|
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);
|
sprintf(title, _("Text search parser \"%s\""), prsname);
|
||||||
myopt.title = title;
|
myopt.title = title;
|
||||||
myopt.footers = NULL;
|
myopt.footers = NULL;
|
||||||
myopt.default_footer = false;
|
myopt.topt.default_footer = false;
|
||||||
myopt.translate_header = true;
|
myopt.translate_header = true;
|
||||||
myopt.translate_columns = translate_columns;
|
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);
|
sprintf(title, _("Token types for parser \"%s\""), prsname);
|
||||||
myopt.title = title;
|
myopt.title = title;
|
||||||
myopt.footers = NULL;
|
myopt.footers = NULL;
|
||||||
myopt.default_footer = true;
|
myopt.topt.default_footer = true;
|
||||||
myopt.translate_header = true;
|
myopt.translate_header = true;
|
||||||
myopt.translate_columns = NULL;
|
myopt.translate_columns = NULL;
|
||||||
|
|
||||||
@ -3725,7 +3728,7 @@ describeOneTSConfig(const char *oid, const char *nspname, const char *cfgname,
|
|||||||
myopt.nullPrint = NULL;
|
myopt.nullPrint = NULL;
|
||||||
myopt.title = title.data;
|
myopt.title = title.data;
|
||||||
myopt.footers = NULL;
|
myopt.footers = NULL;
|
||||||
myopt.default_footer = false;
|
myopt.topt.default_footer = false;
|
||||||
myopt.translate_header = true;
|
myopt.translate_header = true;
|
||||||
|
|
||||||
printQuery(res, &myopt, pset.queryFout, pset.logfile);
|
printQuery(res, &myopt, pset.queryFout, pset.logfile);
|
||||||
|
@ -44,6 +44,9 @@ static char *decimal_point;
|
|||||||
static char *grouping;
|
static char *grouping;
|
||||||
static char *thousands_sep;
|
static char *thousands_sep;
|
||||||
|
|
||||||
|
static char default_footer[100];
|
||||||
|
static printTableFooter default_footer_cell = { default_footer, NULL };
|
||||||
|
|
||||||
/* Line style control structures */
|
/* Line style control structures */
|
||||||
const printTextFormat pg_asciiformat =
|
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 */
|
/* Unaligned text */
|
||||||
/*************************/
|
/*************************/
|
||||||
@ -340,11 +371,13 @@ print_unaligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
/* print footers */
|
/* print footers */
|
||||||
if (cont->opt->stop_table)
|
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;
|
printTableFooter *f;
|
||||||
|
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = footers; f; f = f->next)
|
||||||
{
|
{
|
||||||
if (need_recordsep)
|
if (need_recordsep)
|
||||||
{
|
{
|
||||||
@ -1034,16 +1067,18 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
if (cont->opt->stop_table)
|
if (cont->opt->stop_table)
|
||||||
{
|
{
|
||||||
|
printTableFooter *footers = footers_with_default(cont);
|
||||||
|
|
||||||
if (opt_border == 2 && !cancel_pressed)
|
if (opt_border == 2 && !cancel_pressed)
|
||||||
_print_horizontal_line(col_count, width_wrap, opt_border,
|
_print_horizontal_line(col_count, width_wrap, opt_border,
|
||||||
PRINT_RULE_BOTTOM, format, fout);
|
PRINT_RULE_BOTTOM, format, fout);
|
||||||
|
|
||||||
/* print footers */
|
/* print footers */
|
||||||
if (cont->footers && !opt_tuples_only && !cancel_pressed)
|
if (footers && !opt_tuples_only && !cancel_pressed)
|
||||||
{
|
{
|
||||||
printTableFooter *f;
|
printTableFooter *f;
|
||||||
|
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = footers; f; f = f->next)
|
||||||
fprintf(fout, "%s\n", f->data);
|
fprintf(fout, "%s\n", f->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1447,15 +1482,17 @@ print_html_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
if (cont->opt->stop_table)
|
if (cont->opt->stop_table)
|
||||||
{
|
{
|
||||||
|
printTableFooter *footers = footers_with_default(cont);
|
||||||
|
|
||||||
fputs("</table>\n", fout);
|
fputs("</table>\n", fout);
|
||||||
|
|
||||||
/* print footers */
|
/* print footers */
|
||||||
if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)
|
if (!opt_tuples_only && footers != NULL && !cancel_pressed)
|
||||||
{
|
{
|
||||||
printTableFooter *f;
|
printTableFooter *f;
|
||||||
|
|
||||||
fputs("<p>", fout);
|
fputs("<p>", fout);
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = footers; f; f = f->next)
|
||||||
{
|
{
|
||||||
html_escaped_print(f->data, fout);
|
html_escaped_print(f->data, fout);
|
||||||
fputs("<br />\n", fout);
|
fputs("<br />\n", fout);
|
||||||
@ -1668,17 +1705,19 @@ print_latex_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
if (cont->opt->stop_table)
|
if (cont->opt->stop_table)
|
||||||
{
|
{
|
||||||
|
printTableFooter *footers = footers_with_default(cont);
|
||||||
|
|
||||||
if (opt_border == 2)
|
if (opt_border == 2)
|
||||||
fputs("\\hline\n", fout);
|
fputs("\\hline\n", fout);
|
||||||
|
|
||||||
fputs("\\end{tabular}\n\n\\noindent ", fout);
|
fputs("\\end{tabular}\n\n\\noindent ", fout);
|
||||||
|
|
||||||
/* print footers */
|
/* print footers */
|
||||||
if (cont->footers && !opt_tuples_only && !cancel_pressed)
|
if (footers && !opt_tuples_only && !cancel_pressed)
|
||||||
{
|
{
|
||||||
printTableFooter *f;
|
printTableFooter *f;
|
||||||
|
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = footers; f; f = f->next)
|
||||||
{
|
{
|
||||||
latex_escaped_print(f->data, fout);
|
latex_escaped_print(f->data, fout);
|
||||||
fputs(" \\\\\n", fout);
|
fputs(" \\\\\n", fout);
|
||||||
@ -1871,14 +1910,16 @@ print_troff_ms_text(const printTableContent *cont, FILE *fout)
|
|||||||
|
|
||||||
if (cont->opt->stop_table)
|
if (cont->opt->stop_table)
|
||||||
{
|
{
|
||||||
|
printTableFooter *footers = footers_with_default(cont);
|
||||||
|
|
||||||
fputs(".TE\n.DS L\n", fout);
|
fputs(".TE\n.DS L\n", fout);
|
||||||
|
|
||||||
/* print footers */
|
/* print footers */
|
||||||
if (cont->footers && !opt_tuples_only && !cancel_pressed)
|
if (footers && !opt_tuples_only && !cancel_pressed)
|
||||||
{
|
{
|
||||||
printTableFooter *f;
|
printTableFooter *f;
|
||||||
|
|
||||||
for (f = cont->footers; f; f = f->next)
|
for (f = footers; f; f = f->next)
|
||||||
{
|
{
|
||||||
troff_ms_escaped_print(f->data, fout);
|
troff_ms_escaped_print(f->data, fout);
|
||||||
fputc('\n', 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++)
|
for (footer = opt->footers; *footer; footer++)
|
||||||
printTableAddFooter(&cont, *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);
|
printTable(&cont, fout, flog);
|
||||||
printTableCleanup(&cont);
|
printTableCleanup(&cont);
|
||||||
|
@ -85,6 +85,7 @@ typedef struct printTableOpt
|
|||||||
bool tuples_only; /* don't output headers, row counts, etc. */
|
bool tuples_only; /* don't output headers, row counts, etc. */
|
||||||
bool start_table; /* print start decoration, eg <table> */
|
bool start_table; /* print start decoration, eg <table> */
|
||||||
bool stop_table; /* print stop 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 */
|
unsigned long prior_records; /* start offset for record counters */
|
||||||
const printTextFormat *line_style; /* line style (NULL for default) */
|
const printTextFormat *line_style; /* line style (NULL for default) */
|
||||||
struct separator fieldSep; /* field separator for unaligned text mode */
|
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 */
|
bool quote; /* quote all values as much as possible */
|
||||||
char *title; /* override title */
|
char *title; /* override title */
|
||||||
char **footers; /* override footer (default is "(xx rows)") */
|
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 */
|
bool translate_header; /* do gettext on column headers */
|
||||||
const bool *translate_columns; /* translate_columns[i-1] => do
|
const bool *translate_columns; /* translate_columns[i-1] => do
|
||||||
* gettext on col i */
|
* gettext on col i */
|
||||||
|
@ -129,7 +129,7 @@ main(int argc, char *argv[])
|
|||||||
pset.popt.topt.pager = 1;
|
pset.popt.topt.pager = 1;
|
||||||
pset.popt.topt.start_table = true;
|
pset.popt.topt.start_table = true;
|
||||||
pset.popt.topt.stop_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 */
|
/* We must get COLUMNS here before readline() sets it */
|
||||||
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
|
pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user