Add CAST(NULL AS Null) support. [#CLICKHOUSE-2787]

This commit is contained in:
Vitaliy Lyudvichenko 2017-02-02 16:15:04 +03:00 committed by alexey-milovidov
parent 11b3aad985
commit df9ada58fb
3 changed files with 24 additions and 2 deletions

View File

@ -1498,6 +1498,22 @@ private:
}; };
} }
/// Only trivial NULL -> NULL case
WrapperType createNullWrapper(const DataTypePtr & from_type, const DataTypeNull * to_type)
{
if (!typeid_cast<const DataTypeNull *>(from_type.get()))
throw Exception("Conversion from " + from_type->getName() + " to " + to_type->getName() + " is not supported",
ErrorCodes::CANNOT_CONVERT_TYPE);
return [] (Block & block, const ColumnNumbers & arguments, const size_t result)
{
// just copy pointer to Null column
ColumnWithTypeAndName & res_col = block.safeGetByPosition(result);
const ColumnWithTypeAndName & src_col = block.safeGetByPosition(arguments.front());
res_col.column = src_col.column;
};
}
/// Actions to be taken when performing a conversion. /// Actions to be taken when performing a conversion.
struct Action struct Action
{ {
@ -1622,6 +1638,8 @@ private:
return createEnumWrapper(from_type, type_enum); return createEnumWrapper(from_type, type_enum);
else if (const auto type_enum = typeid_cast<const DataTypeEnum16 *>(to_type)) else if (const auto type_enum = typeid_cast<const DataTypeEnum16 *>(to_type))
return createEnumWrapper(from_type, type_enum); return createEnumWrapper(from_type, type_enum);
else if (const auto type_null = typeid_cast<const DataTypeNull *>(to_type))
return createNullWrapper(from_type, type_null);
/// It's possible to use ConvertImplGenericFromString to convert from String to AggregateFunction, /// It's possible to use ConvertImplGenericFromString to convert from String to AggregateFunction,
/// but it is disabled because deserializing aggregate functions state might be unsafe. /// but it is disabled because deserializing aggregate functions state might be unsafe.
@ -1704,7 +1722,7 @@ public:
if (from_type->isNullable()) if (from_type->isNullable())
action |= Action::UNWRAP_NULLABLE_INPUT; action |= Action::UNWRAP_NULLABLE_INPUT;
else if (from_type->isNull()) else if (from_type->isNull() && !out_return_type->isNull())
action |= Action::CONVERT_NULL; action |= Action::CONVERT_NULL;
if (out_return_type->isNullable()) if (out_return_type->isNullable())

View File

@ -3,3 +3,5 @@
\N \N
\N \N
\N \N
\N
\N

View File

@ -1,5 +1,7 @@
SELECT (SELECT 1 WHERE 0); SELECT (SELECT 1 WHERE 0);
SELECT (SELECT * FROM (SELECT * FROM system.numbers LIMIT 2) WHERE number = number + 1); SELECT (SELECT * FROM (SELECT * FROM system.numbers LIMIT 2) WHERE number = number + 1);
SELECT (SELECT Null WHERE 1);
SELECT (SELECT NULL WHERE 0); SELECT (SELECT NULL WHERE 0);
SELECT (SELECT Null WHERE nuLL IS NOT NULL); SELECT (SELECT Null WHERE nuLL IS NOT NULL);
SELECT (SELECT Null WHERE 1);
SELECT CAST(NULL as Null);
SELECT (SELECT CAST(NULL as Null) WHERE 0);