diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index a6370014987..a33e460bca0 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2235,6 +2235,18 @@ lo_import 152801 + + pager_min_lines + + + If pager_min_lines is set to a number greater than the + page height, the pager program will not be called unless there are + at least this many lines of output to show. The default setting + is 0. + + + + recordsep diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 7c9f28dee06..e64c033bf8c 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1071,7 +1071,8 @@ exec_command(const char *cmd, static const char *const my_list[] = { "border", "columns", "expanded", "fieldsep", "fieldsep_zero", "footer", "format", "linestyle", "null", - "numericlocale", "pager", "recordsep", "recordsep_zero", + "numericlocale", "pager", "pager_min_lines", + "recordsep", "recordsep_zero", "tableattr", "title", "tuples_only", "unicode_border_linestyle", "unicode_column_linestyle", @@ -1265,7 +1266,7 @@ exec_command(const char *cmd, lines++; } - output = PageOutput(lineno, pset.popt.topt.pager); + output = PageOutput(lineno, &(pset.popt.topt)); is_pager = true; } else @@ -2519,6 +2520,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.pager = 1; } + /* set minimum lines for pager use */ + else if (strcmp(param, "pager_min_lines") == 0) + { + if (value) + popt->topt.pager_min_lines = atoi(value); + } + /* disable "(x rows)" footer */ else if (strcmp(param, "footer") == 0) { @@ -2640,6 +2648,13 @@ printPsetInfo(const char *param, struct printQueryOpt *popt) printf(_("Pager usage is off.\n")); } + /* show minimum lines for pager use */ + else if (strcmp(param, "pager_min_lines") == 0) + { + printf(_("Pager won't be used for less than %d lines\n"), + popt->topt.pager_min_lines); + } + /* show record separator for unaligned text */ else if (strcmp(param, "recordsep") == 0) { @@ -2792,6 +2807,8 @@ pset_value_string(const char *param, struct printQueryOpt *popt) return pstrdup(pset_bool_string(popt->topt.numericLocale)); else if (strcmp(param, "pager") == 0) return psprintf("%d", popt->topt.pager); + else if (strcmp(param, "pager_min_lines") == 0) + return psprintf("%d", popt->topt.pager_min_lines); else if (strcmp(param, "recordsep") == 0) return pset_quoted_string(popt->topt.recordSep.separator ? popt->topt.recordSep.separator diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 15488ff0357..2e7d9a45cb3 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -1337,7 +1337,7 @@ ExecQueryUsingCursor(const char *query, double *elapsed_msec) * If query requires multiple result sets, hack to ensure that * only one pager instance is used for the whole mess */ - pset.queryFout = PageOutput(100000, my_popt.topt.pager); + pset.queryFout = PageOutput(100000, &(my_popt.topt)); did_pager = true; } diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c index ac0dc279078..2da444b6d59 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -65,7 +65,7 @@ usage(unsigned short int pager) } } - output = PageOutput(59, pager); + output = PageOutput(59, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("psql is the PostgreSQL interactive terminal.\n\n")); fprintf(output, _("Usage:\n")); @@ -158,7 +158,7 @@ slashUsage(unsigned short int pager) currdb = PQdb(pset.db); - output = PageOutput(103, pager); + output = PageOutput(103, pager ? &(pset.popt.topt) : NULL); /* if you add/remove a line here, change the row count above */ @@ -305,7 +305,7 @@ helpVariables(unsigned short int pager) { FILE *output; - output = PageOutput(85, pager); + output = PageOutput(85, pager ? &(pset.popt.topt) : NULL); fprintf(output, _("List of specially treated variables.\n")); @@ -435,7 +435,7 @@ helpSQL(const char *topic, unsigned short int pager) ncolumns = Max(ncolumns, 1); nrows = (QL_HELP_COUNT + (ncolumns - 1)) / ncolumns; - output = PageOutput(nrows + 1, pager); + output = PageOutput(nrows + 1, pager ? &(pset.popt.topt) : NULL); fputs(_("Available help:\n"), output); @@ -488,7 +488,7 @@ helpSQL(const char *topic, unsigned short int pager) if (wordlen >= len) /* Don't try again if the same word */ { if (!output) - output = PageOutput(nl_count, pager); + output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL); break; } len = wordlen; @@ -509,7 +509,7 @@ helpSQL(const char *topic, unsigned short int pager) } if (!output) - output = PageOutput(nl_count, pager); + output = PageOutput(nl_count, pager ? &(pset.popt.topt) : NULL); for (i = 0; QL_HELP[i].cmd; i++) { diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c index d52a3347970..437fa4d663a 100644 --- a/src/bin/psql/input.c +++ b/src/bin/psql/input.c @@ -474,7 +474,7 @@ printHistory(const char *fname, unsigned short int pager) if (fname == NULL) { /* use pager, if enabled, when printing to console */ - output = PageOutput(INT_MAX, pager); + output = PageOutput(INT_MAX, pager ? &(pset.popt.topt) : NULL); is_pager = true; } else diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index f6f93108413..9c12dbe049a 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -811,7 +811,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout) if (!is_pager && fout == stdout && output_columns > 0 && (output_columns < total_header_width || output_columns < width_total)) { - fout = PageOutput(INT_MAX, cont->opt->pager); /* force pager */ + fout = PageOutput(INT_MAX, cont->opt); /* force pager */ is_pager = true; } @@ -2497,15 +2497,19 @@ print_troff_ms_vertical(const printTableContent *cont, FILE *fout) * PageOutput * * Tests if pager is needed and returns appropriate FILE pointer. + * + * If the topt argument is NULL no pager is used. */ FILE * -PageOutput(int lines, unsigned short int pager) +PageOutput(int lines, const printTableOpt *topt) { /* check whether we need / can / are supposed to use pager */ - if (pager && isatty(fileno(stdin)) && isatty(fileno(stdout))) + if (topt && topt->pager && isatty(fileno(stdin)) && isatty(fileno(stdout))) { const char *pagerprog; FILE *pagerpipe; + unsigned short int pager = topt->pager; + int min_lines = topt->pager_min_lines; #ifdef TIOCGWINSZ int result; @@ -2514,7 +2518,9 @@ PageOutput(int lines, unsigned short int pager) result = ioctl(fileno(stdout), TIOCGWINSZ, &screen_size); /* >= accounts for a one-line prompt */ - if (result == -1 || lines >= screen_size.ws_row || pager > 1) + if (result == -1 + || (lines >= screen_size.ws_row && lines >= min_lines) + || pager > 1) { #endif pagerprog = getenv("PAGER"); @@ -2814,7 +2820,7 @@ IsPagerNeeded(const printTableContent *cont, const int extra_lines, bool expande lines++; } - *fout = PageOutput(lines + extra_lines, cont->opt->pager); + *fout = PageOutput(lines + extra_lines, cont->opt); *is_pager = (*fout != stdout); } else diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h index a1a89d01dbb..66cdaf32ae7 100644 --- a/src/bin/psql/print.h +++ b/src/bin/psql/print.h @@ -89,6 +89,8 @@ typedef struct printTableOpt * 1=dividing lines, 2=full */ unsigned short int pager; /* use pager for output (if to stdout and * stdout is a tty) 0=off 1=on 2=always */ + int pager_min_lines;/* don't use pager unless there are at least + * this many lines */ bool tuples_only; /* don't output headers, row counts, etc. */ bool start_table; /* print start decoration, eg */ bool stop_table; /* print stop decoration, eg
*/ @@ -164,7 +166,7 @@ extern const printTextFormat pg_asciiformat_old; extern const printTextFormat pg_utf8format; -extern FILE *PageOutput(int lines, unsigned short int pager); +extern FILE *PageOutput(int lines, const printTableOpt *topt); extern void ClosePager(FILE *pagerpipe); extern void html_escaped_print(const char *in, FILE *fout); diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c index 7f09c141a90..d57901f7780 100644 --- a/src/bin/psql/startup.c +++ b/src/bin/psql/startup.c @@ -129,6 +129,7 @@ main(int argc, char *argv[]) pset.popt.topt.format = PRINT_ALIGNED; pset.popt.topt.border = 1; pset.popt.topt.pager = 1; + pset.popt.topt.pager_min_lines = 0; pset.popt.topt.start_table = true; pset.popt.topt.stop_table = true; pset.popt.topt.default_footer = true; diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index e87b82b9910..a2a261595a6 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -65,6 +65,7 @@ linestyle ascii null '' numericlocale off pager 1 +pager_min_lines 0 recordsep '\n' recordsep_zero off tableattr