Merge pull request #3358 from yandex/fix-function-if

Fixed error with function 'if' introduced in #3342
This commit is contained in:
alexey-milovidov 2018-10-12 03:18:48 +03:00 committed by GitHub
commit 8d76a55ca1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 70 additions and 23 deletions

View File

@ -16,7 +16,7 @@ struct TypePair
template <typename T, bool _int, bool _float, bool _dec, typename F>
template <typename T, bool _int, bool _float, bool _decimal, bool _datetime, typename F>
bool callOnBasicType(TypeIndex number, F && f)
{
if constexpr (_int)
@ -40,7 +40,7 @@ bool callOnBasicType(TypeIndex number, F && f)
}
}
if constexpr (_dec)
if constexpr (_decimal)
{
switch (number)
{
@ -63,40 +63,51 @@ bool callOnBasicType(TypeIndex number, F && f)
}
}
if constexpr (_datetime)
{
switch (number)
{
case TypeIndex::Date: return f(TypePair<T, UInt16>());
case TypeIndex::DateTime: return f(TypePair<T, UInt32>());
default:
break;
}
}
return false;
}
/// Unroll template using TypeIndex
template <bool _int, bool _float, bool _dec, typename F>
template <bool _int, bool _float, bool _decimal, bool _datetime, typename F>
inline bool callOnBasicTypes(TypeIndex type_num1, TypeIndex type_num2, F && f)
{
if constexpr (_int)
{
switch (type_num1)
{
case TypeIndex::UInt8: return callOnBasicType<UInt8, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::UInt16: return callOnBasicType<UInt16, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::UInt32: return callOnBasicType<UInt32, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::UInt64: return callOnBasicType<UInt64, _int, _float, _dec>(type_num2, std::forward<F>(f));
//case TypeIndex::UInt128: return callOnBasicType<UInt128, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::UInt8: return callOnBasicType<UInt8, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::UInt16: return callOnBasicType<UInt16, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::UInt32: return callOnBasicType<UInt32, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::UInt64: return callOnBasicType<UInt64, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
//case TypeIndex::UInt128: return callOnBasicType<UInt128, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Int8: return callOnBasicType<Int8, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Int16: return callOnBasicType<Int16, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Int32: return callOnBasicType<Int32, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Int64: return callOnBasicType<Int64, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Int128: return callOnBasicType<Int128, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Int8: return callOnBasicType<Int8, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Int16: return callOnBasicType<Int16, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Int32: return callOnBasicType<Int32, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Int64: return callOnBasicType<Int64, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Int128: return callOnBasicType<Int128, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
default:
break;
}
}
if constexpr (_dec)
if constexpr (_decimal)
{
switch (type_num1)
{
case TypeIndex::Decimal32: return callOnBasicType<Decimal32, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Decimal64: return callOnBasicType<Decimal64, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Decimal128: return callOnBasicType<Decimal128, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Decimal32: return callOnBasicType<Decimal32, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Decimal64: return callOnBasicType<Decimal64, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Decimal128: return callOnBasicType<Decimal128, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
default:
break;
}
@ -106,8 +117,19 @@ inline bool callOnBasicTypes(TypeIndex type_num1, TypeIndex type_num2, F && f)
{
switch (type_num1)
{
case TypeIndex::Float32: return callOnBasicType<Float32, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Float64: return callOnBasicType<Float64, _int, _float, _dec>(type_num2, std::forward<F>(f));
case TypeIndex::Float32: return callOnBasicType<Float32, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::Float64: return callOnBasicType<Float64, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
default:
break;
}
}
if constexpr (_datetime)
{
switch (type_num1)
{
case TypeIndex::Date: return callOnBasicType<UInt16, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
case TypeIndex::DateTime: return callOnBasicType<UInt32, _int, _float, _decimal, _datetime>(type_num2, std::forward<F>(f));
default:
break;
}

View File

@ -725,7 +725,7 @@ private:
return true;
};
if (!callOnBasicTypes<true, false, true>(left_number, right_number, call))
if (!callOnBasicTypes<true, false, true, false>(left_number, right_number, call))
throw Exception("Wrong call for " + getName() + " with " + col_left.type->getName() + " and " + col_right.type->getName(),
ErrorCodes::LOGICAL_ERROR);
}

View File

@ -975,7 +975,7 @@ public:
if (auto rigth_array = checkAndGetDataType<DataTypeArray>(arg_else.type.get()))
right_id = rigth_array->getNestedType()->getTypeId();
bool executed_with_nums = callOnBasicTypes<true, true, true>(left_id, right_id, call);
bool executed_with_nums = callOnBasicTypes<true, true, true, true>(left_id, right_id, call);
if (!( executed_with_nums
|| executeString(cond_col, block, arguments, result)

View File

@ -162,7 +162,7 @@ private:
return execute<Type>(block, col_vec, result);
};
if (!callOnBasicType<void, true, true, true>(col.type->getTypeId(), call))
if (!callOnBasicType<void, true, true, true, false>(col.type->getTypeId(), call))
throw Exception{"Illegal column " + col.column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
}
@ -385,7 +385,7 @@ private:
TypeIndex left_index = col_left.type->getTypeId();
TypeIndex right_index = col_right.type->getTypeId();
if (!callOnBasicTypes<true, true, false>(left_index, right_index, call))
if (!callOnBasicTypes<true, true, false, false>(left_index, right_index, call))
throw Exception{"Illegal column " + col_left.column->getName() + " of argument of function " + getName(),
ErrorCodes::ILLEGAL_COLUMN};
}

View File

@ -0,0 +1,16 @@
2001-02-03 04:05:06
2000-01-01 00:00:00
2001-02-03 04:05:06
2000-01-01 00:00:00
2001-02-03 04:05:06
2000-01-01 00:00:00
2001-02-03 04:05:06
2000-01-01 00:00:00
2001-02-03
2000-01-01
2001-02-03
2000-01-01
2001-02-03
2000-01-01
2001-02-03
2000-01-01

View File

@ -0,0 +1,9 @@
SELECT number % 2 ? toDateTime('2000-01-01 00:00:00') : toDateTime('2001-02-03 04:05:06') FROM numbers(2);
SELECT number % 2 ? toDateTime('2000-01-01 00:00:00') : materialize(toDateTime('2001-02-03 04:05:06')) FROM numbers(2);
SELECT number % 2 ? materialize(toDateTime('2000-01-01 00:00:00')) : toDateTime('2001-02-03 04:05:06') FROM numbers(2);
SELECT number % 2 ? materialize(toDateTime('2000-01-01 00:00:00')) : materialize(toDateTime('2001-02-03 04:05:06')) FROM numbers(2);
SELECT number % 2 ? toDate('2000-01-01') : toDate('2001-02-03') FROM numbers(2);
SELECT number % 2 ? toDate('2000-01-01') : materialize(toDate('2001-02-03')) FROM numbers(2);
SELECT number % 2 ? materialize(toDate('2000-01-01')) : toDate('2001-02-03') FROM numbers(2);
SELECT number % 2 ? materialize(toDate('2000-01-01')) : materialize(toDate('2001-02-03')) FROM numbers(2);