Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit a45388d

Browse files
committed
Add xheader_width pset option to psql
The setting controls tha maximum length of the header line in expanded format output. Possible settings are full, column, page, or an integer. the default is full, the current behaviour, and in this case the header line is the length of the widest line of output. column causes the header to be truncated to the width of the first column, page causes it to be truncated to the width of the terminal page, and an integer causes it to be truncated to that value. If the full value is less than the page or integer value no truncation occurs. If given without an argument this option prints its current setting. Platon Pronko, somewhat modified by me. Discussion: https://postgr.es/m/f03d38a3-db96-a56e-d1bc-dbbc80bbde4d@gmail.com
1 parent b35617d commit a45388d

File tree

7 files changed

+164
-18
lines changed

7 files changed

+164
-18
lines changed

doc/src/sgml/ref/psql-ref.sgml

+33
Original file line numberDiff line numberDiff line change
@@ -2842,6 +2842,39 @@ lo_import 152801
28422842
</listitem>
28432843
</varlistentry>
28442844

2845+
<varlistentry>
2846+
<term><literal>xheader_width</literal></term>
2847+
<listitem>
2848+
<para>
2849+
Sets the maximum width of the header for expanded output to one of
2850+
<literal>full</literal> (the default value),
2851+
<literal>column</literal>, <literal>page</literal>, or an
2852+
<replaceable class="parameter">integer value</replaceable>.
2853+
</para>
2854+
2855+
<para>
2856+
<literal>full</literal>: the expanded header is not truncated,
2857+
and will be as wide as the widest output
2858+
line.
2859+
</para>
2860+
2861+
<para>
2862+
<literal>column</literal>: truncate the header line at the
2863+
width of the first column.
2864+
</para>
2865+
2866+
<para>
2867+
<literal>page</literal>: truncate the the header line at the terminal
2868+
width.
2869+
</para>
2870+
2871+
<para>
2872+
<replaceable class="parameter">integer value</replaceable>: specify
2873+
the exact maximum width of the header line.
2874+
</para>
2875+
</listitem>
2876+
</varlistentry>
2877+
28452878
<varlistentry>
28462879
<term><literal>fieldsep</literal></term>
28472880
<listitem>

src/bin/psql/command.c

+54
Original file line numberDiff line numberDiff line change
@@ -2244,6 +2244,7 @@ exec_command_pset(PsqlScanState scan_state, bool active_branch)
22442244
"unicode_border_linestyle",
22452245
"unicode_column_linestyle",
22462246
"unicode_header_linestyle",
2247+
"xheader_width",
22472248
NULL
22482249
};
22492250

@@ -4369,6 +4370,29 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
43694370
popt->topt.expanded = !popt->topt.expanded;
43704371
}
43714372

4373+
/* header line width in expanded mode */
4374+
else if (strcmp(param, "xheader_width") == 0)
4375+
{
4376+
if (! value)
4377+
;
4378+
else if (pg_strcasecmp(value, "full") == 0)
4379+
popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL;
4380+
else if (pg_strcasecmp(value, "column") == 0)
4381+
popt->topt.expanded_header_width_type = PRINT_XHEADER_COLUMN;
4382+
else if (pg_strcasecmp(value, "page") == 0)
4383+
popt->topt.expanded_header_width_type = PRINT_XHEADER_PAGE;
4384+
else
4385+
{
4386+
popt->topt.expanded_header_width_type = PRINT_XHEADER_EXACT_WIDTH;
4387+
popt->topt.expanded_header_exact_width = atoi(value);
4388+
if (popt->topt.expanded_header_exact_width == 0)
4389+
{
4390+
pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or a number specifying the exact width.");
4391+
return false;
4392+
}
4393+
}
4394+
}
4395+
43724396
/* field separator for CSV format */
43734397
else if (strcmp(param, "csv_fieldsep") == 0)
43744398
{
@@ -4561,6 +4585,19 @@ printPsetInfo(const char *param, printQueryOpt *popt)
45614585
printf(_("Expanded display is off.\n"));
45624586
}
45634587

