#include #include #include #include namespace DB { template struct LeastBaseImpl { using ResultType = NumberTraits::ResultOfLeast; static const constexpr bool allow_fixed_string = false; static const constexpr bool allow_string_integer = false; template static inline Result apply(A a, B b) { /** gcc 4.9.2 successfully vectorizes a loop from this function. */ return static_cast(a) < static_cast(b) ? static_cast(a) : static_cast(b); } #if USE_EMBEDDED_COMPILER static constexpr bool compilable = true; static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool is_signed) { if (!left->getType()->isIntegerTy()) { /// Follows the IEEE-754 semantics for minNum, except for handling of signaling NaNs. This match’s the behavior of libc fmin. return b.CreateMinNum(left, right); } auto * compare_value = is_signed ? b.CreateICmpSLT(left, right) : b.CreateICmpULT(left, right); return b.CreateSelect(compare_value, left, right); } #endif }; template struct LeastSpecialImpl { using ResultType = std::make_signed_t; static const constexpr bool allow_fixed_string = false; static const constexpr bool allow_string_integer = false; template static inline Result apply(A a, B b) { static_assert(std::is_same_v, "ResultType != Result"); return accurate::lessOp(a, b) ? static_cast(a) : static_cast(b); } #if USE_EMBEDDED_COMPILER static constexpr bool compilable = false; /// ??? #endif }; template using LeastImpl = std::conditional_t, LeastBaseImpl, LeastSpecialImpl>; struct NameLeast { static constexpr auto name = "least"; }; using FunctionLeast = FunctionBinaryArithmetic; REGISTER_FUNCTION(Least) { factory.registerFunction>(FunctionFactory::CaseInsensitive); } }