Re: very long record lines in expanded psql output
Hi, + pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or an number specifying exact width."); an number specifying -> a number specifying Cheers Fixed, attaching the updated patch. Thank you! Best regards, Platon Pronkodiff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 14e0a4dbe3..78d27caefa 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2799,6 +2799,32 @@ lo_import 152801 + + xheader_width + + + Sets expanded header width to one of full, + column, + page, + or integer value. + + + full is the default option - expanded header + is not truncated. + + + column: don't print header line past the first + column. + + + page: fit header line to terminal width. + + + integer value: specify exact width of header line. + + + + fieldsep diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 49d4c0e3ce..801810aba9 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -4310,6 +4310,32 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.expanded = !popt->topt.expanded; } + /* header line width in expanded mode */ + else if (strcmp(param, "xheader_width") == 0) + { + if (value && pg_strcasecmp(value, "full") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + else if (value && pg_strcasecmp(value, "column") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_COLUMN; + else if (value && pg_strcasecmp(value, "page") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_PAGE; + else if (value) + { + popt->topt.expanded_header_width_type = PRINT_XHEADER_EXACT_WIDTH; + popt->topt.expanded_header_exact_width = atoi(value); + if (popt->topt.expanded_header_exact_width == 0) + { +pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or a number specifying exact width."); +return false; + } + } + else + { + /* reset to default if value is empty */ + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + } + } + /* field separator for CSV format */ else if (strcmp(param, "csv_fieldsep") == 0) { @@ -4502,6 +4528,19 @@ printPsetInfo(const char *param, printQueryOpt *popt) printf(_("Expanded display is off.\n")); } + /* show xheader width type */ + else if (strcmp(param, "xheader_width") == 0) + { + if (popt->topt.expanded_header_width_type == PRINT_XHEADER_FULL) + printf(_("Expanded header width is 'full'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_COLUMN) + printf(_("Expanded header width is 'column'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_PAGE) + printf(_("Expanded header width is 'page'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_EXACT_WIDTH) + printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width); + } + /* show field separator for CSV format */ else if (strcmp(param, "csv_fieldsep") == 0) { diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 5cd5838668..e3e3bdc709 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -4168,13 +4168,16 @@ psql_completion(const char *text, int start, int end) "tableattr", "title", "tuples_only", "unicode_border_linestyle", "unicode_column_linestyle", - "unicode_header_linestyle"); + "unicode_header_linestyle", + "xheader_width"); else if (TailMatchesCS("\\pset", MatchAny)) { if (TailMatchesCS("format")) COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex", "latex-longtable", "troff-ms", "unaligned", "wrapped"); + else if (TailMatchesCS("xheader_width")) + COMPLETE_WITH_CS("full", "column", "page"); else if (TailMatchesCS("linestyle")) COMPLETE_WITH_CS("ascii", "old-ascii", "unicode"); else if (TailMatchesCS("pager")) diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index d48fcc4a03..1e94772b8b 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -1152,15 +1152,16 @@ cleanup: static void -print_aligned_vertical_line(const printTextFormat *format, - const unsigned short opt_border, +print_aligned_vertical_line(const printTableOpt *topt, unsigned long record, unsigned int hwidth, unsigned int dwidth, + int output_columns, printTextRule pos, FILE *fout) { - const printTextLineFormat *lformat = &format->lrule[pos]; + const printTextLineFormat *lformat = &get_line_style(topt)->lrule[pos]; + const unsigned short opt_border = topt->border; unsigned int i; int reclen =
Re: very long record lines in expanded psql output
On 2021-09-24 14:42, Andrew Dunstan wrote: On 9/24/21 12:49 AM, Platon Pronko wrote: On 2021-09-23 22:28, Andrew Dunstan wrote: 2. It would possibly be better to pass the relevant parts of the options to print_aligned_vertical_line() rather than the whole options structure. It feels odd to pass both that and opt_border. What do you think about doing it the other way around - passing only whole options structure? That way we will roll 4 parameters (opt_border, printTextFormat, and two xheader ones) into only one argument. This increases code coupling a bit, but I'm not sure if that's relevant here. Sure, as long as it doesn't result in duplicated computation. Hi! Please find attached the updated patch - with fixed braces and adjusted parameters to print_aligned_vertical_line(). Best regards, Platon Pronkodiff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index 14e0a4dbe3..78d27caefa 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2799,6 +2799,32 @@ lo_import 152801 + + xheader_width + + + Sets expanded header width to one of full, + column, + page, + or integer value. + + + full is the default option - expanded header + is not truncated. + + + column: don't print header line past the first + column. + + + page: fit header line to terminal width. + + + integer value: specify exact width of header line. + + + + fieldsep diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 49d4c0e3ce..ebba14d082 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -4310,6 +4310,32 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.expanded = !popt->topt.expanded; } + /* header line width in expanded mode */ + else if (strcmp(param, "xheader_width") == 0) + { + if (value && pg_strcasecmp(value, "full") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + else if (value && pg_strcasecmp(value, "column") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_COLUMN; + else if (value && pg_strcasecmp(value, "page") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_PAGE; + else if (value) + { + popt->topt.expanded_header_width_type = PRINT_XHEADER_EXACT_WIDTH; + popt->topt.expanded_header_exact_width = atoi(value); + if (popt->topt.expanded_header_exact_width == 0) + { +pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or an number specifying exact width."); +return false; + } + } + else + { + /* reset to default if value is empty */ + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + } + } + /* field separator for CSV format */ else if (strcmp(param, "csv_fieldsep") == 0) { @@ -4502,6 +4528,19 @@ printPsetInfo(const char *param, printQueryOpt *popt) printf(_("Expanded display is off.\n")); } + /* show xheader width type */ + else if (strcmp(param, "xheader_width") == 0) + { + if (popt->topt.expanded_header_width_type == PRINT_XHEADER_FULL) + printf(_("Expanded header width is 'full'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_COLUMN) + printf(_("Expanded header width is 'column'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_PAGE) + printf(_("Expanded header width is 'page'.\n")); + else if (popt->topt.expanded_header_width_type == PRINT_XHEADER_EXACT_WIDTH) + printf(_("Expanded header width is %d.\n"), popt->topt.expanded_header_exact_width); + } + /* show field separator for CSV format */ else if (strcmp(param, "csv_fieldsep") == 0) { diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 5cd5838668..e3e3bdc709 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -4168,13 +4168,16 @@ psql_completion(const char *text, int start, int end) "tableattr", "title", "tuples_only", "unicode_border_linestyle", "unicode_column_linestyle", - "unicode_header_linestyle"); + "unicode_header_linestyle", + "xheader_width"); else if (TailMatchesCS("\\pset", MatchAny)) { if (TailMatchesCS("format")) COMPLETE_WITH_CS("aligned", "asciidoc", "csv", "html", "latex", "latex-longtable", "troff-ms", "unaligned&quo
Re: very long record lines in expanded psql output
On 2021-09-23 22:28, Andrew Dunstan wrote: 2. It would possibly be better to pass the relevant parts of the options to print_aligned_vertical_line() rather than the whole options structure. It feels odd to pass both that and opt_border. What do you think about doing it the other way around - passing only whole options structure? That way we will roll 4 parameters (opt_border, printTextFormat, and two xheader ones) into only one argument. This increases code coupling a bit, but I'm not sure if that's relevant here. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
Hi! Done, here's the link: https://commitfest.postgresql.org/34/3295/ Best regards, Platon Pronko On 2021-08-23 21:14, Andrew Dunstan wrote: On 8/23/21 2:00 PM, Platon Pronko wrote: Hi! Apparently I did forget something, and that's the patch itself :) Thanks for Justin Pryzby for pointing this out. Attaching the patch now. Please add it to the commitfest, the next one starts in about a week. cheers andrew -- Andrew Dunstan EDB: https://www.enterprisedb.com
Re: very long record lines in expanded psql output
Hi! Apparently I did forget something, and that's the patch itself :) Thanks for Justin Pryzby for pointing this out. Attaching the patch now. Best regards, Platon Pronko On 2021-08-23 20:51, Platon Pronko wrote: Hi! Please find attached the patch implementing the proposed changes. I hope I didn't forget anything (docs, tab completion, comments, etc), if I did forget something please tell me and I'll fix it. Best regards, Platon Pronko On 2021-08-08 01:18, Andrew Dunstan wrote: On 8/7/21 10:56 AM, Platon Pronko wrote: Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Yes, but it changes the data line output. Ideally, you should be able to modify these independently. I agree, and I think this can be implemented, but I'm a bit afraid of introducing an additional psql option (there's already quite a lot of them). I suspect primary PostgreSQL maintainers won't be happy with such an approach. I think I qualify as one of those ... :-) Sorry, I'm new here, don't know who's who :) No problem. Welcome! We're always very glad to see new contributors. I'll start working on a new patch then. A couple questions about specifics: 1. Can we add "expanded" in the option name, like "xheader_expanded_width"? I think adjusting the header row width doesn't make sense on any other modes, and placing that in the option name makes intent a bit clearer. "xheader" was meant to be shorthand for "expanded output header" 2. What was "column" option in your original suggestion supposed to do? ("\pset xheader_width column|page|nnn") It's meant to say don't print anything past the column spec, e.g.: -[ RECORD 1 ]+ n | 42 long_column_name | xx -[ RECORD 2 ]+ n | 210 long_column_name | xx 3. Should we bother with using this option when in "\pset border 2" mode? I can do it for consistency, but it will still look bad. Probably not, but since I never use it I'll let others who do weigh in on the subject. cheers andrew -- Andrew Dunstan EDB: https://www.enterprisedb.com diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index fcab5c0d51..8cffc18165 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -2799,6 +2799,32 @@ lo_import 152801 + + xheader_width + + + Sets expanded header width to one of full, + column, + page, + or integer value. + + + full is the default option - expanded header + is not truncated. + + + column: don't print header line past the first + column. + + + page: fit header line to terminal width. + + + integer value: specify exact width of header line. + + + + fieldsep diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 49d4c0e3ce..440b732d3c 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -4310,6 +4310,28 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) popt->topt.expanded = !popt->topt.expanded; } + /* header line width in expanded mode */ + else if (strcmp(param, "xheader_width") == 0) + { + if (value && pg_strcasecmp(value, "full") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + else if (value && pg_strcasecmp(value, "column") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_COLUMN; + else if (value && pg_strcasecmp(value, "page") == 0) + popt->topt.expanded_header_width_type = PRINT_XHEADER_PAGE; + else if (value) { + popt->topt.expanded_header_width_type = PRINT_XHEADER_EXACT_WIDTH; + popt->topt.expanded_header_exact_width = atoi(value); + if (popt->topt.expanded_header_exact_width == 0) { +pg_log_error("\\pset: allowed xheader_width values are full (default), column, page, or an number specifying exact width."); +return false; + } + } else { + /* reset to default if value is empty */ + popt->topt.expanded_header_width_type = PRINT_XHEADER_FULL; + } + } + /* field separator for CSV format */ else if (strcmp(param, "csv_fieldsep") == 0) { @@ -4502,6 +4524,19 @@ printPsetInfo(const char *param, printQueryOpt *popt)
Re: very long record lines in expanded psql output
Hi! Please find attached the patch implementing the proposed changes. I hope I didn't forget anything (docs, tab completion, comments, etc), if I did forget something please tell me and I'll fix it. Best regards, Platon Pronko On 2021-08-08 01:18, Andrew Dunstan wrote: On 8/7/21 10:56 AM, Platon Pronko wrote: Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Yes, but it changes the data line output. Ideally, you should be able to modify these independently. I agree, and I think this can be implemented, but I'm a bit afraid of introducing an additional psql option (there's already quite a lot of them). I suspect primary PostgreSQL maintainers won't be happy with such an approach. I think I qualify as one of those ... :-) Sorry, I'm new here, don't know who's who :) No problem. Welcome! We're always very glad to see new contributors. I'll start working on a new patch then. A couple questions about specifics: 1. Can we add "expanded" in the option name, like "xheader_expanded_width"? I think adjusting the header row width doesn't make sense on any other modes, and placing that in the option name makes intent a bit clearer. "xheader" was meant to be shorthand for "expanded output header" 2. What was "column" option in your original suggestion supposed to do? ("\pset xheader_width column|page|nnn") It's meant to say don't print anything past the column spec, e.g.: -[ RECORD 1 ]+ n| 42 long_column_name | xx -[ RECORD 2 ]+ n| 210 long_column_name | xx 3. Should we bother with using this option when in "\pset border 2" mode? I can do it for consistency, but it will still look bad. Probably not, but since I never use it I'll let others who do weigh in on the subject. cheers andrew -- Andrew Dunstan EDB: https://www.enterprisedb.com
Re: very long record lines in expanded psql output
Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Yes, but it changes the data line output. Ideally, you should be able to modify these independently. I agree, and I think this can be implemented, but I'm a bit afraid of introducing an additional psql option (there's already quite a lot of them). I suspect primary PostgreSQL maintainers won't be happy with such an approach. I think I qualify as one of those ... :-) Sorry, I'm new here, don't know who's who :) I'll start working on a new patch then. A couple questions about specifics: 1. Can we add "expanded" in the option name, like "xheader_expanded_width"? I think adjusting the header row width doesn't make sense on any other modes, and placing that in the option name makes intent a bit clearer. 2. What was "column" option in your original suggestion supposed to do? ("\pset xheader_width column|page|nnn") 3. Should we bother with using this option when in "\pset border 2" mode? I can do it for consistency, but it will still look bad. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
it can be a fully new format - designed for simple copy from terminal. Some like == record: 10 == proname left prosrc $lalalal ewqrwqerw ewqrwqerqrewq $ === no, it was proposed for psql How is this better than "copy (...) to stdout"? E.g.: $ copy (select * from pg_class limit 1) to stdout; 2619pg_statistic11 12016 0 10 2 26190 18 402 18 2840t f p r 31 0 f f f f f t n f0 478 1 {postgres=arwdDxt/postgres} \N \N You can still copy the necessary parts (using mouse selection) - seems that it achieves the the same goal. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
Hi! I don't think that would be a good idea. If somebody really just needs to copy, then wrapping the query in "copy (...) to stdout" already works nicely, no need to create a special mode just for that. It is working well, but it is copy to file, not copy to clipboard. Maybe I misunderstood - are you suggesting this a special mode in pspg? I thought that you were suggesting to implement a mode in psql, something like "\pset format_for_clipboard". I think the question was more about being able to copy in an ad-hoc way, in the middle of scrolling trough "normal" output. I understand your motivation, but I don't feel a significant benefit to increase the complexity of the main format (more, when it breaks pspg, without possibility to fix it). but it can depend on usual data, and it is true, so when I use pspg, I don't use extended mode too often. To clarify: I'm not suggesting my patch anymore - it definitely breaks pspg and this is completely unacceptable. We're just discussing the possible alternate solutions, I think. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Yes, but it changes the data line output. Ideally, you should be able to modify these independently. I agree, and I think this can be implemented, but I'm a bit afraid of introducing an additional psql option (there's already quite a lot of them). I suspect primary PostgreSQL maintainers won't be happy with such an approach. it can be a fully new format - designed for simple copy from terminal. Some like == record: 10 == proname left prosrc $lalalal ewqrwqerw ewqrwqerqrewq $ === I don't think that would be a good idea. If somebody really just needs to copy, then wrapping the query in "copy (...) to stdout" already works nicely, no need to create a special mode just for that. I think the question was more about being able to copy in an ad-hoc way, in the middle of scrolling trough "normal" output. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Yes, but it changes the data line output. Ideally, you should be able to modify these independently. I agree, and I think this can be implemented, but I'm a bit afraid of introducing an additional psql option (there's already quite a lot of them). I suspect primary PostgreSQL maintainers won't be happy with such an approach. Best regards, Platon Pronko
Re: very long record lines in expanded psql output
Hi! I also find this annoying and would be happy to be rid of it. Have you tried "\pset format wrapped"? Pavel suggested it, and it solved most of the problem for me, for example. Best regards, Platon Pronko
very long record lines in expanded psql output
In expanded mode psql calculates the width of the longest field in all the output rows, and prints the header line according to it. This often results in record header wrapping over several lines (see example below). This huge record header is printed the same way before each record, even if all the fields in current record are small and fit into terminal width. This often leads to situations when record header occupies the entirety of the screen, for all records, even though there are only a few records with huge fields in a record set. Maybe we can avoid making the header line longer than terminal width for \pset border 0 and \pset border 1? We already have terminal width calculated. Please see attached a patch with the proposed implementation. Example output before the modification, in a terminal with a 100-column width: $ psql template1 -c "\x on" -c "\pset border 1;" -c "select n, repeat('x', n) as long_column_name from unnest(array[42,210]) as n" Expanded display is on. Border style is 1. ─[ RECORD 1 ]┬── ─ n│ 42 long_column_name │ xx ─[ RECORD 2 ]┼── ─ n│ 210 long_column_name │ x x And here's the same command after the patch: $ psql template1 -c "\x on" -c "\pset border 1;" -c "select n, repeat('x', n) as long_column_name from unnest(array[42,210]) as n" Expanded display is on. Border style is 1. ─[ RECORD 1 ]┬── n│ 42 long_column_name │ xx ─[ RECORD 2 ]┼── n│ 210 long_column_name │ x xxxxxxxx x Best regards, Platon Pronko diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index d48fcc4a03..9483d0d852 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -1157,6 +1157,7 @@ print_aligned_vertical_line(const printTextFormat *format, unsigned long record, unsigned int hwidth, unsigned int dwidth, + int output_columns, printTextRule pos, FILE *fout) { @@ -1200,6 +1201,14 @@ print_aligned_vertical_line(const printTextFormat *format, } if (reclen < 0) reclen = 0; + + if (output_columns > 0) { + if (opt_border == 0) + dwidth = Min(dwidth, output_columns - hwidth); + if (opt_border == 1) + dwidth = Min(dwidth, output_columns - hwidth - 3); + } + for (i = reclen; i < dwidth; i++) fputs(opt_border > 0 ? lformat->hrule : " ", fout); if (opt_border == 2) @@ -1501,10 +1510,11 @@ print_aligned_vertical(const printTableContent *cont, if (!opt_tuples_only) print_aligned_vertical_line(format, opt_border, record++, - lhwidth, dwidth, pos, fout); + lhwidth, dwidth, output_columns, + pos, fout); else if (i != 0 || !cont->opt->start_table || opt_border == 2) print_aligned_vertical_line(format, opt_border, 0, lhwidth, - dwidth, pos, fout); + dwidth, output_columns, pos, fout); } /* Format the header */ @@ -1691,7 +1701,7 @@ print_aligned_vertical(const printTableContent *cont, { if (opt_border == 2 && !cancel_pressed) print_aligned_vertical_line(format, opt_border, 0, hwidth, dwidth, - PRINT_RULE_BOTTOM, fout); + output_columns, PRINT_RULE_BOTTOM, fout); /* print footers */ if (!opt_tuples_only && cont->footers != NULL && !cancel_pressed)