mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Merge branch 'master' into memory-profiler-fix
This commit is contained in:
commit
97011463e5
@ -70,4 +70,22 @@ struct DivideIntegralImpl
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct ModuloImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfModulo<A, B>::Type;
|
||||
static const constexpr bool allow_fixed_string = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<A>::Type(a), typename NumberTraits::ToInteger<B>::Type(b));
|
||||
return typename NumberTraits::ToInteger<A>::Type(a) % typename NumberTraits::ToInteger<B>::Type(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// don't know how to throw from LLVM IR
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
@ -22,7 +22,7 @@
|
||||
#include <Columns/ColumnAggregateFunction.h>
|
||||
#include "IFunctionImpl.h"
|
||||
#include "FunctionHelpers.h"
|
||||
#include "intDiv.h"
|
||||
#include "DivisionUtils.h"
|
||||
#include "castTypeToEither.h"
|
||||
#include "FunctionFactory.h"
|
||||
#include <Common/typeid_cast.h>
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionBinaryArithmetic.h>
|
||||
#include <Functions/intDiv.h>
|
||||
|
||||
#ifdef __SSE2__
|
||||
#define LIBDIVIDE_USE_SSE2 1
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionBinaryArithmetic.h>
|
||||
|
||||
#include "intDiv.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
@ -16,23 +16,7 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_DIVISION;
|
||||
}
|
||||
|
||||
template <typename A, typename B>
|
||||
struct ModuloImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfModulo<A, B>::Type;
|
||||
static const constexpr bool allow_fixed_string = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
throwIfDivisionLeadsToFPE(typename NumberTraits::ToInteger<A>::Type(a), typename NumberTraits::ToInteger<B>::Type(b));
|
||||
return typename NumberTraits::ToInteger<A>::Type(a) % typename NumberTraits::ToInteger<B>::Type(b);
|
||||
}
|
||||
|
||||
#if USE_EMBEDDED_COMPILER
|
||||
static constexpr bool compilable = false; /// don't know how to throw from LLVM IR
|
||||
#endif
|
||||
};
|
||||
/// Optimizations for integer modulo by a constant.
|
||||
|
||||
template <typename A, typename B>
|
||||
struct ModuloByConstantImpl
|
||||
|
36
dbms/src/Functions/moduloOrZero.cpp
Normal file
36
dbms/src/Functions/moduloOrZero.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionBinaryArithmetic.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
template <typename A, typename B>
|
||||
struct ModuloOrZeroImpl
|
||||
{
|
||||
using ResultType = typename NumberTraits::ResultOfModulo<A, B>::Type;
|
||||
static const constexpr bool allow_fixed_string = false;
|
||||
|
||||
template <typename Result = ResultType>
|
||||
static inline Result apply(A a, B b)
|
||||
{
|
||||
if (unlikely(divisionLeadsToFPE(a, b)))
|
||||
return 0;
|
||||
|
||||
return ModuloImpl<A, B>::template apply<Result>(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 = FunctionBinaryArithmetic<ModuloOrZeroImpl, NameModuloOrZero>;
|
||||
|
||||
void registerFunctionModuloOrZero(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionModuloOrZero>();
|
||||
}
|
||||
|
||||
}
|
@ -10,6 +10,7 @@ void registerFunctionDivide(FunctionFactory & factory);
|
||||
void registerFunctionIntDiv(FunctionFactory & factory);
|
||||
void registerFunctionIntDivOrZero(FunctionFactory & factory);
|
||||
void registerFunctionModulo(FunctionFactory & factory);
|
||||
void registerFunctionModuloOrZero(FunctionFactory & factory);
|
||||
void registerFunctionNegate(FunctionFactory & factory);
|
||||
void registerFunctionAbs(FunctionFactory & factory);
|
||||
void registerFunctionBitAnd(FunctionFactory & factory);
|
||||
@ -49,6 +50,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
|
||||
registerFunctionIntDiv(factory);
|
||||
registerFunctionIntDivOrZero(factory);
|
||||
registerFunctionModulo(factory);
|
||||
registerFunctionModuloOrZero(factory);
|
||||
registerFunctionNegate(factory);
|
||||
registerFunctionAbs(factory);
|
||||
registerFunctionBitAnd(factory);
|
||||
|
@ -35,6 +35,8 @@
|
||||
<value>multiply</value>
|
||||
<value>divide</value>
|
||||
<value>intDivOrZero</value>
|
||||
<value>modulo</value>
|
||||
<value>moduloOrZero</value>
|
||||
</values>
|
||||
</substitution>
|
||||
</substitutions>
|
||||
|
@ -0,0 +1,5 @@
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
5
dbms/tests/queries/0_stateless/01086_modulo_or_zero.sql
Normal file
5
dbms/tests/queries/0_stateless/01086_modulo_or_zero.sql
Normal file
@ -0,0 +1,5 @@
|
||||
select moduloOrZero(0, 0) = 0;
|
||||
select moduloOrZero(-128, -1) = 0;
|
||||
select moduloOrZero(-127, -1) = 0;
|
||||
select moduloOrZero(1, 1) = 0;
|
||||
select moduloOrZero(5, 3) = 2;
|
@ -55,6 +55,10 @@ If arguments are floating-point numbers, they are pre-converted to integers by d
|
||||
The remainder is taken in the same sense as in C++. Truncated division is used for negative numbers.
|
||||
An exception is thrown when dividing by zero or when dividing a minimal negative number by minus one.
|
||||
|
||||
## moduloOrZero(a, b)
|
||||
|
||||
Differs from 'modulo' in that it returns zero when the divisor is zero.
|
||||
|
||||
## negate(a), -a operator
|
||||
|
||||
Calculates a number with the reverse sign. The result is always signed.
|
||||
|
Loading…
Reference in New Issue
Block a user