Merge pull request #60379 from rogeryk/improve-pretty-format

Improve pretty format if a block consists of a single numeric value and exceeds one million.
This commit is contained in:
Alexey Milovidov 2024-02-29 02:20:42 +03:00 committed by GitHub
commit e6dffb1f2d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 423 additions and 12 deletions

View File

@ -1656,6 +1656,33 @@ Result:
└─────────────────────────┴─────────┘
```
### output_format_pretty_single_large_number_tip_threshold {#output_format_pretty_single_large_number_tip_threshold}
Print a readable number tip on the right side of the table if the block consists of a single number which exceeds
this value (except 0).
Possible values:
- 0 — The readable number tip will not be printed.
- Positive integer — The readable number tip will be printed if the single number exceeds this value.
Default value: `1000000`.
**Example**
Query:
```sql
SELECT 1000000000 as a;
```
Result:
```text
┌──────────a─┐
│ 1000000000 │ -- 1.00 billion
└────────────┘
```
## Template format settings {#template-format-settings}
### format_template_resultset {#format_template_resultset}

View File

@ -1121,6 +1121,7 @@ class IColumn;
M(Bool, output_format_enable_streaming, false, "Enable streaming in output formats that support it.", 0) \
M(Bool, output_format_write_statistics, true, "Write statistics about read rows, bytes, time elapsed in suitable output formats.", 0) \
M(Bool, output_format_pretty_row_numbers, false, "Add row numbers before each row for pretty output format", 0) \
M(UInt64, output_format_pretty_single_large_number_tip_threshold, 1'000'000, "Print a readable number tip on the right side of the table if the block consists of a single number which exceeds this value (except 0)", 0) \
M(Bool, insert_distributed_one_random_shard, false, "If setting is enabled, inserting into distributed table will choose a random shard to write when there is no sharding key", 0) \
\
M(Bool, exact_rows_before_limit, false, "When enabled, ClickHouse will provide exact value for rows_before_limit_at_least statistic, but with the cost that the data before limit will have to be read completely", 0) \

View File

@ -88,6 +88,7 @@ static std::map<ClickHouseVersion, SettingsChangesHistory::SettingsChanges> sett
{"24.2", {
{"validate_experimental_and_suspicious_types_inside_nested_types", false, true, "Validate usage of experimental and suspicious types inside nested types"},
{"output_format_values_escape_quote_with_quote", false, false, "If true escape ' with '', otherwise quoted with \\'"},
{"output_format_pretty_single_large_number_tip_threshold", 0, 1'000'000, "Print a readable number tip on the right side of the table if the block consists of a single number which exceeds this value (except 0)"},
{"input_format_try_infer_exponent_floats", true, false, "Don't infer floats in exponential notation by default"},
{"query_plan_optimize_prewhere", true, true, "Allow to push down filter to PREWHERE expression for supported storages"},
{"async_insert_max_data_size", 1000000, 10485760, "The previous value appeared to be too small."},

View File

@ -150,6 +150,7 @@ FormatSettings getFormatSettings(const ContextPtr & context, const Settings & se
format_settings.pretty.max_rows = settings.output_format_pretty_max_rows;
format_settings.pretty.max_value_width = settings.output_format_pretty_max_value_width;
format_settings.pretty.output_format_pretty_row_numbers = settings.output_format_pretty_row_numbers;
format_settings.pretty.output_format_pretty_single_large_number_tip_threshold = settings.output_format_pretty_single_large_number_tip_threshold;
format_settings.protobuf.input_flatten_google_wrappers = settings.input_format_protobuf_flatten_google_wrappers;
format_settings.protobuf.output_nullables_with_google_wrappers = settings.output_format_protobuf_nullables_with_google_wrappers;
format_settings.protobuf.skip_fields_with_unsupported_types_in_schema_inference = settings.input_format_protobuf_skip_fields_with_unsupported_types_in_schema_inference;

View File

@ -277,6 +277,7 @@ struct FormatSettings
SettingFieldUInt64Auto color{"auto"};
bool output_format_pretty_row_numbers = false;
UInt64 output_format_pretty_single_large_number_tip_threshold = 1'000'000;
enum class Charset
{

View File

@ -6,6 +6,7 @@
#include <IO/Operators.h>
#include <Common/UTF8Helpers.h>
#include <Common/PODArray.h>
#include <Common/formatReadable.h>
namespace DB
@ -305,6 +306,7 @@ void PrettyBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind port_kind
}
writeCString(grid_symbols.bar, out);
writeReadableNumberTip(chunk);
writeCString("\n", out);
}
@ -410,6 +412,24 @@ void PrettyBlockOutputFormat::writeSuffix()
}
}
void PrettyBlockOutputFormat::writeReadableNumberTip(const Chunk & chunk)
{
auto columns = chunk.getColumns();
auto is_single_number = chunk.getNumRows() == 1 && chunk.getNumColumns() == 1 && WhichDataType(columns[0]->getDataType()).isNumber();
if (!is_single_number)
return;
auto value = columns[0]->getFloat64(0);
auto threshold = format_settings.pretty.output_format_pretty_single_large_number_tip_threshold;
if (threshold == 0 || value <= threshold)
return;
if (color)
writeCString("\033[90m", out);
writeCString(" -- ", out);
formatReadableQuantity(value, out, 2);
if (color)
writeCString("\033[0m", out);
}
void registerOutputFormatPretty(FormatFactory & factory)
{
registerPrettyFormatWithNoEscapesAndMonoBlock<PrettyBlockOutputFormat>(factory, "Pretty");

View File

@ -38,6 +38,7 @@ protected:
virtual void writeChunk(const Chunk & chunk, PortKind port_kind);
void writeMonoChunkIfNeeded();
void writeSuffix() override;
void writeReadableNumberTip(const Chunk & chunk);
void onRowsReadBeforeUpdate() override { total_rows = getRowsReadBefore(); }

View File

@ -1,4 +1,5 @@
#include <Common/PODArray.h>
#include <Common/formatReadable.h>
#include <IO/WriteBuffer.h>
#include <IO/WriteHelpers.h>
#include <IO/Operators.h>
@ -137,7 +138,7 @@ void PrettyCompactBlockOutputFormat::writeBottom(const Widths & max_widths)
void PrettyCompactBlockOutputFormat::writeRow(
size_t row_num,
const Block & header,
const Columns & columns,
const Chunk & chunk,
const WidthsPerColumn & widths,
const Widths & max_widths)
{
@ -157,6 +158,7 @@ void PrettyCompactBlockOutputFormat::writeRow(
ascii_grid_symbols;
size_t num_columns = max_widths.size();
const auto & columns = chunk.getColumns();
writeCString(grid_symbols.bar, out);
@ -171,6 +173,7 @@ void PrettyCompactBlockOutputFormat::writeRow(
}
writeCString(grid_symbols.bar, out);
writeReadableNumberTip(chunk);
writeCString("\n", out);
}
@ -180,7 +183,6 @@ void PrettyCompactBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind po
size_t num_rows = chunk.getNumRows();
const auto & header = getPort(port_kind).getHeader();
const auto & columns = chunk.getColumns();
WidthsPerColumn widths;
Widths max_widths;
@ -190,7 +192,8 @@ void PrettyCompactBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind po
writeHeader(header, max_widths, name_widths);
for (size_t i = 0; i < num_rows && total_rows + i < max_rows; ++i)
writeRow(i, header, columns, widths, max_widths);
writeRow(i, header, chunk, widths, max_widths);
writeBottom(max_widths);

View File

@ -22,7 +22,7 @@ private:
void writeRow(
size_t row_num,
const Block & header,
const Columns & columns,
const Chunk & chunk,
const WidthsPerColumn & widths,
const Widths & max_widths);

View File

@ -1,8 +1,8 @@
#include <Common/PODArray.h>
#include <Formats/FormatFactory.h>
#include <IO/WriteBuffer.h>
#include <IO/WriteHelpers.h>
#include <Formats/FormatFactory.h>
#include <Processors/Formats/Impl/PrettySpaceBlockOutputFormat.h>
#include <Common/PODArray.h>
namespace DB
@ -30,9 +30,7 @@ void PrettySpaceBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind port
calculateWidths(header, chunk, widths, max_widths, name_widths);
if (format_settings.pretty.output_format_pretty_row_numbers)
{
writeString(String(row_number_width, ' '), out);
}
/// Names
for (size_t i = 0; i < num_columns; ++i)
{
@ -75,9 +73,7 @@ void PrettySpaceBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind port
// Write row number;
auto row_num_string = std::to_string(row + 1 + total_rows) + ". ";
for (size_t i = 0; i < row_number_width - row_num_string.size(); ++i)
{
writeCString(" ", out);
}
writeString(row_num_string, out);
}
for (size_t column = 0; column < num_columns; ++column)
@ -87,10 +83,11 @@ void PrettySpaceBlockOutputFormat::writeChunk(const Chunk & chunk, PortKind port
const auto & type = *header.getByPosition(column).type;
auto & cur_width = widths[column].empty() ? max_widths[column] : widths[column][row];
writeValueWithPadding(*columns[column], *serializations[column],
row, cur_width, max_widths[column], type.shouldAlignRightInPrettyFormats());
writeValueWithPadding(
*columns[column], *serializations[column], row, cur_width, max_widths[column], type.shouldAlignRightInPrettyFormats());
}
writeReadableNumberTip(chunk);
writeChar('\n', out);
}

View File

@ -0,0 +1,280 @@
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │
└─────────┘
┌───────a─┐
│ 1000000 │
└─────────┘
┌───────a─┐
│ 1000000 │
└─────────┘
┌───────a─┐
│ 1000000 │
└─────────┘
┌───────a─┐
│ 1000000 │
└─────────┘
a
1000000
a
1000000
a
1000000
a
1000000
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000000 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000000 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000000 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000000 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000000 │ -- 1.00 million
└─────────┘
a
1000000 -- 1.00 million
a
1000000 -- 1.00 million
a
1000000 -- 1.00 million
a
1000000 -- 1.00 million
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000001 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000001 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000001 │ -- 1.00 million
└─────────┘
┏━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━┩
│ 1000001 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000001 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000001 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000001 │ -- 1.00 million
└─────────┘
┌───────a─┐
│ 1000001 │ -- 1.00 million
└─────────┘
a
1000001 -- 1.00 million
a
1000001 -- 1.00 million
a
1000001 -- 1.00 million
a
1000001 -- 1.00 million
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │ -- 1.00 billion
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │ -- 1.00 billion
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │ -- 1.00 billion
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │ -- 1.00 billion
└────────────┘
┌──────────a─┐
│ 1000000000 │ -- 1.00 billion
└────────────┘
┌──────────a─┐
│ 1000000000 │ -- 1.00 billion
└────────────┘
┌──────────a─┐
│ 1000000000 │ -- 1.00 billion
└────────────┘
┌──────────a─┐
│ 1000000000 │ -- 1.00 billion
└────────────┘
a
1000000000 -- 1.00 billion
a
1000000000 -- 1.00 billion
a
1000000000 -- 1.00 billion
a
1000000000 -- 1.00 billion
┏━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ a ┃ b ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┏━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ a ┃ b ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┏━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ a ┃ b ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┏━━━━━━━━━━━━┳━━━━━━━━━━━━┓
┃ a ┃ b ┃
┡━━━━━━━━━━━━╇━━━━━━━━━━━━┩
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┌──────────a─┬──────────b─┐
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┌──────────a─┬──────────b─┐
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┌──────────a─┬──────────b─┐
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
┌──────────a─┬──────────b─┐
│ 1000000000 │ 1000000000 │
└────────────┴────────────┘
a b
1000000000 1000000000
a b
1000000000 1000000000
a b
1000000000 1000000000
a b
1000000000 1000000000
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │
├────────────┤
│ 1000000000 │
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │
├────────────┤
│ 1000000000 │
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │
├────────────┤
│ 1000000000 │
└────────────┘
┏━━━━━━━━━━━━┓
┃ a ┃
┡━━━━━━━━━━━━┩
│ 1000000000 │
├────────────┤
│ 1000000000 │
└────────────┘
┌──────────a─┐
│ 1000000000 │
│ 1000000000 │
└────────────┘
┌──────────a─┐
│ 1000000000 │
│ 1000000000 │
└────────────┘
┌──────────a─┐
│ 1000000000 │
│ 1000000000 │
└────────────┘
┌──────────a─┐
│ 1000000000 │
│ 1000000000 │
└────────────┘
a
1000000000
1000000000
a
1000000000
1000000000
a
1000000000
1000000000
a
1000000000
1000000000

View File

@ -0,0 +1,79 @@
SELECT 1_000_000 as a FORMAT Pretty;
SELECT 1_000_000 as a FORMAT PrettyNoEscapes;
SELECT 1_000_000 as a FORMAT PrettyMonoBlock;
SELECT 1_000_000 as a FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_000 as a FORMAT PrettyCompact;
SELECT 1_000_000 as a FORMAT PrettyCompactNoEscapes;
SELECT 1_000_000 as a FORMAT PrettyCompactMonoBlock;
SELECT 1_000_000 as a FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_000 as a FORMAT PrettySpace;
SELECT 1_000_000 as a FORMAT PrettySpaceNoEscapes;
SELECT 1_000_000 as a FORMAT PrettySpaceMonoBlock;
SELECT 1_000_000 as a FORMAT PrettySpaceNoEscapesMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT Pretty;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyNoEscapes;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyCompact;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyCompactNoEscapes;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyCompactMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettySpace;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettySpaceNoEscapes;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettySpaceMonoBlock;
SELECT 1_000_000 as a SETTINGS output_format_pretty_single_large_number_tip_threshold = 1000 FORMAT PrettySpaceNoEscapesMonoBlock;
SELECT 1_000_001 as a FORMAT Pretty;
SELECT 1_000_001 as a FORMAT PrettyNoEscapes;
SELECT 1_000_001 as a FORMAT PrettyMonoBlock;
SELECT 1_000_001 as a FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_001 as a FORMAT PrettyCompact;
SELECT 1_000_001 as a FORMAT PrettyCompactNoEscapes;
SELECT 1_000_001 as a FORMAT PrettyCompactMonoBlock;
SELECT 1_000_001 as a FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_001 as a FORMAT PrettySpace;
SELECT 1_000_001 as a FORMAT PrettySpaceNoEscapes;
SELECT 1_000_001 as a FORMAT PrettySpaceMonoBlock;
SELECT 1_000_001 as a FORMAT PrettySpaceNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FORMAT Pretty;
SELECT 1_000_000_000 as a FORMAT PrettyNoEscapes;
SELECT 1_000_000_000 as a FORMAT PrettyMonoBlock;
SELECT 1_000_000_000 as a FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FORMAT PrettyCompact;
SELECT 1_000_000_000 as a FORMAT PrettyCompactNoEscapes;
SELECT 1_000_000_000 as a FORMAT PrettyCompactMonoBlock;
SELECT 1_000_000_000 as a FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FORMAT PrettySpace;
SELECT 1_000_000_000 as a FORMAT PrettySpaceNoEscapes;
SELECT 1_000_000_000 as a FORMAT PrettySpaceMonoBlock;
SELECT 1_000_000_000 as a FORMAT PrettySpaceNoEscapesMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT Pretty;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyNoEscapes;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyCompact;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyCompactNoEscapes;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyCompactMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettySpace;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettySpaceNoEscapes;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettySpaceMonoBlock;
SELECT 1_000_000_000 as a, 1_000_000_000 as b FORMAT PrettySpaceNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT Pretty;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyNoEscapes;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyCompact;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyCompactNoEscapes;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyCompactMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettyCompactNoEscapesMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettySpace;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettySpaceNoEscapes;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettySpaceMonoBlock;
SELECT 1_000_000_000 as a FROM system.numbers LIMIT 2 FORMAT PrettySpaceNoEscapesMonoBlock;