ClickHouse/dbms/include/DB/DataStreams/NullableAdapterBlockInputStream.h
2016-12-30 08:13:14 +03:00

62 lines
1.8 KiB
C++

#pragma once
#include <DB/DataStreams/IProfilingBlockInputStream.h>
namespace DB
{
/// This stream allows perfoming INSERT requests in which the types of
/// the target and source blocks are compatible up to nullability:
///
/// - if a target column is nullable while the corresponding source
/// column is not, we embed the source column into a nullable column;
/// - if a source column is nullable while the corresponding target
/// column is not, we extract the nested column from the source; /// TODO Probably this is totally incorrect.
/// - otherwise we just perform an identity mapping.
class NullableAdapterBlockInputStream : public IProfilingBlockInputStream
{
public:
NullableAdapterBlockInputStream(BlockInputStreamPtr input_, const Block & in_sample_,
const Block & out_sample_, const NamesAndTypesListPtr & required_columns_);
String getName() const override { return "NullableAdapterBlockInputStream"; }
String getID() const override;
protected:
Block readImpl() override;
private:
/// Given a column of a block we have just read,
/// how must we process it?
enum Action
{
/// Do nothing.
NONE = 0,
/// Convert nullable column to ordinary column.
TO_ORDINARY,
/// Convert non-nullable column to nullable column.
TO_NULLABLE
};
/// Actions to be taken for each column of a block.
using Actions = std::vector<Action>;
private:
/// Return true if we must transform the blocks we read.
bool mustTransform() const;
/// Determine the actions to be taken using the source sample block,
/// which describes the columns from which we fetch data inside an INSERT
/// query, and the target sample block which contains the columns
/// we insert data into.
Actions getActions(const Block & in_sample, const Block & out_sample) const;
private:
NamesAndTypesListPtr required_columns;
const Actions actions;
const bool must_transform;
};
}