Format Vertical: added support for totals, extremes and output_format_pretty_max_rows [#CLICKHOUSE-3014].

This commit is contained in:
Alexey Milovidov 2017-05-22 22:00:45 +03:00
parent 734b240490
commit 7269f3a23b
5 changed files with 417 additions and 7 deletions

View File

@ -155,9 +155,11 @@ static BlockOutputStreamPtr getOutputImpl(const String & name, WriteBuffer & buf
else if (name == "PrettySpaceNoEscapes")
return std::make_shared<PrettySpaceBlockOutputStream>(buf, true, settings.output_format_pretty_max_rows, context);
else if (name == "Vertical")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<VerticalRowOutputStream>(buf, sample, context));
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<VerticalRowOutputStream>(
buf, sample, settings.output_format_pretty_max_rows, context));
else if (name == "VerticalRaw")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<VerticalRawRowOutputStream>(buf, sample, context));
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<VerticalRawRowOutputStream>(
buf, sample, settings.output_format_pretty_max_rows, context));
else if (name == "Values")
return std::make_shared<BlockOutputStreamFromRowOutputStream>(std::make_shared<ValuesRowOutputStream>(buf));
else if (name == "JSON")

View File

@ -10,8 +10,9 @@
namespace DB
{
VerticalRowOutputStream::VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context)
: ostr(ostr_), sample(sample_)
VerticalRowOutputStream::VerticalRowOutputStream(
WriteBuffer & ostr_, const Block & sample_, size_t max_rows_, const Context & context)
: ostr(ostr_), sample(sample_), max_rows(max_rows_)
{
size_t columns = sample.columns();
@ -60,6 +61,9 @@ void VerticalRowOutputStream::flush()
void VerticalRowOutputStream::writeField(const IColumn & column, const IDataType & type, size_t row_num)
{
if (row_number > max_rows)
return;
writeString(names_and_paddings[field_number], ostr);
writeValue(column, type, row_num);
writeChar('\n', ostr);
@ -82,6 +86,10 @@ void VerticalRawRowOutputStream::writeValue(const IColumn & column, const IDataT
void VerticalRowOutputStream::writeRowStartDelimiter()
{
++row_number;
if (row_number > max_rows)
return;
writeCString("Row ", ostr);
writeIntText(row_number, ostr);
writeCString(":\n", ostr);
@ -95,9 +103,77 @@ void VerticalRowOutputStream::writeRowStartDelimiter()
void VerticalRowOutputStream::writeRowBetweenDelimiter()
{
if (row_number > max_rows)
return;
writeCString("\n", ostr);
field_number = 0;
}
void VerticalRowOutputStream::writeSuffix()
{
if (row_number > max_rows)
{
writeCString("Showed first ", ostr);
writeIntText(max_rows, ostr);
writeCString(".\n", ostr);
}
if (totals || extremes)
{
writeCString("\n", ostr);
writeTotals();
writeExtremes();
}
}
void VerticalRowOutputStream::writeSpecialRow(const Block & block, size_t row_num, const char * title)
{
writeCString("\n", ostr);
row_number = 0;
field_number = 0;
size_t columns = block.columns();
writeCString(title, ostr);
writeCString(":\n", ostr);
size_t width = strlen(title) + 1;
for (size_t i = 0; i < width; ++i)
writeCString("", ostr);
writeChar('\n', ostr);
for (size_t i = 0; i < columns; ++i)
{
if (i != 0)
writeFieldDelimiter();
auto & col = block.getByPosition(i);
writeField(*col.column.get(), *col.type.get(), row_num);
}
}
void VerticalRowOutputStream::writeTotals()
{
if (totals)
{
writeSpecialRow(totals, 0, "Totals");
}
}
void VerticalRowOutputStream::writeExtremes()
{
if (extremes)
{
writeSpecialRow(extremes, 0, "Min");
writeSpecialRow(extremes, 1, "Max");
}
}
}

View File

@ -18,24 +18,37 @@ class Context;
class VerticalRowOutputStream : public IRowOutputStream
{
public:
VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context);
VerticalRowOutputStream(WriteBuffer & ostr_, const Block & sample_, size_t max_rows_, const Context & context);
void writeField(const IColumn & column, const IDataType & type, size_t row_num) override;
void writeRowStartDelimiter() override;
void writeRowBetweenDelimiter() override;
void writeSuffix() override;
void flush() override;
void setTotals(const Block & totals_) override { totals = totals_; }
void setExtremes(const Block & extremes_) override { extremes = extremes_; }
protected:
virtual void writeValue(const IColumn & column, const IDataType & type, size_t row_num) const;
void writeTotals();
void writeExtremes();
/// For totals and extremes.
void writeSpecialRow(const Block & block, size_t row_num, const char * title);
WriteBuffer & ostr;
const Block sample;
size_t max_rows;
size_t field_number = 0;
size_t row_number = 0;
using NamesAndPaddings = std::vector<String>;
NamesAndPaddings names_and_paddings;
Block totals;
Block extremes;
};
@ -44,8 +57,7 @@ protected:
class VerticalRawRowOutputStream final : public VerticalRowOutputStream
{
public:
VerticalRawRowOutputStream(WriteBuffer & ostr_, const Block & sample_, const Context & context)
: VerticalRowOutputStream(ostr_, sample_, context) {}
using VerticalRowOutputStream::VerticalRowOutputStream;
protected:
void writeValue(const IColumn & column, const IDataType & type, size_t row_num) const override;

View File

@ -0,0 +1,298 @@
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Row 5:
──────
k: 4
count(): 20
Totals:
───────
k: 0
count(): 100
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Row 5:
──────
k: 4
count(): 20
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Row 5:
──────
k: 4
count(): 20
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Showed first 4.
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Showed first 4.
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Showed first 4.
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Row 5:
──────
k: 4
count(): 20
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20
Row 1:
──────
k: 0
count(): 20
Row 2:
──────
k: 1
count(): 20
Row 3:
──────
k: 2
count(): 20
Row 4:
──────
k: 3
count(): 20
Showed first 4.
Totals:
───────
k: 0
count(): 100
Min:
────
k: 0
count(): 20
Max:
────
k: 4
count(): 20

View File

@ -0,0 +1,22 @@
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT Vertical;
SET extremes = 1;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT Vertical;
SET output_format_pretty_max_rows = 5;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT Vertical;
SET output_format_pretty_max_rows = 4;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT Vertical;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT VerticalRaw;
SET extremes = 1;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT VerticalRaw;
SET output_format_pretty_max_rows = 5;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT VerticalRaw;
SET output_format_pretty_max_rows = 4;
SELECT k, count() FROM (SELECT number % 5 AS k FROM system.numbers LIMIT 100) GROUP BY k WITH TOTALS ORDER BY k FORMAT VerticalRaw;