#include #include #include #include namespace DB { template struct LeastBaseImpl { using ResultType = NumberTraits::ResultOfLeast; static const constexpr bool allow_fixed_string = false; template static inline Result apply(A a, B b) { /** gcc 4.9.2 successfully vectorizes a loop from this function. */ return bigint_cast(a) < bigint_cast(b) ? bigint_cast(a) : bigint_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()) /// XXX minnum is basically fmin(), it may or may not match whatever apply() does return b.CreateMinNum(left, right); return b.CreateSelect(is_signed ? b.CreateICmpSLT(left, right) : b.CreateICmpULT(left, right), left, right); } #endif }; template struct LeastSpecialImpl { using ResultType = std::make_signed_t; static const constexpr bool allow_fixed_string = 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; void registerFunctionLeast(FunctionFactory & factory) { factory.registerFunction>(FunctionFactory::CaseInsensitive); } }