4588+
/* show xheader width value */
4589+
else if (strcmp(param, "xheader_width") == 0)
4590+
{
4591+
if (popt->topt.expanded_header_width_type == PRINT_XHEADER_FULL)
4592+
printf(_("Expanded header width is 'full'.\n"));
4593+
else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_COLUMN)
4594+
printf(_("Expanded header width is 'column'.\n"));
4595+
else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_PAGE)
4596+
printf(_("Expanded header width is 'page'.\n"));
4597+
else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_EXACT_WIDTH)
4598+
printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width);
4599+
}
4600+
45644601
/* show field separator for CSV format */
45654602
else if (strcmp(param, "csv_fieldsep") == 0)
45664603
{
@@ -4881,6 +4918,23 @@ pset_value_string(const char *param, printQueryOpt *popt)
48814918
return pstrdup(_unicode_linestyle2string(popt->topt.unicode_column_linestyle));
48824919
else if (strcmp(param, "unicode_header_linestyle") == 0)
48834920
return pstrdup(_unicode_linestyle2string(popt->topt.unicode_header_linestyle));
4921+
else if (strcmp(param, "xheader_width") == 0)
4922+
{
4923+
if (popt->topt.expanded_header_width_type == PRINT_XHEADER_FULL)
4924+
return(pstrdup("full"));
4925+
else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_COLUMN)
4926+
return(pstrdup("column"));
4927+
else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_PAGE)
4928+
return(pstrdup("page"));
4929+
else
4930+
{
4931+
/* must be PRINT_XHEADER_EXACT_WIDTH */
4932+
char wbuff[32];
4933+
snprintf(wbuff, sizeof(wbuff), "%d",
4934+
popt->topt.expanded_header_exact_width);
4935+
return pstrdup(wbuff);
4936+
}
4937+
}
48844938
else
48854939
return pstrdup("ERROR");
48864940
}

src/bin/psql/tab-complete.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -4654,13 +4654,16 @@ psql_completion(const char *text, int start, int end)
46544654
"tableattr", "title", "tuples_only",
46554655
"unicode_border_linestyle",
46564656
"unicode_column_linestyle",
4657-
"unicode_header_linestyle");
4657+
"unicode_header_linestyle",
4658+
"xheader_width");
46584659
else if (TailMatchesCS("\\pset", MatchAny))
46594660
{
46604661
if (TailMatchesCS("format"))
46614662
COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex",
46624663
"latex-longtable", "troff-ms", "unaligned",
46634664
"wrapped");
4665+
else if (TailMatchesCS("xheader_width"))
4666+
COMPLETE_WITH_CS("full", "column", "page");
46644667
else if (TailMatchesCS("linestyle"))
46654668
COMPLETE_WITH_CS("ascii", "old-ascii", "unicode");
46664669
else if (TailMatchesCS("pager"))

src/fe_utils/print.c

+60-17
Original file line numberDiff line numberDiff line change
@@ -1222,15 +1222,16 @@ print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
12221222

12231223

12241224
static void
1225-
print_aligned_vertical_line(const printTextFormat *format,
1226-
const unsigned short opt_border,
1225+
print_aligned_vertical_line(const printTableOpt *topt,
12271226
unsigned long record,
12281227
unsigned int hwidth,
12291228
unsigned int dwidth,
1229+
int output_columns,
12301230
printTextRule pos,
12311231
FILE *fout)
12321232
{
1233-
const printTextLineFormat *lformat = &format->lrule[pos];
1233+
const printTextLineFormat *lformat = &get_line_style(topt)->lrule[pos];
1234+
const unsigned short opt_border = topt->border;
12341235
unsigned int i;
12351236
int reclen = 0;
12361237

@@ -1259,21 +1260,62 @@ print_aligned_vertical_line(const printTextFormat *format,
12591260
if (reclen-- <= 0)
12601261
fputs(lformat->hrule, fout);
12611262
if (reclen-- <= 0)
1262-
fputs(lformat->midvrule, fout);
1263-
if (reclen-- <= 0)
1263+
{
1264+
if (topt->expanded_header_width_type == PRINT_XHEADER_COLUMN)
1265+
{
1266+
fputs(lformat->rightvrule, fout);
1267+
}
1268+
else
1269+
{
1270+
fputs(lformat->midvrule, fout);
1271+
}
1272+
}
1273+
if (reclen-- <= 0
1274+
&& topt->expanded_header_width_type != PRINT_XHEADER_COLUMN)
12641275
fputs(lformat->hrule, fout);
12651276
}
12661277
else
12671278
{
12681279
if (reclen-- <= 0)
12691280
fputc(' ', fout);
12701281
}
1271-
if (reclen < 0)
1272-
reclen = 0;
1273-
for (i = reclen; i < dwidth; i++)
1274-
fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1275-
if (opt_border == 2)
1276-
fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
1282+
1283+
if (topt->expanded_header_width_type != PRINT_XHEADER_COLUMN)
1284+
{
1285+
if (topt->expanded_header_width_type == PRINT_XHEADER_PAGE
1286+
|| topt->expanded_header_width_type == PRINT_XHEADER_EXACT_WIDTH)
1287+
{
1288+
if (topt->expanded_header_width_type == PRINT_XHEADER_EXACT_WIDTH)
1289+
{
1290+
output_columns = topt->expanded_header_exact_width;
1291+
}
1292+
if (output_columns > 0)
1293+
{
1294+
if (opt_border == 0)
1295+
dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth)));
1296+
if (opt_border == 1)
1297+
dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth - 3)));
1298+
/*
1299+
* Handling the xheader width for border=2 doesn't make
1300+
* much sense because this format has an additional
1301+
* right border, but keep this for consistency.
1302+
*/
1303+
if (opt_border == 2)
1304+
dwidth = Min(dwidth, Max(0, (int) (output_columns - hwidth - 7)));
1305+
}
1306+
}
1307+
1308+
if (reclen < 0)
1309+
reclen = 0;
1310+
if (dwidth < reclen)
1311+
dwidth = reclen;
1312+
1313+
for (i = reclen; i < dwidth; i++)
1314+
fputs(opt_border > 0 ? lformat->hrule : " ", fout);
1315+
if (opt_border == 2)
1316+
fprintf(fout, "%s%s", lformat->hrule, lformat->rightvrule);
1317+
}
1318+
12771319
fputc('\n', fout);
12781320
}
12791321

