ClickHouse
71 строка · 2.3 Кб
1#include <Functions/FunctionFactory.h>2#include <Functions/FunctionBinaryArithmetic.h>3#include <Core/AccurateComparison.h>4#include <Functions/LeastGreatestGeneric.h>5
6
7namespace DB8{
9
10template <typename A, typename B>11struct GreatestBaseImpl12{
13using ResultType = NumberTraits::ResultOfGreatest<A, B>;14static const constexpr bool allow_fixed_string = false;15static const constexpr bool allow_string_integer = false;16
17template <typename Result = ResultType>18static inline Result apply(A a, B b)19{20return static_cast<Result>(a) > static_cast<Result>(b) ?21static_cast<Result>(a) : static_cast<Result>(b);22}23
24#if USE_EMBEDDED_COMPILER25static constexpr bool compilable = true;26
27static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed)28{29if (!left->getType()->isIntegerTy())30{31/// Follows the IEEE-754 semantics for maxNum except for the handling of signaling NaNs. This matches the behavior of libc fmax.32return b.CreateMaxNum(left, right);33}34
35auto * compare_value = is_signed ? b.CreateICmpSGT(left, right) : b.CreateICmpUGT(left, right);36return b.CreateSelect(compare_value, left, right);37}38#endif39};40
41template <typename A, typename B>42struct GreatestSpecialImpl43{
44using ResultType = make_unsigned_t<A>;45static const constexpr bool allow_fixed_string = false;46static const constexpr bool allow_string_integer = false;47
48template <typename Result = ResultType>49static inline Result apply(A a, B b)50{51static_assert(std::is_same_v<Result, ResultType>, "ResultType != Result");52return accurate::greaterOp(a, b) ? static_cast<Result>(a) : static_cast<Result>(b);53}54
55#if USE_EMBEDDED_COMPILER56static constexpr bool compilable = false; /// ???57#endif58};59
60template <typename A, typename B>61using GreatestImpl = std::conditional_t<!NumberTraits::LeastGreatestSpecialCase<A, B>, GreatestBaseImpl<A, B>, GreatestSpecialImpl<A, B>>;62
63struct NameGreatest { static constexpr auto name = "greatest"; };64using FunctionGreatest = FunctionBinaryArithmetic<GreatestImpl, NameGreatest>;65
66REGISTER_FUNCTION(Greatest)67{
68factory.registerFunction<LeastGreatestOverloadResolver<LeastGreatest::Greatest, FunctionGreatest>>({}, FunctionFactory::CaseInsensitive);69}
70
71}
72