Index: doc/src/sgml/ref/psql-ref.sgml
===================================================================
RCS file: /cvsroot/pgsql/doc/src/sgml/ref/psql-ref.sgml,v
retrieving revision 1.204
diff -c -c -r1.204 psql-ref.sgml
*** doc/src/sgml/ref/psql-ref.sgml 14 May 2008 04:07:01 -0000 1.204
--- doc/src/sgml/ref/psql-ref.sgml 16 May 2008 16:49:19 -0000
***************
*** 1555,1561 ****
columns
! Controls the target width for the wrapped> format.
Zero (the default) causes the wrapped> format to
affect only screen output.
--- 1555,1562 ----
columns
! Controls the target width for the wrapped> format,
! and width for determining if wide output requires the pager.
Zero (the default) causes the wrapped> format to
affect only screen output.
***************
*** 1717,1726 ****
When the pager is off>, the pager is not used. When the pager
is on>, the pager is used only when appropriate, i.e. the
output is to a terminal and will not fit on the screen.
! (psql> does not do a perfect job of estimating
! when to use the pager.) \pset pager> turns the
! pager on and off. Pager can also be set to always>,
! which causes the pager to be always used.
--- 1718,1726 ----
When the pager is off>, the pager is not used. When the pager
is on>, the pager is used only when appropriate, i.e. the
output is to a terminal and will not fit on the screen.
! \pset pager> turns the pager on and off. Pager can
! also be set to always>, which causes the pager to be
! always used.
***************
*** 2734,2741 ****
! Used for the wrapped> output format if
! \pset columns> is zero.
--- 2734,2742 ----
! If \pset columns> is zero, controls the
! width for the wrapped> format and width for determining
! if wide output requires the pager.
Index: src/bin/psql/print.c
===================================================================
RCS file: /cvsroot/pgsql/src/bin/psql/print.c,v
retrieving revision 1.101
diff -c -c -r1.101 print.c
*** src/bin/psql/print.c 13 May 2008 00:14:11 -0000 1.101
--- src/bin/psql/print.c 16 May 2008 16:49:20 -0000
***************
*** 45,50 ****
--- 45,52 ----
/* 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,
+ FILE **fout, bool *is_pager);
static void *
***************
*** 394,400 ****
* Print pretty boxes around cells.
*/
static void
! print_aligned_text(const printTableContent *cont, bool is_pager, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
bool opt_numeric_locale = cont->opt->numericLocale;
--- 396,402 ----
* Print pretty boxes around cells.
*/
static void
! print_aligned_text(const printTableContent *cont, FILE *fout)
{
bool opt_tuples_only = cont->opt->tuples_only;
bool opt_numeric_locale = cont->opt->numericLocale;
***************
*** 416,421 ****
--- 418,425 ----
unsigned char **format_buf;
unsigned int width_total;
unsigned int total_header_width;
+ unsigned int extra_row_output_lines = 0;
+ unsigned int extra_output_lines = 0;
const char * const *ptr;
***************
*** 424,429 ****
--- 428,434 ----
bool *header_done; /* Have all header lines been output? */
int *bytes_output; /* Bytes output for column value */
int output_columns = 0; /* Width of interactive console */
+ bool is_pager = false;
if (cancel_pressed)
return;
***************
*** 476,484 ****
--- 481,494 ----
max_nl_lines[i] = nl_lines;
if (bytes_required > max_bytes[i])
max_bytes[i] = bytes_required;
+ if (nl_lines > extra_row_output_lines)
+ extra_row_output_lines = nl_lines;
width_header[i] = width;
}
+ /* Add height of tallest header column */
+ extra_output_lines += extra_row_output_lines;
+ extra_row_output_lines = 0;
/* scan all cells, find maximum width, compute cell_count */
for (i = 0, ptr = cont->cells; *ptr; ptr++, i++, cell_count++)
***************
*** 487,493 ****
nl_lines,
bytes_required;
- /* Get width, ignore nl_lines */
pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
&width, &nl_lines, &bytes_required);
if (opt_numeric_locale && cont->aligns[i % col_count] == 'r')
--- 497,502 ----
***************
*** 552,579 ****
for (i = 0; i < col_count; i++)
width_wrap[i] = max_width[i];
! if (cont->opt->format == PRINT_WRAPPED)
{
! /*
! * Choose target output width: \pset columns, or $COLUMNS, or ioctl
! */
! if (cont->opt->columns > 0)
! output_columns = cont->opt->columns;
! else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
! {
! if (cont->opt->env_columns > 0)
! output_columns = cont->opt->env_columns;
#ifdef TIOCGWINSZ
! else
! {
! struct winsize screen_size;
!
! if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
! output_columns = screen_size.ws_col;
! }
! #endif
}
/*
* Optional optimized word wrap. Shrink columns with a high max/avg
* ratio. Slighly bias against wider columns. (Increases chance a
--- 561,588 ----
for (i = 0; i < col_count; i++)
width_wrap[i] = max_width[i];
! /*
! * Choose target output width: \pset columns, or $COLUMNS, or ioctl
! */
! if (cont->opt->columns > 0)
! output_columns = cont->opt->columns;
! else if ((fout == stdout && isatty(fileno(stdout))) || is_pager)
{
! if (cont->opt->env_columns > 0)
! output_columns = cont->opt->env_columns;
#ifdef TIOCGWINSZ
! else
! {
! struct winsize screen_size;
!
! if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1)
! output_columns = screen_size.ws_col;
}
+ #endif
+ }
+ if (cont->opt->format == PRINT_WRAPPED)
+ {
/*
* Optional optimized word wrap. Shrink columns with a high max/avg
* ratio. Slighly bias against wider columns. (Increases chance a
***************
*** 623,628 ****
--- 632,680 ----
}
}
+ /* If we wrapped beyond the display width, use the pager */
+ if (!is_pager && output_columns > 0 &&
+ (output_columns < total_header_width || output_columns < width_total))
+ {
+ fout = PageOutput(INT_MAX, cont->opt->pager); /* force pager */
+ is_pager = true;
+ }
+
+ /* Check if newlines or our wrapping now need the pager */
+ if (!is_pager)
+ {
+ /* scan all cells, find maximum width, compute cell_count */
+ for (i = 0, ptr = cont->cells; *ptr; ptr++, i++, cell_count++)
+ {
+ int width,
+ nl_lines,
+ bytes_required;
+
+ pg_wcssize((unsigned char *) *ptr, strlen(*ptr), encoding,
+ &width, &nl_lines, &bytes_required);
+ if (opt_numeric_locale && cont->align[i % col_count] == 'r')
+ width += additional_numeric_locale_len(*ptr);
+
+ /*
+ * A row can have both wrapping and newlines that cause
+ * it to display across multiple lines. We check
+ * for both cases below.
+ */
+ if (width > 0 && width_wrap[i] &&
+ (width-1) / width_wrap[i] + nl_lines > extra_row_output_lines)
+ extra_row_output_lines = (width-1) / width_wrap[i] + nl_lines;
+
+ /* If last column, add tallest column height */
+ if (i % col_count == col_count - 1)
+ {
+ /* Add height of tallest row */
+ extra_output_lines += extra_row_output_lines;
+ extra_row_output_lines = 0;
+ }
+ }
+ IsPagerNeeded(cont, extra_output_lines, &fout, &is_pager);
+ }
+
/* time to output */
if (cont->opt->start_table)
{
***************
*** 882,887 ****
--- 934,942 ----
for (i = 0; i < col_count; i++)
free(format_buf[i]);
free(format_buf);
+
+ if (is_pager)
+ ClosePager(fout);
}
***************
*** 2115,2135 ****
}
/*
! * Use this to print just any table in the supported formats.
*/
void
! printTable(const printTableContent *cont, FILE *fout, FILE *flog)
{
! FILE *output;
! bool is_pager = false;
!
! if (cancel_pressed)
! return;
!
! if (cont->opt->format == PRINT_NOTHING)
! return;
!
! if (fout == stdout)
{
int lines;
--- 2170,2184 ----
}
/*
! * IsPagerNeeded
! *
! * Setup pager if required
*/
void
! IsPagerNeeded(const printTableContent *cont, const int extra_lines, FILE **fout,
! bool *is_pager)
{
! if (*fout == stdout)
{
int lines;
***************
*** 2150,2207 ****
lines++;
}
! output = PageOutput(lines, cont->opt->pager);
! is_pager = (output != fout);
}
else
! output = fout;
/* print the stuff */
if (flog)
! print_aligned_text(cont, is_pager, flog);
switch (cont->opt->format)
{
case PRINT_UNALIGNED:
if (cont->opt->expanded)
! print_unaligned_vertical(cont, output);
else
! print_unaligned_text(cont, output);
break;
case PRINT_ALIGNED:
case PRINT_WRAPPED:
if (cont->opt->expanded)
! print_aligned_vertical(cont, output);
else
! print_aligned_text(cont, is_pager, output);
break;
case PRINT_HTML:
if (cont->opt->expanded)
! print_html_vertical(cont, output);
else
! print_html_text(cont, output);
break;
case PRINT_LATEX:
if (cont->opt->expanded)
! print_latex_vertical(cont, output);
else
! print_latex_text(cont, output);
break;
case PRINT_TROFF_MS:
if (cont->opt->expanded)
! print_troff_ms_vertical(cont, output);
else
! print_troff_ms_text(cont, output);
break;
default:
! fprintf(stderr, _("invalid output format (internal error): %d"),
cont->opt->format);
exit(EXIT_FAILURE);
}
if (is_pager)
! ClosePager(output);
}
/*
--- 2199,2277 ----
lines++;
}
! *fout = PageOutput(lines + extra_lines, cont->opt->pager);
! *is_pager = (*fout != stdout);
}
else
! *is_pager = false;
! }
!
! /*
! * Use this to print just any table in the supported formats.
! */
! void
! printTable(const printTableContent *cont, FILE *fout, FILE *flog)
! {
! bool is_pager = false;
!
! if (cancel_pressed)
! return;
!
! 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 the stuff */
if (flog)
! print_aligned_text(cont, flog);
switch (cont->opt->format)
{
case PRINT_UNALIGNED:
if (cont->opt->expanded)
! print_unaligned_vertical(cont, fout);
else
! print_unaligned_text(cont, fout);
break;
case PRINT_ALIGNED:
case PRINT_WRAPPED:
if (cont->opt->expanded)
! print_aligned_vertical(cont, fout);
else
! print_aligned_text(cont, fout);
break;
case PRINT_HTML:
if (cont->opt->expanded)
! print_html_vertical(cont, fout);
else
! print_html_text(cont, fout);
break;
case PRINT_LATEX:
if (cont->opt->expanded)
! print_latex_vertical(cont, fout);
else
! print_latex_text(cont, fout);
break;
case PRINT_TROFF_MS:
if (cont->opt->expanded)
! print_troff_ms_vertical(cont, fout);
else
! print_troff_ms_text(cont, fout);
break;
default:
! fprintf(stderr, _("invalid fout format (internal error): %d"),
cont->opt->format);
exit(EXIT_FAILURE);
}
if (is_pager)
! ClosePager(fout);
}
/*