Fix further concerns about psql wrapping in expanded mode having
collateral damage on other formats, by Sergey Muraviov.
This commit is contained in:
parent
48d50840d5
commit
458ef6bad1
@ -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
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user