2016-08-25 12:38:47 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <DB/DataStreams/IProfilingBlockInputStream.h>
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2016-09-21 12:31:50 +00:00
|
|
|
/// This stream allows perfoming INSERT requests in which the types of
|
2016-08-25 12:38:47 +00:00
|
|
|
/// 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
|
2016-08-25 13:23:24 +00:00
|
|
|
/// column is not, we extract the nested column from the source;
|
2016-08-25 12:38:47 +00:00
|
|
|
/// - otherwise we just perform an identity mapping.
|
|
|
|
class NullableAdapterBlockInputStream : public IProfilingBlockInputStream
|
|
|
|
{
|
2016-09-21 12:31:50 +00:00
|
|
|
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;
|
|
|
|
|
2016-08-25 12:38:47 +00:00
|
|
|
private:
|
|
|
|
/// Given a column of a block we have just read,
|
|
|
|
/// how must we process it?
|
|
|
|
enum Action
|
|
|
|
{
|
|
|
|
/// Do nothing.
|
|
|
|
NONE = 0,
|
2016-08-25 13:23:24 +00:00
|
|
|
/// Convert nullable column to ordinary column.
|
2016-08-25 12:38:47 +00:00
|
|
|
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.
|
2016-09-21 12:31:50 +00:00
|
|
|
bool mustTransform() const;
|
2016-08-25 12:38:47 +00:00
|
|
|
|
|
|
|
/// Determine the actions to be taken using the source sample block,
|
|
|
|
/// which describes the columns from which we fetch data inside an INSERT
|
2016-08-25 20:01:36 +00:00
|
|
|
/// query, and the target sample block which contains the columns
|
|
|
|
/// we insert data into.
|
2016-09-21 12:31:50 +00:00
|
|
|
Actions getActions(const Block & in_sample, const Block & out_sample) const;
|
2016-08-25 12:38:47 +00:00
|
|
|
|
|
|
|
private:
|
2016-09-21 12:31:50 +00:00
|
|
|
NamesAndTypesListPtr required_columns;
|
2016-08-25 12:38:47 +00:00
|
|
|
const Actions actions;
|
|
|
|
const bool must_transform;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|