2019-08-17 22:53:46 +00:00
|
|
|
#include "ProtobufRowInputFormat.h"
|
2019-02-21 18:36:46 +00:00
|
|
|
|
2019-08-04 12:43:11 +00:00
|
|
|
#if USE_PROTOBUF
|
2019-02-21 18:36:46 +00:00
|
|
|
#include <Core/Block.h>
|
|
|
|
#include <Formats/FormatFactory.h>
|
2019-04-05 10:52:07 +00:00
|
|
|
#include <Formats/FormatSchemaInfo.h>
|
|
|
|
#include <Formats/ProtobufSchemas.h>
|
2019-09-24 14:25:22 +00:00
|
|
|
#include <Interpreters/Context.h>
|
2019-02-21 18:36:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2020-10-06 14:32:01 +00:00
|
|
|
ProtobufRowInputFormat::ProtobufRowInputFormat(ReadBuffer & in_, const Block & header_, Params params_, const FormatSchemaInfo & info_, const bool use_length_delimiters_)
|
2019-08-03 11:02:40 +00:00
|
|
|
: IRowInputFormat(header_, in_, params_)
|
2019-08-23 18:30:04 +00:00
|
|
|
, data_types(header_.getDataTypes())
|
2020-10-06 14:32:01 +00:00
|
|
|
, reader(in, ProtobufSchemas::instance().getMessageTypeForFormatSchema(info_), header_.getNames(), use_length_delimiters_)
|
2019-02-21 18:36:46 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ProtobufRowInputFormat::~ProtobufRowInputFormat() = default;
|
|
|
|
|
|
|
|
bool ProtobufRowInputFormat::readRow(MutableColumns & columns, RowReadExtension & extra)
|
|
|
|
{
|
|
|
|
if (!reader.startMessage())
|
|
|
|
return false; // EOF reached, no more messages.
|
|
|
|
|
|
|
|
// Set of columns for which the values were read. The rest will be filled with default values.
|
|
|
|
auto & read_columns = extra.read_columns;
|
|
|
|
read_columns.assign(columns.size(), false);
|
|
|
|
|
|
|
|
// Read values from this message and put them to the columns while it's possible.
|
|
|
|
size_t column_index;
|
|
|
|
while (reader.readColumnIndex(column_index))
|
|
|
|
{
|
|
|
|
bool allow_add_row = !static_cast<bool>(read_columns[column_index]);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
bool row_added;
|
|
|
|
data_types[column_index]->deserializeProtobuf(*columns[column_index], reader, allow_add_row, row_added);
|
|
|
|
if (row_added)
|
|
|
|
{
|
|
|
|
read_columns[column_index] = true;
|
|
|
|
allow_add_row = false;
|
|
|
|
}
|
2019-07-24 11:41:49 +00:00
|
|
|
} while (reader.canReadMoreValues());
|
2019-02-21 18:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fill non-visited columns with the default values.
|
|
|
|
for (column_index = 0; column_index < read_columns.size(); ++column_index)
|
|
|
|
if (!read_columns[column_index])
|
|
|
|
data_types[column_index]->insertDefaultInto(*columns[column_index]);
|
|
|
|
|
|
|
|
reader.endMessage();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ProtobufRowInputFormat::allowSyncAfterError() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ProtobufRowInputFormat::syncAfterError()
|
|
|
|
{
|
2019-07-24 11:41:49 +00:00
|
|
|
reader.endMessage(true);
|
2019-02-21 18:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void registerInputFormatProcessorProtobuf(FormatFactory & factory)
|
|
|
|
{
|
2020-10-06 14:32:01 +00:00
|
|
|
for (bool use_length_delimiters : {false, true})
|
2019-02-21 18:36:46 +00:00
|
|
|
{
|
2020-10-06 14:32:01 +00:00
|
|
|
factory.registerInputFormatProcessor(use_length_delimiters ? "Protobuf" : "ProtobufSingle", [use_length_delimiters](
|
2020-09-23 15:10:04 +00:00
|
|
|
ReadBuffer & buf,
|
|
|
|
const Block & sample,
|
|
|
|
IRowInputFormat::Params params,
|
|
|
|
const FormatSettings & settings)
|
|
|
|
{
|
|
|
|
return std::make_shared<ProtobufRowInputFormat>(buf, sample, std::move(params),
|
|
|
|
FormatSchemaInfo(settings.schema.format_schema, "Protobuf", true,
|
|
|
|
settings.schema.is_server, settings.schema.format_schema_path),
|
2020-10-06 14:32:01 +00:00
|
|
|
use_length_delimiters);
|
2020-09-23 15:10:04 +00:00
|
|
|
});
|
|
|
|
}
|
2019-02-21 18:36:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
class FormatFactory;
|
|
|
|
void registerInputFormatProcessorProtobuf(FormatFactory &) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|