summaryrefslogtreecommitdiff
path: root/src/bin/psql/print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/psql/print.c')
-rw-r--r--src/bin/psql/print.c197
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);