mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-10 09:32:06 +00:00
Allow Nullable types in MySQL, ODBC and MongoDB external sources #3284
This commit is contained in:
parent
d5bfe37879
commit
4bb8da039f
@ -29,37 +29,38 @@ void ExternalResultDescription::init(const Block & sample_block_)
|
||||
if (elem.column->empty())
|
||||
elem.column = elem.type->createColumnConstWithDefaultValue(1)->convertToFullColumnIfConst();
|
||||
|
||||
bool is_nullable = elem.type->isNullable();
|
||||
DataTypePtr type_not_nullable = removeNullable(elem.type);
|
||||
const IDataType * type = type_not_nullable.get();
|
||||
|
||||
if (typeid_cast<const DataTypeUInt8 *>(type))
|
||||
types.push_back(ValueType::UInt8);
|
||||
types.emplace_back(ValueType::UInt8, is_nullable);
|
||||
else if (typeid_cast<const DataTypeUInt16 *>(type))
|
||||
types.push_back(ValueType::UInt16);
|
||||
types.emplace_back(ValueType::UInt16, is_nullable);
|
||||
else if (typeid_cast<const DataTypeUInt32 *>(type))
|
||||
types.push_back(ValueType::UInt32);
|
||||
types.emplace_back(ValueType::UInt32, is_nullable);
|
||||
else if (typeid_cast<const DataTypeUInt64 *>(type))
|
||||
types.push_back(ValueType::UInt64);
|
||||
types.emplace_back(ValueType::UInt64, is_nullable);
|
||||
else if (typeid_cast<const DataTypeInt8 *>(type))
|
||||
types.push_back(ValueType::Int8);
|
||||
types.emplace_back(ValueType::Int8, is_nullable);
|
||||
else if (typeid_cast<const DataTypeInt16 *>(type))
|
||||
types.push_back(ValueType::Int16);
|
||||
types.emplace_back(ValueType::Int16, is_nullable);
|
||||
else if (typeid_cast<const DataTypeInt32 *>(type))
|
||||
types.push_back(ValueType::Int32);
|
||||
types.emplace_back(ValueType::Int32, is_nullable);
|
||||
else if (typeid_cast<const DataTypeInt64 *>(type))
|
||||
types.push_back(ValueType::Int64);
|
||||
types.emplace_back(ValueType::Int64, is_nullable);
|
||||
else if (typeid_cast<const DataTypeFloat32 *>(type))
|
||||
types.push_back(ValueType::Float32);
|
||||
types.emplace_back(ValueType::Float32, is_nullable);
|
||||
else if (typeid_cast<const DataTypeFloat64 *>(type))
|
||||
types.push_back(ValueType::Float64);
|
||||
types.emplace_back(ValueType::Float64, is_nullable);
|
||||
else if (typeid_cast<const DataTypeString *>(type))
|
||||
types.push_back(ValueType::String);
|
||||
types.emplace_back(ValueType::String, is_nullable);
|
||||
else if (typeid_cast<const DataTypeDate *>(type))
|
||||
types.push_back(ValueType::Date);
|
||||
types.emplace_back(ValueType::Date, is_nullable);
|
||||
else if (typeid_cast<const DataTypeDateTime *>(type))
|
||||
types.push_back(ValueType::DateTime);
|
||||
types.emplace_back(ValueType::DateTime, is_nullable);
|
||||
else if (typeid_cast<const DataTypeUUID *>(type))
|
||||
types.push_back(ValueType::UUID);
|
||||
types.emplace_back(ValueType::UUID, is_nullable);
|
||||
else
|
||||
throw Exception{"Unsupported type " + type->getName(), ErrorCodes::UNKNOWN_TYPE};
|
||||
}
|
||||
|
@ -25,14 +25,11 @@ struct ExternalResultDescription
|
||||
String,
|
||||
Date,
|
||||
DateTime,
|
||||
UUID
|
||||
UUID,
|
||||
};
|
||||
|
||||
/// For Nullable source types, these types correspond to their nested types.
|
||||
std::vector<ValueType> types;
|
||||
|
||||
/// May contain Nullable types.
|
||||
Block sample_block;
|
||||
std::vector<std::pair<ValueType, bool /* is_nullable */>> types;
|
||||
|
||||
void init(const Block & sample_block_);
|
||||
};
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <Dictionaries/MongoDBBlockInputStream.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <Common/FieldVisitors.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
@ -185,7 +186,16 @@ Block MongoDBBlockInputStream::readImpl()
|
||||
if (value.isNull() || value->type() == Poco::MongoDB::ElementTraits<Poco::MongoDB::NullValue>::TypeId)
|
||||
insertDefaultValue(*columns[idx], *description.sample_block.getByPosition(idx).column);
|
||||
else
|
||||
insertValue(*columns[idx], description.types[idx], *value, name);
|
||||
{
|
||||
if (description.types[idx].second)
|
||||
{
|
||||
ColumnNullable & column_nullable = static_cast<ColumnNullable &>(*columns[idx]);
|
||||
insertValue(column_nullable.getNestedColumn(), description.types[idx].first, *value, name);
|
||||
column_nullable.getNullMapData().emplace_back(0);
|
||||
}
|
||||
else
|
||||
insertValue(*columns[idx], description.types[idx].first, *value, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <Dictionaries/MySQLBlockInputStream.h>
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
#include <ext/range.h>
|
||||
@ -82,7 +83,16 @@ Block MySQLBlockInputStream::readImpl()
|
||||
{
|
||||
const auto value = row[idx];
|
||||
if (!value.isNull())
|
||||
insertValue(*columns[idx], description.types[idx], value);
|
||||
{
|
||||
if (description.types[idx].second)
|
||||
{
|
||||
ColumnNullable & column_nullable = static_cast<ColumnNullable &>(*columns[idx]);
|
||||
insertValue(column_nullable.getNestedColumn(), description.types[idx].first, value);
|
||||
column_nullable.getNullMapData().emplace_back(0);
|
||||
}
|
||||
else
|
||||
insertValue(*columns[idx], description.types[idx].first, value);
|
||||
}
|
||||
else
|
||||
insertDefaultValue(*columns[idx], *description.sample_block.getByPosition(idx).column);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <Columns/ColumnsNumber.h>
|
||||
#include <Columns/ColumnString.h>
|
||||
#include <Columns/ColumnNullable.h>
|
||||
|
||||
#include <IO/ReadHelpers.h>
|
||||
#include <IO/WriteHelpers.h>
|
||||
@ -91,7 +92,16 @@ Block ODBCBlockInputStream::readImpl()
|
||||
const Poco::Dynamic::Var & value = row[idx];
|
||||
|
||||
if (!value.isEmpty())
|
||||
insertValue(*columns[idx], description.types[idx], value);
|
||||
{
|
||||
if (description.types[idx].second)
|
||||
{
|
||||
ColumnNullable & column_nullable = static_cast<ColumnNullable &>(*columns[idx]);
|
||||
insertValue(column_nullable.getNestedColumn(), description.types[idx].first, value);
|
||||
column_nullable.getNullMapData().emplace_back(0);
|
||||
}
|
||||
else
|
||||
insertValue(*columns[idx], description.types[idx].first, value);
|
||||
}
|
||||
else
|
||||
insertDefaultValue(*columns[idx], *description.sample_block.getByPosition(idx).column);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user