2018-05-24 01:02:16 +00:00
|
|
|
#include <string>
|
|
|
|
#include <Processors/Formats/IRowOutputFormat.h>
|
2019-02-19 18:41:18 +00:00
|
|
|
#include <IO/WriteHelpers.h>
|
2018-05-24 01:02:16 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2020-02-25 18:10:48 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int LOGICAL_ERROR;
|
|
|
|
}
|
2018-05-24 01:02:16 +00:00
|
|
|
|
2021-03-09 14:46:52 +00:00
|
|
|
IRowOutputFormat::IRowOutputFormat(const Block & header, WriteBuffer & out_, const Params & params_)
|
|
|
|
: IOutputFormat(header, out_)
|
|
|
|
, types(header.getDataTypes())
|
|
|
|
, params(params_)
|
|
|
|
{
|
|
|
|
serializations.reserve(types.size());
|
|
|
|
for (const auto & type : types)
|
|
|
|
serializations.push_back(type->getDefaultSerialization());
|
|
|
|
}
|
|
|
|
|
2019-02-19 18:41:18 +00:00
|
|
|
void IRowOutputFormat::consume(DB::Chunk chunk)
|
|
|
|
{
|
|
|
|
auto num_rows = chunk.getNumRows();
|
2020-04-22 06:34:20 +00:00
|
|
|
const auto & columns = chunk.getColumns();
|
2019-02-19 18:41:18 +00:00
|
|
|
|
2020-02-03 10:02:52 +00:00
|
|
|
for (size_t row = 0; row < num_rows; ++row)
|
2019-02-19 18:41:18 +00:00
|
|
|
{
|
|
|
|
if (!first_row)
|
|
|
|
writeRowBetweenDelimiter();
|
|
|
|
|
|
|
|
write(columns, row);
|
2019-08-20 11:17:57 +00:00
|
|
|
|
2020-10-06 12:47:52 +00:00
|
|
|
if (params.callback)
|
|
|
|
params.callback(columns, row);
|
2020-10-12 13:05:40 +00:00
|
|
|
|
|
|
|
first_row = false;
|
2019-02-19 18:41:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void IRowOutputFormat::consumeTotals(DB::Chunk chunk)
|
|
|
|
{
|
|
|
|
writeSuffixIfNot();
|
|
|
|
|
|
|
|
auto num_rows = chunk.getNumRows();
|
|
|
|
if (num_rows != 1)
|
|
|
|
throw Exception("Got " + toString(num_rows) + " in totals chunk, expected 1", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
2020-04-22 06:34:20 +00:00
|
|
|
const auto & columns = chunk.getColumns();
|
2019-02-19 18:41:18 +00:00
|
|
|
|
|
|
|
writeBeforeTotals();
|
|
|
|
writeTotals(columns, 0);
|
|
|
|
writeAfterTotals();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IRowOutputFormat::consumeExtremes(DB::Chunk chunk)
|
|
|
|
{
|
|
|
|
writeSuffixIfNot();
|
|
|
|
|
|
|
|
auto num_rows = chunk.getNumRows();
|
2020-04-22 06:34:20 +00:00
|
|
|
const auto & columns = chunk.getColumns();
|
2019-02-19 18:41:18 +00:00
|
|
|
if (num_rows != 2)
|
|
|
|
throw Exception("Got " + toString(num_rows) + " in extremes chunk, expected 2", ErrorCodes::LOGICAL_ERROR);
|
|
|
|
|
|
|
|
writeBeforeExtremes();
|
|
|
|
writeMinExtreme(columns, 0);
|
|
|
|
writeRowBetweenDelimiter();
|
|
|
|
writeMaxExtreme(columns, 1);
|
|
|
|
writeAfterExtremes();
|
|
|
|
}
|
|
|
|
|
|
|
|
void IRowOutputFormat::finalize()
|
|
|
|
{
|
|
|
|
writeSuffixIfNot();
|
|
|
|
writeLastSuffix();
|
|
|
|
}
|
|
|
|
|
2018-05-24 01:02:16 +00:00
|
|
|
void IRowOutputFormat::write(const Columns & columns, size_t row_num)
|
|
|
|
{
|
|
|
|
size_t num_columns = columns.size();
|
|
|
|
|
|
|
|
writeRowStartDelimiter();
|
|
|
|
|
|
|
|
for (size_t i = 0; i < num_columns; ++i)
|
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
writeFieldDelimiter();
|
|
|
|
|
2021-03-09 14:46:52 +00:00
|
|
|
writeField(*columns[i], *serializations[i], row_num);
|
2018-05-24 01:02:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
writeRowEndDelimiter();
|
|
|
|
}
|
|
|
|
|
2019-02-19 18:41:18 +00:00
|
|
|
void IRowOutputFormat::writeMinExtreme(const DB::Columns & columns, size_t row_num)
|
|
|
|
{
|
|
|
|
write(columns, row_num);
|
|
|
|
}
|
|
|
|
|
2021-05-08 14:43:03 +00:00
|
|
|
void IRowOutputFormat::writeMaxExtreme(const DB::Columns & columns, size_t row_num) //-V524
|
2019-02-19 18:41:18 +00:00
|
|
|
{
|
|
|
|
write(columns, row_num);
|
|
|
|
}
|
|
|
|
|
|
|
|
void IRowOutputFormat::writeTotals(const DB::Columns & columns, size_t row_num)
|
|
|
|
{
|
|
|
|
write(columns, row_num);
|
|
|
|
}
|
|
|
|
|
2018-05-24 01:02:16 +00:00
|
|
|
}
|