@@ -1570,11 +1612,12 @@ print_aligned_vertical(const printTableContent *cont,
15701612
lhwidth++; /* for newline indicators */
15711613

15721614
if (!opt_tuples_only)
1573-
print_aligned_vertical_line(format, opt_border, record++,
1574-
lhwidth, dwidth, pos, fout);
1615+
print_aligned_vertical_line(cont->opt, record++,
1616+
lhwidth, dwidth, output_columns,
1617+
pos, fout);
15751618
else if (i != 0 || !cont->opt->start_table || opt_border == 2)
1576-
print_aligned_vertical_line(format, opt_border, 0, lhwidth,
1577-
dwidth, pos, fout);
1619+
print_aligned_vertical_line(cont->opt, 0, lhwidth,
1620+
dwidth, output_columns, pos, fout);
15781621
}
15791622

15801623
/* Format the header */
@@ -1760,8 +1803,8 @@ print_aligned_vertical(const printTableContent *cont,
17601803
if (cont->opt->stop_table)
17611804
{
17621805
if (opt_border == 2 && !cancel_pressed)
1763-
print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth,
1764-
PRINT_RULE_BOTTOM, fout);
1806+
print_aligned_vertical_line(cont->opt, 0, hwidth, dwidth,
1807+
output_columns, PRINT_RULE_BOTTOM, fout);
17651808

17661809
/* print footers */
17671810
if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)

src/include/fe_utils/print.h

+11
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ typedef enum printTextLineWrap
6666
PRINT_LINE_WRAP_NEWLINE /* Newline in data */
6767
} printTextLineWrap;
6868

69+
typedef enum printXheaderWidthType
70+
{
71+
/* Expanded header line width variants */
72+
PRINT_XHEADER_FULL, /* do not truncate header line (this is the default) */
73+
PRINT_XHEADER_COLUMN, /* only print header line above the first column */
74+
PRINT_XHEADER_PAGE, /* header line must not be longer than terminal width */
75+
PRINT_XHEADER_EXACT_WIDTH, /* explicitly specified width */
76+
} printXheaderWidthType;
77+
6978
typedef struct printTextFormat
7079
{
7180
/* A complete line style */
@@ -101,6 +110,8 @@ typedef struct printTableOpt
101110
enum printFormat format; /* see enum above */
102111
unsigned short int expanded; /* expanded/vertical output (if supported
103112
* by output format); 0=no, 1=yes, 2=auto */
113+
printXheaderWidthType expanded_header_width_type; /* width type for header line in expanded mode */
114+
int expanded_header_exact_width; /* explicit width for header line in expanded mode */
104115
unsigned short int border; /* Print a border around the table. 0=none,
105116
* 1=dividing lines, 2=full */
106117
unsigned short int pager; /* use pager for output (if to stdout and

src/test/regress/expected/psql.out

+1
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ tuples_only off
317317
unicode_border_linestyle single
318318
unicode_column_linestyle single
319319
unicode_header_linestyle single
320+
xheader_width full
320321
-- test multi-line headers, wrapping, and newline indicators
321322
-- in aligned, unaligned, and wrapped formats
322323
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab

src/tools/pgindent/typedefs.list

+1
Original file line numberDiff line numberDiff line change
@@ -3569,6 +3569,7 @@ printTextFormat
35693569
printTextLineFormat
35703570
printTextLineWrap
35713571
printTextRule
3572+
printXheaderWidthType
35723573
printfunc
35733574
priv_map
35743575
process_file_callback_t

0 commit comments

Comments
 (0)