mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
New behavior for least() and greatest() function with (Int64, UInt64) arguments. [#CLICKHOUSE-29]
This commit is contained in:
parent
56743008dd
commit
a1dcd24a76
@ -271,9 +271,9 @@ struct BitShiftRightImpl
|
||||
|
||||
|
||||
template<typename A, typename B>
|
||||
struct LeastImpl
|
||||
struct LeastBaseImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfIf<A, B>::Type;
|
||||
using ResultType = NumberTraits::ResultOfLeast<A, B>;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -283,10 +283,37 @@ struct LeastImpl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
struct GreatestImpl
|
||||
template<typename A>
|
||||
struct LeastSpecialImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfIf<A, B>::Type;
|
||||
using ResultType = std::make_signed_t<A>;
|
||||
using SecondType = std::make_unsigned_t<A>;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(ResultType a, SecondType b)
|
||||
{
|
||||
static_assert(std::is_same<Result, ResultType>::value, "typeof(a) != Result");
|
||||
return (a < static_cast<Result>(b) || a < 0 || b > static_cast<SecondType>(std::numeric_limits<ResultType>::max()))
|
||||
? a : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(SecondType a, ResultType b)
|
||||
{
|
||||
static_assert(std::is_same<Result, ResultType>::value, "typeof(b) != Result");
|
||||
return (b < static_cast<Result>(a) || b < 0 || a > static_cast<SecondType>(std::numeric_limits<ResultType>::max()))
|
||||
? b : static_cast<Result>(a);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
using LeastImpl = std::conditional_t<!NumberTraits::GreatestAndLeastSpecialCase<A, B>::value, LeastBaseImpl<A, B>, LeastSpecialImpl<A>>;
|
||||
|
||||
|
||||
template<typename A, typename B>
|
||||
struct GreatestBaseImpl
|
||||
{
|
||||
using ResultType = NumberTraits::ResultOfGreatest<A, B>;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
@ -295,6 +322,33 @@ struct GreatestImpl
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A>
|
||||
struct GreatestSpecialImpl
|
||||
{
|
||||
using ResultType = std::make_unsigned_t<A>;
|
||||
using SecondType = std::make_signed_t<A>;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(ResultType a, SecondType b)
|
||||
{
|
||||
static_assert(std::is_same<Result, ResultType>::value, "typeof(a) != Result");
|
||||
return (a > static_cast<Result>(b) || b < 0 || a > static_cast<Result>((std::numeric_limits<SecondType>::max())))
|
||||
? a : static_cast<Result>(b);
|
||||
}
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(SecondType a, ResultType b)
|
||||
{
|
||||
static_assert(std::is_same<Result, ResultType>::value, "typeof(b) != Result");
|
||||
return (b > static_cast<Result>(a) || a < 0 || b > static_cast<Result>((std::numeric_limits<SecondType>::max())))
|
||||
? b : static_cast<Result>(a);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename A, typename B>
|
||||
using GreatestImpl = std::conditional_t<!NumberTraits::GreatestAndLeastSpecialCase<A, B>::value, GreatestBaseImpl<A, B>, GreatestSpecialImpl<A>>;
|
||||
|
||||
|
||||
template<typename A>
|
||||
struct NegateImpl
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <DB/Core/Types.h>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
@ -263,6 +264,7 @@ template <typename A> struct ResultOfBitNot
|
||||
typename Traits<A>::Nullity>::Type Type;
|
||||
};
|
||||
|
||||
|
||||
/** Приведение типов для функции if:
|
||||
* 1) void, Type -> Type
|
||||
* 2) UInt<x>, UInt<y> -> UInt<max(x,y)>
|
||||
@ -302,7 +304,7 @@ struct ResultOfIf
|
||||
typename Traits<B>::Floatness,
|
||||
typename Traits<B>::Bits,
|
||||
typename ExactNext<typename Traits<B>::Bits>::Type>::type>::type,
|
||||
Bits32>::type,
|
||||
Bits32>::type,
|
||||
typename boost::mpl::or_<typename Traits<A>::Nullity, typename Traits<B>::Nullity>::type>::Type,
|
||||
/// 2) and 3)
|
||||
typename boost::mpl::if_<
|
||||
@ -342,10 +344,26 @@ template <typename A> struct ToInteger
|
||||
typename Traits<A>::Floatness,
|
||||
Bits64,
|
||||
typename Traits<A>::Bits>::type,
|
||||
typename Traits<A>::Nullity
|
||||
typename Traits<A>::Nullity
|
||||
>::Type Type;
|
||||
};
|
||||
|
||||
|
||||
// CLICKHOUSE-29. The same depth, different signs
|
||||
template <typename A, typename B>
|
||||
using GreatestAndLeastSpecialCase = std::integral_constant<bool, std::is_integral<A>::value && std::is_integral<B>::value
|
||||
&& (sizeof(A) == sizeof(B)) && (std::is_signed<A>::value ^ std::is_signed<B>::value)>;
|
||||
|
||||
template <typename A, typename B>
|
||||
using ResultOfLeast = std::conditional_t<GreatestAndLeastSpecialCase<A, B>::value,
|
||||
typename Construct<Signed, Integer, typename Traits<A>::Bits, HasNoNull>::Type,
|
||||
typename ResultOfIf<A, B>::Type>;
|
||||
|
||||
template <typename A, typename B>
|
||||
using ResultOfGreatest = std::conditional_t<GreatestAndLeastSpecialCase<A, B>::value,
|
||||
typename Construct<Unsigned, Integer, typename Traits<A>::Bits, HasNoNull>::Type,
|
||||
typename ResultOfIf<A, B>::Type>;
|
||||
|
||||
/// Notes on type composition.
|
||||
///
|
||||
/// I. Problem statement.
|
||||
|
@ -0,0 +1,3 @@
|
||||
Int8 UInt8 Int64 UInt64
|
||||
0 -400 127 -1 -1 -128 -128 -9223372036854775808 -9223372036854775807 9223372036854775807
|
||||
1 -200 255 1 1 254 255 18446744073709551615 18446744073709551615 9223372036854775808
|
@ -0,0 +1,3 @@
|
||||
SELECT toTypeName(least(-1, 1)), toTypeName(greatest(-1, 1)), toTypeName(least(-9223372036854775808, 18446744073709551615)), toTypeName(greatest(-9223372036854775808, 18446744073709551615));
|
||||
SELECT least(0, 1), least(-400, -200), least(toInt8(127), 255), least(-1, 1), least(toUInt64(1), toInt64(-1)), least(-128, 254), least(-128, 255), least(-9223372036854775808, 18446744073709551615), least(-9223372036854775807, 18446744073709551615), least(toInt64(9223372036854775807), 9223372036854775808);
|
||||
SELECT greatest(0, 1), greatest(-400, -200), greatest(toInt8(127), 255), greatest(-1, 1), greatest(toUInt64(1), toInt64(-1)), greatest(-128, 254), greatest(-128, 255), greatest(-9223372036854775808, 18446744073709551615), greatest(-9223372036854775807, 18446744073709551615), greatest(toInt64(9223372036854775807), 9223372036854775808);
|
Loading…
Reference in New Issue
Block a user