Fix further concerns about psql wrapping in expanded mode having

collateral damage on other formats, by Sergey Muraviov.
This commit is contained in:
Greg Stark 2014-08-18 12:06:11 +01:00
parent 48d50840d5
commit 458ef6bad1
3 changed files with 1757 additions and 434 deletions

View File

@ -1160,7 +1160,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
dformatsize = 0; dformatsize = 0;
struct lineptr *hlineptr, struct lineptr *hlineptr,
*dlineptr; *dlineptr;
bool is_pager = false; bool is_pager = false,
hmultiline = false,
dmultiline = false;
int output_columns = 0; /* Width of interactive console */ int output_columns = 0; /* Width of interactive console */
if (cancel_pressed) if (cancel_pressed)
@ -1196,7 +1198,10 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (width > hwidth) if (width > hwidth)
hwidth = width; hwidth = width;
if (height > hheight) if (height > hheight)
{
hheight = height; hheight = height;
hmultiline = true;
}
if (fs > hformatsize) if (fs > hformatsize)
hformatsize = fs; hformatsize = fs;
} }
@ -1213,7 +1218,10 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (width > dwidth) if (width > dwidth)
dwidth = width; dwidth = width;
if (height > dheight) if (height > dheight)
{
dheight = height; dheight = height;
dmultiline = true;
}
if (fs > dformatsize) if (fs > dformatsize)
dformatsize = fs; dformatsize = fs;
} }
@ -1258,45 +1266,82 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
if (cont->opt->format == PRINT_WRAPPED) if (cont->opt->format == PRINT_WRAPPED)
{ {
/* /*
* Calculate the available width to wrap the columns to after * Separators width
* subtracting the maximum header width and separators. At a minimum
* enough to print "[ RECORD N ]"
*/ */
unsigned int width, unsigned int width,
swidth; min_width,
swidth,
iwidth = 0;
if (opt_border == 0) if (opt_border == 0)
swidth = 1; /* "header data" */
else if (opt_border == 1)
swidth = 3; /* "header | data" */
else
swidth = 7; /* "| header | data |" */
/* Wrap to maximum width */
width = dwidth + swidth + hwidth;
if ((output_columns > 0) && (width > output_columns))
{ {
dwidth = output_columns - hwidth - swidth; /*
width = output_columns; * For border = 0, one space in the middle.
*/
swidth = 1;
}
else if (opt_border == 1)
{
/*
* For border = 1, one for the pipe (|) in the middle
* between the two spaces.
*/
swidth = 3;
}
else
/*
* For border = 2, two more for the pipes (|) at the begging and
* at the end of the lines.
*/
swidth = 7;
if ((opt_border < 2) &&
((hmultiline &&
(format == &pg_asciiformat_old)) ||
(dmultiline &&
(format != &pg_asciiformat_old))))
iwidth++; /* for newline indicators */
min_width = hwidth + iwidth + swidth + 3;
/*
* Record header width
*/
if (!opt_tuples_only)
{
/*
* Record number
*/
unsigned int rwidth = 1 + log10(cont->nrows);
if (opt_border == 0)
rwidth += 9; /* "* RECORD " */
else if (opt_border == 1)
rwidth += 12; /* "-[ RECORD ]" */
else
rwidth += 15; /* "+-[ RECORD ]-+" */
if (rwidth > min_width)
min_width = rwidth;
} }
/* Wrap to minimum width */ /* Wrap to minimum width */
if (!opt_tuples_only) width = hwidth + iwidth + swidth + dwidth;
if ((width < min_width) || (output_columns < min_width))
width = min_width - hwidth - iwidth - swidth;
else if (output_columns > 0)
/*
* Wrap to maximum width
*/
width = output_columns - hwidth - iwidth - swidth;
if ((width < dwidth) || (dheight > 1))
{ {
int delta = 1 + log10(cont->nrows) - width; dmultiline = true;
if ((opt_border == 0) &&
if (opt_border == 0) (format != &pg_asciiformat_old))
delta += 6; /* "* RECORD " */ width--; /* for wrap indicators */
else if (opt_border == 1)
delta += 10; /* "-[ RECORD ]" */
else
delta += 15; /* "+-[ RECORD ]-+" */
if (delta > 0)
dwidth += delta;
} }
else if (dwidth < 3) dwidth = width;
dwidth = 3;
} }
/* print records */ /* print records */
@ -1321,11 +1366,17 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
/* Print record header (e.g. "[ RECORD N ]") above each record */ /* Print record header (e.g. "[ RECORD N ]") above each record */
if (i % cont->ncolumns == 0) if (i % cont->ncolumns == 0)
{ {
unsigned int lhwidth = hwidth;
if ((opt_border < 2) &&
(hmultiline) &&
(format == &pg_asciiformat_old))
lhwidth++; /* for newline indicators */
if (!opt_tuples_only) if (!opt_tuples_only)
print_aligned_vertical_line(cont, record++, hwidth, dwidth, print_aligned_vertical_line(cont, record++, lhwidth,
pos, fout); dwidth, pos, fout);
else if (i != 0 || !cont->opt->start_table || opt_border == 2) else if (i != 0 || !cont->opt->start_table || opt_border == 2)
print_aligned_vertical_line(cont, 0, hwidth, dwidth, print_aligned_vertical_line(cont, 0, lhwidth, dwidth,
pos, fout); pos, fout);
} }
@ -1354,35 +1405,62 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
/* Header (never wrapped so just need to deal with newlines) */ /* Header (never wrapped so just need to deal with newlines) */
if (!hcomplete) if (!hcomplete)
{ {
int swidth, int swidth = hwidth,
twidth = hwidth + 1; target_width = hwidth;
/*
fputs(hline ? format->header_nl_left : " ", fout); * Left spacer or new line indicator
strlen_max_width(hlineptr[hline].ptr, &twidth, */
if ((opt_border == 2) ||
(hmultiline && (format == &pg_asciiformat_old)))
fputs(hline ? format->header_nl_left : " ", fout);
/*
* Header text
*/
strlen_max_width(hlineptr[hline].ptr, &target_width,
encoding); encoding);
fprintf(fout, "%-s", hlineptr[hline].ptr); fprintf(fout, "%-s", hlineptr[hline].ptr);
swidth = hwidth - twidth; /*
if (swidth > 0) /* spacer */ * Spacer
*/
swidth -= target_width;
if (swidth > 0)
fprintf(fout, "%*s", swidth, " "); fprintf(fout, "%*s", swidth, " ");
/*
* New line indicator or separator's space
*/
if (hlineptr[hline + 1].ptr) if (hlineptr[hline + 1].ptr)
{ {
/* More lines after this one due to a newline */ /* More lines after this one due to a newline */
fputs(format->header_nl_right, fout); if ((opt_border > 0) ||
(hmultiline && (format != &pg_asciiformat_old)))
fputs(format->header_nl_right, fout);
hline++; hline++;
} }
else else
{ {
/* This was the last line of the header */ /* This was the last line of the header */
fputs(" ", fout); if ((opt_border > 0) ||
(hmultiline && (format != &pg_asciiformat_old)))
fputs(" ", fout);
hcomplete = 1; hcomplete = 1;
} }
} }
else else
{ {
/* Header exhausted but more data for column */ unsigned int swidth = hwidth + opt_border;
fprintf(fout, "%*s", hwidth + 2, ""); if ((opt_border < 2) &&
(hmultiline) &&
(format == &pg_asciiformat_old))
swidth++;
if ((opt_border == 0) &&
(format != &pg_asciiformat_old) &&
(hmultiline))
swidth++;
fprintf(fout, "%*s", swidth, " ");
} }
/* Separator */ /* Separator */
@ -1401,13 +1479,18 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
/* Data */ /* Data */
if (!dcomplete) if (!dcomplete)
{ {
int target_width, int target_width = dwidth,
bytes_to_output, bytes_to_output,
swidth; swidth = dwidth;
/*
* Left spacer on wrap indicator
*/
fputs(!dcomplete && !offset ? " " : format->wrap_left, fout); fputs(!dcomplete && !offset ? " " : format->wrap_left, fout);
target_width = dwidth; /*
* Data text
*/
bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset, bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset,
&target_width, encoding); &target_width, encoding);
fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset), fputnbytes(fout, (char *) (dlineptr[dline].ptr + offset),
@ -1416,20 +1499,30 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
chars_to_output -= target_width; chars_to_output -= target_width;
offset += bytes_to_output; offset += bytes_to_output;
/* spacer */ /* Spacer */
swidth = dwidth - target_width; swidth -= target_width;
if (swidth > 0)
fprintf(fout, "%*s", swidth, "");
if (chars_to_output) if (chars_to_output)
{ {
/* continuing a wrapped column */ /* continuing a wrapped column */
fputs(format->wrap_right, fout); if ((opt_border > 1) ||
(dmultiline && (format != &pg_asciiformat_old)))
{
if (swidth > 0)
fprintf(fout, "%*s", swidth, " ");
fputs(format->wrap_right, fout);
}
} }
else if (dlineptr[dline + 1].ptr) else if (dlineptr[dline + 1].ptr)
{ {
/* reached a newline in the column */ /* reached a newline in the column */
fputs(format->nl_right, fout); if ((opt_border > 1) ||
(dmultiline && (format != &pg_asciiformat_old)))
{
if (swidth > 0)
fprintf(fout, "%*s", swidth, " ");
fputs(format->nl_right, fout);
}
dline++; dline++;
offset = 0; offset = 0;
chars_to_output = dlineptr[dline].width; chars_to_output = dlineptr[dline].width;
@ -1437,10 +1530,16 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
else else
{ {
/* reached the end of the cell */ /* reached the end of the cell */
fputs(" ", fout); if (opt_border > 1)
{
if (swidth > 0)
fprintf(fout, "%*s", swidth, " ");
fputs(" ", fout);
}
dcomplete = 1; dcomplete = 1;
} }
/* Right border */
if (opt_border == 2) if (opt_border == 2)
fputs(dformat->rightvrule, fout); fputs(dformat->rightvrule, fout);

File diff suppressed because it is too large Load Diff

View File

@ -42,10 +42,10 @@ select 10 as test01, 20 as test02 from generate_series(1,0) \gset
\pset \pset
-- test multi-line headers, wrapping, and newline indicators -- test multi-line headers, wrapping, and newline indicators
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "a prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab
b", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a c", array_to_string(array_agg(repeat('y',20-2*n)),E'\n') as "a
b" from generate_series(1,10) as n(n) group by n>1 ; bc" from generate_series(1,10) as n(n) group by n>1 ;
\pset linestyle ascii \pset linestyle ascii
@ -160,3 +160,119 @@ execute q;
execute q; execute q;
deallocate q; deallocate q;
-- test single-line header and data
prepare q as select repeat('x',2*n) as "0123456789abcdef", repeat('y',20-2*n) as "0123456789" from generate_series(1,10) as n;
\pset linestyle ascii
\pset expanded off
\pset columns 40
\pset border 0
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 1
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 2
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset expanded on
\pset columns 20
\pset border 0
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 1
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 2
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset linestyle old-ascii
\pset expanded off
\pset columns 40
\pset border 0
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 1
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 2
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset expanded on
\pset border 0
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 1
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
\pset border 2
\pset format unaligned
execute q;
\pset format aligned
execute q;
\pset format wrapped
execute q;
deallocate q;