Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mBakA-0006Kp-CY for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Aug 2021 10:36:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1mBak8-0007Qd-Tf for pgsql-hackers@arkaria.postgresql.org; Thu, 05 Aug 2021 10:36:52 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1mBak8-0007QV-KG for pgsql-hackers@lists.postgresql.org; Thu, 05 Aug 2021 10:36:52 +0000 Received: from mail-lj1-x22f.google.com ([2a00:1450:4864:20::22f]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1mBak6-0002jl-Lm for pgsql-hackers@lists.postgresql.org; Thu, 05 Aug 2021 10:36:52 +0000 Received: by mail-lj1-x22f.google.com with SMTP id m9so6430612ljp.7 for ; Thu, 05 Aug 2021 03:36:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=ASFsFuavver5psn/080FU3imtAhIe6VLZiv+vRDHXLg=; b=jx5rQtsEgSUVoaQNYsnpO9j6sn89gXHTJKmM2c56r4SQe8jEdy3XFGkKirVdxLohCf MesjzeVsJWTnq1IqLG76Yvp0BEcruAjOnuPT9hl28GFInk4X3NdhBey0k7UQ/DIGXHc7 y4C/neanWNy1xDersTZhnwi7afzo1ENhrEg3hATbq4hAnlFI6ck71ab2hgwOOWt2ykYx DWW6i9nRbDRkTn00hNAlNO0lJikM3lutfmnofX1AHTXjImQKAEfn/tGhPyDUje9uwih8 ScYg7YW5uU7FXlsbTQerfSxqV3hSnDqtA0x4jse8qCSkzZUVNA3kP6IGFsCtVYdkhgY9 WJQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:to:from:subject:message-id:date:user-agent :mime-version:content-language; bh=ASFsFuavver5psn/080FU3imtAhIe6VLZiv+vRDHXLg=; b=bNXTDiCBPDdGJwB3wBWJUc1BD7CKVUwjdrSCMkIm8VfOsPnCoUkSIHVKYNNdUkn1wz PFw1xXdYdWH+06wz0AoTyqBC09lqhr6A+Rg9rYoguHDsN0RyME/REfxrBSZk9SSA4Vfh HpwsDLQMfJxw6AIqyZXnt1l1qPb+uQL/L61RcTbZX+KUXS5KR+DLYKyA4ztXSLUd518w dm9v6y4GIODfeHVMk8abqJNpLNOb4vNh5H5z3b43T4QrvVF1YB/GgDXnl+fVIpWprYmo YHzO9uct1c7t/Ond6I16l6K5NNNwDFBG7TV1O94PtBwz34o2ohJP54eYrp+FTJL8xHxR y5pQ== X-Gm-Message-State: AOAM532bGKYEfsYbkZydeuwcJW/imF0oxw+/5QueEeMI88hJpEW3EC+d m/TJCUiPfn8JBIR3l/LI1oy6+NKoJhM= X-Google-Smtp-Source: ABdhPJxXHaiPm80vPQjut5loWpJM88FD/GYhdDbNrM2OT0N67R4rd4DFT7FQqVFMpjHo7t7P1xc0jw== X-Received: by 2002:a2e:934c:: with SMTP id m12mr2604049ljh.375.1628159807240; Thu, 05 Aug 2021 03:36:47 -0700 (PDT) Received: from [192.168.1.3] ([46.138.249.39]) by smtp.gmail.com with ESMTPSA id b15sm474938lff.104.2021.08.05.03.36.46 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 05 Aug 2021 03:36:46 -0700 (PDT) To: pgsql-hackers@lists.postgresql.org From: Platon Pronko Subject: very long record lines in expanded psql output Message-ID: Date: Thu, 5 Aug 2021 13:36:45 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------C434E484567DFAA9A14C59C0" Content-Language: en-US List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk This is a multi-part message in MIME format. --------------C434E484567DFAA9A14C59C0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit 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 │ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ─[ RECORD 2 ]────┼────────────────────────────────────────────────────────────────────────────────── ──────────────────────────────────────────────────────────────────────────────────────────────────── ───────────────────────────── n │ 210 long_column_name │ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx 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 │ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ─[ RECORD 2 ]────┼────────────────────────────────────────────────────────────────────────────────── n │ 210 long_column_name │ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx Best regards, Platon Pronko --------------C434E484567DFAA9A14C59C0 Content-Type: text/x-patch; charset=UTF-8; name="fix-header-lines-in-expanded-output.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="fix-header-lines-in-expanded-output.patch" 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) --------------C434E484567DFAA9A14C59C0--