#include #include #include #include namespace DB { template struct AbsImpl { using ResultType = std::conditional_t, A, typename NumberTraits::ResultOfAbs::Type>; static const constexpr bool allow_fixed_string = false; static inline NO_SANITIZE_UNDEFINED ResultType apply(A a) { if constexpr (IsDecimalNumber) return a < 0 ? A(-a) : a; else if constexpr (is_integral_v && is_signed_v) return a < 0 ? static_cast(~a) + 1 : a; else if constexpr (is_integral_v && is_unsigned_v) return static_cast(a); else if constexpr (std::is_floating_point_v) return static_cast(std::abs(a)); } #if USE_EMBEDDED_COMPILER static constexpr bool compilable = false; /// special type handling, some other time #endif }; struct NameAbs { static constexpr auto name = "abs"; }; using FunctionAbs = FunctionUnaryArithmetic; template <> struct FunctionUnaryArithmeticMonotonicity { static bool has() { return true; } static IFunction::Monotonicity get(const Field & left, const Field & right) { Float64 left_float = left.isNull() ? -std::numeric_limits::infinity() : applyVisitor(FieldVisitorConvertToNumber(), left); Float64 right_float = right.isNull() ? std::numeric_limits::infinity() : applyVisitor(FieldVisitorConvertToNumber(), right); if ((left_float < 0 && right_float > 0) || (left_float > 0 && right_float < 0)) return {}; return { true, (left_float > 0) }; } }; void registerFunctionAbs(FunctionFactory & factory) { factory.registerFunction(FunctionFactory::CaseInsensitive); } }