Merge branch 'master' into memory-profiler-fix

This commit is contained in:
Alexey Milovidov 2020-03-03 05:33:35 +03:00
commit 97011463e5
11 changed files with 74 additions and 21 deletions

View File

@ -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
};
}

View File

@ -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>

View File

@ -1,6 +1,5 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionBinaryArithmetic.h>
#include <Functions/intDiv.h>
#ifdef __SSE2__
#define LIBDIVIDE_USE_SSE2 1

View File

@ -1,8 +1,6 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionBinaryArithmetic.h>
#include "intDiv.h"
namespace DB
{

View File

@ -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

View 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>();
}
}

View File

@ -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);

View File

@ -35,6 +35,8 @@
<value>multiply</value>
<value>divide</value>
<value>intDivOrZero</value>
<value>modulo</value>
<value>moduloOrZero</value>
</values>
</substitution>
</substitutions>

View File

@ -0,0 +1,5 @@
1
1
1
1
1

View 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;

View File

@ -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.