diff options
Diffstat (limited to 'src/bin/psql/print.c')
-rw-r--r-- | src/bin/psql/print.c | 127 |
1 files changed, 76 insertions, 51 deletions
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index ad4350e1fe0..b53e81be379 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -1346,88 +1346,115 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) #endif } + /* + * Calculate available width for data in wrapped mode + */ if (cont->opt->format == PRINT_WRAPPED) { - /* - * Separators width - */ - unsigned int width, - min_width, - swidth, - iwidth = 0; + unsigned int swidth, + rwidth = 0, + newdwidth; if (opt_border == 0) { /* - * For border = 0, one space in the middle. + * For border = 0, one space in the middle. (If we discover we + * need to wrap, the spacer column will be replaced by a wrap + * marker, and we'll make room below for another wrap marker at + * the end of the line. But for now, assume no wrap is needed.) */ swidth = 1; + + /* We might need a column for header newline markers, too */ + if (hmultiline) + swidth++; } else if (opt_border == 1) { /* - * For border = 1, one for the pipe (|) in the middle between the - * two spaces. + * For border = 1, two spaces and a vrule in the middle. (As + * above, we might need one more column for a wrap marker.) */ swidth = 3; + + /* We might need a column for left header newline markers, too */ + if (hmultiline && (format == &pg_asciiformat_old)) + swidth++; } else - + { /* - * For border = 2, two more for the pipes (|) at the beginning and - * at the end of the lines. + * For border = 2, two more for the vrules at the beginning and + * end of the lines, plus spacer columns adjacent to these. (We + * won't need extra columns for wrap/newline markers, we'll just + * repurpose the spacers.) */ 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; + /* Reserve a column for data newline indicators, too, if needed */ + if (dmultiline && + opt_border < 2 && format != &pg_asciiformat_old) + swidth++; - /* - * Record header width - */ + /* Determine width required for record header lines */ if (!opt_tuples_only) { - /* - * Record number - */ - unsigned int rwidth = 1 + log10(cont->nrows); - + rwidth = 1 + log10(cont->nrows); if (opt_border == 0) rwidth += 9; /* "* RECORD " */ else if (opt_border == 1) rwidth += 12; /* "-[ RECORD ]" */ else rwidth += 15; /* "+-[ RECORD ]-+" */ + } + + /* We might need to do the rest of the calculation twice */ + for (;;) + { + unsigned int width, + min_width; + + /* Total width required to not wrap data */ + width = hwidth + swidth + dwidth; + /* Minimum acceptable width: room for just 3 columns of data */ + min_width = hwidth + swidth + 3; + /* ... but not less than what the record header lines need */ if (rwidth > min_width) min_width = rwidth; - } - /* Wrap to minimum width */ - width = hwidth + iwidth + swidth + dwidth; - if ((width < min_width) || (output_columns < min_width)) - width = min_width - hwidth - iwidth - swidth; - else if (output_columns > 0) + if (width < min_width || output_columns < min_width) + { + /* Set data width to match min_width */ + newdwidth = min_width - hwidth - swidth; + } + else if (output_columns > 0) + { + /* Set data width to match output_columns */ + newdwidth = output_columns - hwidth - swidth; + } + else + { + /* Use native data width */ + newdwidth = dwidth; + } /* - * Wrap to maximum width + * If we will need to wrap data and didn't already allocate a data + * newline/wrap marker column, do so and recompute. */ - width = output_columns - hwidth - iwidth - swidth; - - if ((width < dwidth) || (dheight > 1)) - { - dmultiline = true; - if ((opt_border == 0) && - (format != &pg_asciiformat_old)) - width--; /* for wrap indicators */ + if (newdwidth < dwidth && !dmultiline && + opt_border < 2 && format != &pg_asciiformat_old) + { + dmultiline = true; + swidth++; + } + else + break; } - dwidth = width; + + dwidth = newdwidth; } /* print records */ @@ -1558,12 +1585,10 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) { if (offset) fputs(format->midvrule_wrap, fout); - else if (!dline) + else if (dline == 0) fputs(dformat->midvrule, fout); - else if (dline) - fputs(format->midvrule_nl, fout); else - fputs(format->midvrule_blank, fout); + fputs(format->midvrule_nl, fout); } /* Data */ @@ -1574,9 +1599,9 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) swidth = dwidth; /* - * Left spacer on wrap indicator + * Left spacer or wrap indicator */ - fputs(!dcomplete && !offset ? " " : format->wrap_left, fout); + fputs(offset == 0 ? " " : format->wrap_left, fout); /* * Data text |