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