#include #include namespace DB { namespace { template struct ModuloOrZeroImpl { using ResultType = typename NumberTraits::ResultOfModulo::Type; 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) { if constexpr (std::is_floating_point_v) { /// This computation is similar to `fmod` but the latter is not inlined and has 40 times worse performance. return ResultType(a) - trunc(ResultType(a) / ResultType(b)) * ResultType(b); } else { if (unlikely(divisionLeadsToFPE(a, b))) return 0; return ModuloImpl::template apply(a, b); } } #if USE_EMBEDDED_COMPILER static constexpr bool compilable = false; /// TODO implement the checks #endif }; struct NameModuloOrZero { static constexpr auto name = "moduloOrZero"; }; using FunctionModuloOrZero = BinaryArithmeticOverloadResolver; } REGISTER_FUNCTION(ModuloOrZero) { factory.registerFunction(); } }