diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c index 79fc43eeda3330873acbea4ad1c555e051e81d00..0ebffff2e35316b13b5c5db88e902727860767fa 100644 --- a/src/bin/psql/print.c +++ b/src/bin/psql/print.c @@ -1161,6 +1161,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) struct lineptr *hlineptr, *dlineptr; bool is_pager = false; + int output_columns = 0; /* Width of interactive console */ if (cancel_pressed) return; @@ -1234,24 +1235,86 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) fprintf(fout, "%s\n", cont->title); } + /* + * Choose target output width: \pset columns, or $COLUMNS, or ioctl + */ + if (cont->opt->columns > 0) + output_columns = cont->opt->columns; + else if ((fout == stdout && isatty(fileno(stdout))) || is_pager) + { + if (cont->opt->env_columns > 0) + output_columns = cont->opt->env_columns; +#ifdef TIOCGWINSZ + else + { + struct winsize screen_size; + + if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) != -1) + output_columns = screen_size.ws_col; + } +#endif + } + + 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 ]" */ + unsigned int width, swidth; + + if (opt_border == 0) + swidth = 1; /* "header data" */ + else if (opt_border == 1) + swidth = 3; /* "header | data" */ + else if (opt_border > 1) + 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; + } + + /* Wrap to minimum width */ + if (!opt_tuples_only) + { + int delta = 1 + log10(cont->nrows) - width; + if (opt_border == 0) + delta += 6; /* "* RECORD " */ + else if (opt_border == 1) + delta += 10; /* "-[ RECORD ]" */ + else if (opt_border == 2) + delta += 15; /* "+-[ RECORD ]-+" */ + + if (delta > 0) + dwidth += delta; + } + else if (dwidth < 3) + dwidth = 3; + } + /* print records */ for (i = 0, ptr = cont->cells; *ptr; i++, ptr++) { printTextRule pos; - int line_count, + int dline, + hline, dcomplete, - hcomplete; + hcomplete, + offset, + chars_to_output; if (cancel_pressed) break; if (i == 0) pos = PRINT_RULE_TOP; - else if (!(*(ptr + 1))) - pos = PRINT_RULE_BOTTOM; else pos = PRINT_RULE_MIDDLE; + /* Print record header (e.g. "[ RECORD N ]") above each record */ if (i % cont->ncolumns == 0) { if (!opt_tuples_only) @@ -1270,48 +1333,120 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout) pg_wcsformat((const unsigned char *) *ptr, strlen(*ptr), encoding, dlineptr, dheight); - line_count = 0; + /* Loop through header and data in parallel dealing with newlines and + * wrapped lines until they're both exhausted */ + dline = hline = 0; dcomplete = hcomplete = 0; + offset = 0; + chars_to_output = dlineptr[dline].width; while (!dcomplete || !hcomplete) { + /* Left border */ if (opt_border == 2) - fprintf(fout, "%s ", dformat->leftvrule); + fprintf(fout, "%s", dformat->leftvrule); + + /* Header (never wrapped so just need to deal with newlines) */ if (!hcomplete) { - fprintf(fout, "%-s%*s", hlineptr[line_count].ptr, - hwidth - hlineptr[line_count].width, ""); + int swidth, twidth = hwidth + 1; + fputs(hline? format->header_nl_left: " ", fout); + strlen_max_width((char *) hlineptr[hline].ptr, &twidth, + encoding); + fprintf(fout, "%-s", hlineptr[hline].ptr); + + swidth = hwidth - twidth; + if (swidth > 0) /* spacer */ + fprintf(fout, "%*s", swidth, " "); - if (!hlineptr[line_count + 1].ptr) + if (hlineptr[hline + 1].ptr) + { + /* More lines after this one due to a newline */ + fputs(format->header_nl_right, fout); + hline++; + } + else + { + /* This was the last line of the header */ + fputs(" ", fout); hcomplete = 1; + } } else - fprintf(fout, "%*s", hwidth, ""); + { + /* Header exhausted but more data for column */ + fprintf(fout, "%*s", hwidth + 2, ""); + } + /* Separator */ if (opt_border > 0) - fprintf(fout, " %s ", dformat->midvrule); - else - fputc(' ', fout); + { + if (offset) + fputs(format->midvrule_wrap, fout); + else if (!dline) + fputs(dformat->midvrule, fout); + else if (dline) + fputs(format->midvrule_nl, fout); + else + fputs(format->midvrule_blank, fout); + } + /* Data */ if (!dcomplete) { - if (opt_border < 2) - fprintf(fout, "%s\n", dlineptr[line_count].ptr); - else - fprintf(fout, "%-s%*s %s\n", dlineptr[line_count].ptr, - dwidth - dlineptr[line_count].width, "", - dformat->rightvrule); + int target_width, + bytes_to_output, + swidth; + + fputs(!dcomplete && !offset? " ": format->wrap_left, fout); - if (!dlineptr[line_count + 1].ptr) + target_width = dwidth; + bytes_to_output = strlen_max_width(dlineptr[dline].ptr + offset, + &target_width, encoding); + fputnbytes(fout, (char *)(dlineptr[dline].ptr + offset), + bytes_to_output); + + chars_to_output -= target_width; + offset += bytes_to_output; + + /* spacer */ + swidth = dwidth - target_width; + if (swidth > 0) + fprintf(fout, "%*s", swidth, ""); + + if (chars_to_output) + { + /* continuing a wrapped column */ + fputs(format->wrap_right, fout); + } + else if (dlineptr[dline + 1].ptr) + { + /* reached a newline in the column */ + fputs(format->nl_right, fout); + dline++; + offset = 0; + chars_to_output = dlineptr[dline].width; + } + else + { + /* reached the end of the cell */ + fputs(" ", fout); dcomplete = 1; + } + + if (opt_border == 2) + fputs(dformat->rightvrule, fout); + + fputs("\n", fout); } else { + /* data exhausted (this can occur if header is longer than the + * data due to newlines in the header) */ if (opt_border < 2) - fputc('\n', fout); + fputs("\n", fout); else - fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule); + fprintf(fout, "%*s %s\n", dwidth, "", dformat->rightvrule); } - line_count++; } } diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 2bbee7df004ee32c507626ecbd04c072d69cdcbc..c7dbd543071b49b214f608fa0a27f8c0a59fcd47 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -68,3 +68,947 @@ Record separator (recordsep) is <newline>. Table attributes (tableattr) unset. Title (title) unset. Tuples only (tuples_only) is off. +-- 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 + +b", 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 ; +\pset linestyle ascii +\pset expanded off +\pset columns 40 +\pset border 0 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; + a + a + + + b + b +-------------------- ------------------ +xx yyyyyyyyyyyyyyyyyy +xxxx +yyyyyyyyyyyyyyyy + +xxxxxx +yyyyyyyyyyyyyy + +xxxxxxxx +yyyyyyyyyyyy + +xxxxxxxxxx +yyyyyyyyyy + +xxxxxxxxxxxx +yyyyyyyy + +xxxxxxxxxxxxxx +yyyyyy + +xxxxxxxxxxxxxxxx +yyyy + +xxxxxxxxxxxxxxxxxx +yy + +xxxxxxxxxxxxxxxxxxxx +(2 rows) + +\pset format wrapped +execute q; + a + a + + + b + b +-------------------- ------------------ +xx yyyyyyyyyyyyyyyyyy +xxxx +yyyyyyyyyyyyyyyy + +xxxxxx +yyyyyyyyyyyyyy + +xxxxxxxx +yyyyyyyyyyyy + +xxxxxxxxxx +yyyyyyyyyy + +xxxxxxxxxxxx +yyyyyyyy + +xxxxxxxxxxxxxx +yyyyyy + +xxxxxxxxxxxxxxxx +yyyy + +xxxxxxxxxxxxxxxxxx +yy + +xxxxxxxxxxxxxxxxxxxx +(2 rows) + +\pset border 1 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; + a +| a + + +| b + b | +----------------------+-------------------- + xx | yyyyyyyyyyyyyyyyyy + xxxx +| yyyyyyyyyyyyyyyy + + xxxxxx +| yyyyyyyyyyyyyy + + xxxxxxxx +| yyyyyyyyyyyy + + xxxxxxxxxx +| yyyyyyyyyy + + xxxxxxxxxxxx +| yyyyyyyy + + xxxxxxxxxxxxxx +| yyyyyy + + xxxxxxxxxxxxxxxx +| yyyy + + xxxxxxxxxxxxxxxxxx +| yy + + xxxxxxxxxxxxxxxxxxxx | +(2 rows) + +\pset format wrapped +execute q; + a +| a + + +| b + b | +-------------------+-------------------- + xx | yyyyyyyyyyyyyyyyyy + xxxx +| yyyyyyyyyyyyyyyy + + xxxxxx +| yyyyyyyyyyyyyy + + xxxxxxxx +| yyyyyyyyyyyy + + xxxxxxxxxx +| yyyyyyyyyy + + xxxxxxxxxxxx +| yyyyyyyy + + xxxxxxxxxxxxxx +| yyyyyy + + xxxxxxxxxxxxxxxx +| yyyy + + xxxxxxxxxxxxxxxxx.| yy + +.x +| + xxxxxxxxxxxxxxxxx.| +.xxx | +(2 rows) + +\pset border 2 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; ++----------------------+--------------------+ +| a +| a +| +| +| b | +| b | | ++----------------------+--------------------+ +| xx | yyyyyyyyyyyyyyyyyy | +| xxxx +| yyyyyyyyyyyyyyyy +| +| xxxxxx +| yyyyyyyyyyyyyy +| +| xxxxxxxx +| yyyyyyyyyyyy +| +| xxxxxxxxxx +| yyyyyyyyyy +| +| xxxxxxxxxxxx +| yyyyyyyy +| +| xxxxxxxxxxxxxx +| yyyyyy +| +| xxxxxxxxxxxxxxxx +| yyyy +| +| xxxxxxxxxxxxxxxxxx +| yy +| +| xxxxxxxxxxxxxxxxxxxx | | ++----------------------+--------------------+ +(2 rows) + +\pset format wrapped +execute q; ++-----------------+--------------------+ +| a +| a +| +| +| b | +| b | | ++-----------------+--------------------+ +| xx | yyyyyyyyyyyyyyyyyy | +| xxxx +| yyyyyyyyyyyyyyyy +| +| xxxxxx +| yyyyyyyyyyyyyy +| +| xxxxxxxx +| yyyyyyyyyyyy +| +| xxxxxxxxxx +| yyyyyyyyyy +| +| xxxxxxxxxxxx +| yyyyyyyy +| +| xxxxxxxxxxxxxx +| yyyyyy +| +| xxxxxxxxxxxxxxx.| yyyy +| +|.x +| yy +| +| xxxxxxxxxxxxxxx.| | +|.xxx +| | +| xxxxxxxxxxxxxxx.| | +|.xxxxx | | ++-----------------+--------------------+ +(2 rows) + +\pset expanded on +\pset columns 20 +\pset border 0 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; +* Record 1 + a+ xx + + + b + a+ yyyyyyyyyyyyyyyyyy + b +* Record 2 + a+ xxxx + + + xxxxxx + + b xxxxxxxx + + xxxxxxxxxx + + xxxxxxxxxxxx + + xxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxxxxxx + a+ yyyyyyyyyyyyyyyy + + b yyyyyyyyyyyyyy + + yyyyyyyyyyyy + + yyyyyyyyyy + + yyyyyyyy + + yyyyyy + + yyyy + + yy + + + +\pset format wrapped +execute q; +* Record 1 + a+ xx + + + b + a+ yyyyyyyyyyyyyyyyyy + b +* Record 2 + a+ xxxx + + + xxxxxx + + b xxxxxxxx + + xxxxxxxxxx + + xxxxxxxxxxxx + + xxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxx + + xxxxxxxxxxxxxxxxxx+ + xxxxxxxxxxxxxxxxxx. + .xx + a+ yyyyyyyyyyyyyyyy + + b yyyyyyyyyyyyyy + + yyyyyyyyyyyy + + yyyyyyyyyy + + yyyyyyyy + + yyyyyy + + yyyy + + yy + + + +\pset border 1 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; +-[ RECORD 1 ]----------- + a+| xx + +| + b | + a+| yyyyyyyyyyyyyyyyyy + b | +-[ RECORD 2 ]----------- + a+| xxxx + + +| xxxxxx + + b | xxxxxxxx + + | xxxxxxxxxx + + | xxxxxxxxxxxx + + | xxxxxxxxxxxxxx + + | xxxxxxxxxxxxxxxx + + | xxxxxxxxxxxxxxxxxx + + | xxxxxxxxxxxxxxxxxxxx + a+| yyyyyyyyyyyyyyyy + + b | yyyyyyyyyyyyyy + + | yyyyyyyyyyyy + + | yyyyyyyyyy + + | yyyyyyyy + + | yyyyyy + + | yyyy + + | yy + + | + +\pset format wrapped +execute q; +-[ RECORD 1 ]------- + a+| xx + +| + b | + a+| yyyyyyyyyyyyyyyy. + b |.yy +-[ RECORD 2 ]------- + a+| xxxx + + +| xxxxxx + + b | xxxxxxxx + + | xxxxxxxxxx + + | xxxxxxxxxxxx + + | xxxxxxxxxxxxxx + + | xxxxxxxxxxxxxxxx+ + | xxxxxxxxxxxxxxxx. + |.xx + + | xxxxxxxxxxxxxxxx. + |.xxxx + a+| yyyyyyyyyyyyyyyy+ + b | yyyyyyyyyyyyyy + + | yyyyyyyyyyyy + + | yyyyyyyyyy + + | yyyyyyyy + + | yyyyyy + + | yyyy + + | yy + + | + +\pset border 2 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; ++-[ RECORD 1 ]-------------+ +| a+| xx | +| +| | +| b | | +| a+| yyyyyyyyyyyyyyyyyy | +| b | | ++-[ RECORD 2 ]-------------+ +| a+| xxxx +| +| +| xxxxxx +| +| b | xxxxxxxx +| +| | xxxxxxxxxx +| +| | xxxxxxxxxxxx +| +| | xxxxxxxxxxxxxx +| +| | xxxxxxxxxxxxxxxx +| +| | xxxxxxxxxxxxxxxxxx +| +| | xxxxxxxxxxxxxxxxxxxx | +| a+| yyyyyyyyyyyyyyyy +| +| b | yyyyyyyyyyyyyy +| +| | yyyyyyyyyyyy +| +| | yyyyyyyyyy +| +| | yyyyyyyy +| +| | yyyyyy +| +| | yyyy +| +| | yy +| +| | | ++---+----------------------+ + +\pset format wrapped +execute q; ++-[ RECORD 1 ]-----+ +| a+| xx | +| +| | +| b | | +| a+| yyyyyyyyyyyy.| +| b |.yyyyyy | ++-[ RECORD 2 ]-----+ +| a+| xxxx +| +| +| xxxxxx +| +| b | xxxxxxxx +| +| | xxxxxxxxxx +| +| | xxxxxxxxxxxx+| +| | xxxxxxxxxxxx.| +| |.xx +| +| | xxxxxxxxxxxx.| +| |.xxxx +| +| | xxxxxxxxxxxx.| +| |.xxxxxx +| +| | xxxxxxxxxxxx.| +| |.xxxxxxxx | +| a+| yyyyyyyyyyyy.| +| b |.yyyy +| +| | yyyyyyyyyyyy.| +| |.yy +| +| | yyyyyyyyyyyy+| +| | yyyyyyyyyy +| +| | yyyyyyyy +| +| | yyyyyy +| +| | yyyy +| +| | yy +| +| | | ++---+--------------+ + +\pset linestyle old-ascii +\pset expanded off +\pset columns 40 +\pset border 0 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; + a a + + b + b + +-------------------- ------------------ +xx yyyyyyyyyyyyyyyyyy +xxxx yyyyyyyyyyyyyyyy +xxxxxx yyyyyyyyyyyyyy +xxxxxxxx yyyyyyyyyyyy +xxxxxxxxxx yyyyyyyyyy +xxxxxxxxxxxx yyyyyyyy +xxxxxxxxxxxxxx yyyyyy +xxxxxxxxxxxxxxxx yyyy +xxxxxxxxxxxxxxxxxx yy +xxxxxxxxxxxxxxxxxxxx +(2 rows) + +\pset format wrapped +execute q; + a a + + b + b + +-------------------- ------------------ +xx yyyyyyyyyyyyyyyyyy +xxxx yyyyyyyyyyyyyyyy +xxxxxx yyyyyyyyyyyyyy +xxxxxxxx yyyyyyyyyyyy +xxxxxxxxxx yyyyyyyyyy +xxxxxxxxxxxx yyyyyyyy +xxxxxxxxxxxxxx yyyyyy +xxxxxxxxxxxxxxxx yyyy +xxxxxxxxxxxxxxxxxx yy +xxxxxxxxxxxxxxxxxxxx +(2 rows) + +\pset border 1 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; + a | a ++ |+ b ++ b |+ +----------------------+-------------------- + xx | yyyyyyyyyyyyyyyyyy + xxxx | yyyyyyyyyyyyyyyy + xxxxxx : yyyyyyyyyyyyyy + xxxxxxxx : yyyyyyyyyyyy + xxxxxxxxxx : yyyyyyyyyy + xxxxxxxxxxxx : yyyyyyyy + xxxxxxxxxxxxxx : yyyyyy + xxxxxxxxxxxxxxxx : yyyy + xxxxxxxxxxxxxxxxxx : yy + xxxxxxxxxxxxxxxxxxxx : +(2 rows) + +\pset format wrapped +execute q; + a | a ++ |+ b ++ b |+ +-------------------+-------------------- + xx | yyyyyyyyyyyyyyyyyy + xxxx | yyyyyyyyyyyyyyyy + xxxxxx : yyyyyyyyyyyyyy + xxxxxxxx : yyyyyyyyyyyy + xxxxxxxxxx : yyyyyyyyyy + xxxxxxxxxxxx : yyyyyyyy + xxxxxxxxxxxxxx : yyyyyy + xxxxxxxxxxxxxxxx : yyyy + xxxxxxxxxxxxxxxxx : yy + x : + xxxxxxxxxxxxxxxxx + xxx +(2 rows) + +\pset border 2 +\pset format unaligned +execute q; +a + +b|a +b +xx|yyyyyyyyyyyyyyyyyy +xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +(2 rows) +\pset format aligned +execute q; ++----------------------+--------------------+ +| a | a | +|+ |+ b | +|+ b |+ | ++----------------------+--------------------+ +| xx | yyyyyyyyyyyyyyyyyy | +| xxxx | yyyyyyyyyyyyyyyy | +| xxxxxx : yyyyyyyyyyyyyy | +| xxxxxxxx : yyyyyyyyyyyy | +| xxxxxxxxxx : yyyyyyyyyy | +| xxxxxxxxxxxx : yyyyyyyy | +| xxxxxxxxxxxxxx : yyyyyy | +| xxxxxxxxxxxxxxxx : yyyy | +| xxxxxxxxxxxxxxxxxx : yy | +| xxxxxxxxxxxxxxxxxxxx : | ++----------------------+--------------------+ +(2 rows) + +\pset format wrapped +execute q; ++-----------------+--------------------+ +| a | a | +|+ |+ b | +|+ b |+ | ++-----------------+--------------------+ +| xx | yyyyyyyyyyyyyyyyyy | +| xxxx | yyyyyyyyyyyyyyyy | +| xxxxxx : yyyyyyyyyyyyyy | +| xxxxxxxx : yyyyyyyyyyyy | +| xxxxxxxxxx : yyyyyyyyyy | +| xxxxxxxxxxxx : yyyyyyyy | +| xxxxxxxxxxxxxx : yyyyyy | +| xxxxxxxxxxxxxxx : yyyy | +| x : yy | +| xxxxxxxxxxxxxxx : | +| xxx | +| xxxxxxxxxxxxxxx | +| xxxxx | ++-----------------+--------------------+ +(2 rows) + +\pset expanded on +\pset columns 20 +\pset border 0 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; +* Record 1 + a xx ++ ++b + a yyyyyyyyyyyyyyyyyy ++b +* Record 2 + a xxxx ++ xxxxxx ++b xxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxx + a yyyyyyyyyyyyyyyy ++b yyyyyyyyyyyyyy + yyyyyyyyyyyy + yyyyyyyyyy + yyyyyyyy + yyyyyy + yyyy + yy + + +\pset format wrapped +execute q; +* Record 1 + a xx ++ ++b + a yyyyyyyyyyyyyyyyyy ++b +* Record 2 + a xxxx ++ xxxxxx ++b xxxxxxxx + xxxxxxxxxx + xxxxxxxxxxxx + xxxxxxxxxxxxxx + xxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxx + xx + a yyyyyyyyyyyyyyyy ++b yyyyyyyyyyyyyy + yyyyyyyyyyyy + yyyyyyyyyy + yyyyyyyy + yyyyyy + yyyy + yy + + +\pset border 1 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; +-[ RECORD 1 ]----------- + a | xx ++ ; ++b ; + a | yyyyyyyyyyyyyyyyyy ++b ; +-[ RECORD 2 ]----------- + a | xxxx ++ : xxxxxx ++b : xxxxxxxx + : xxxxxxxxxx + : xxxxxxxxxxxx + : xxxxxxxxxxxxxx + : xxxxxxxxxxxxxxxx + : xxxxxxxxxxxxxxxxxx + : xxxxxxxxxxxxxxxxxxxx + a | yyyyyyyyyyyyyyyy ++b : yyyyyyyyyyyyyy + : yyyyyyyyyyyy + : yyyyyyyyyy + : yyyyyyyy + : yyyyyy + : yyyy + : yy + : + +\pset format wrapped +execute q; +-[ RECORD 1 ]------- + a | xx ++ ; ++b ; + a | yyyyyyyyyyyyyyyy ++b ; yy +-[ RECORD 2 ]------- + a | xxxx ++ : xxxxxx ++b : xxxxxxxx + : xxxxxxxxxx + : xxxxxxxxxxxx + : xxxxxxxxxxxxxx + : xxxxxxxxxxxxxxxx + : xxxxxxxxxxxxxxxx + ; xx + : xxxxxxxxxxxxxxxx + ; xxxx + a | yyyyyyyyyyyyyyyy ++b : yyyyyyyyyyyyyy + : yyyyyyyyyyyy + : yyyyyyyyyy + : yyyyyyyy + : yyyyyy + : yyyy + : yy + : + +\pset border 2 +\pset format unaligned +execute q; +a + +b|xx +a +b|yyyyyyyyyyyyyyyyyy + +a + +b|xxxx +xxxxxx +xxxxxxxx +xxxxxxxxxx +xxxxxxxxxxxx +xxxxxxxxxxxxxx +xxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxx +xxxxxxxxxxxxxxxxxxxx +a +b|yyyyyyyyyyyyyyyy +yyyyyyyyyyyyyy +yyyyyyyyyyyy +yyyyyyyyyy +yyyyyyyy +yyyyyy +yyyy +yy + +\pset format aligned +execute q; ++-[ RECORD 1 ]-------------+ +| a | xx | +|+ ; | +|+b ; | +| a | yyyyyyyyyyyyyyyyyy | +|+b ; | ++-[ RECORD 2 ]-------------+ +| a | xxxx | +|+ : xxxxxx | +|+b : xxxxxxxx | +| : xxxxxxxxxx | +| : xxxxxxxxxxxx | +| : xxxxxxxxxxxxxx | +| : xxxxxxxxxxxxxxxx | +| : xxxxxxxxxxxxxxxxxx | +| : xxxxxxxxxxxxxxxxxxxx | +| a | yyyyyyyyyyyyyyyy | +|+b : yyyyyyyyyyyyyy | +| : yyyyyyyyyyyy | +| : yyyyyyyyyy | +| : yyyyyyyy | +| : yyyyyy | +| : yyyy | +| : yy | +| : | ++---+----------------------+ + +\pset format wrapped +execute q; ++-[ RECORD 1 ]-----+ +| a | xx | +|+ ; | +|+b ; | +| a | yyyyyyyyyyyy | +|+b ; yyyyyy | ++-[ RECORD 2 ]-----+ +| a | xxxx | +|+ : xxxxxx | +|+b : xxxxxxxx | +| : xxxxxxxxxx | +| : xxxxxxxxxxxx | +| : xxxxxxxxxxxx | +| ; xx | +| : xxxxxxxxxxxx | +| ; xxxx | +| : xxxxxxxxxxxx | +| ; xxxxxx | +| : xxxxxxxxxxxx | +| ; xxxxxxxx | +| a | yyyyyyyyyyyy | +|+b ; yyyy | +| : yyyyyyyyyyyy | +| ; yy | +| : yyyyyyyyyyyy | +| : yyyyyyyyyy | +| : yyyyyyyy | +| : yyyyyy | +| : yyyy | +| : yy | +| : | ++---+--------------+ + +deallocate q; diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 99ad5b4a70b97398de8eabfd86524793c433992b..a7d5eeb587a8ad9bff87240cb8271fbff01731c3 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -40,3 +40,123 @@ select 10 as test01, 20 as test02 from generate_series(1,0) \gset -- show all pset options \pset + +-- 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 + +b", 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 ; + +\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 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; + +deallocate q;