1 | #include <Functions/FunctionFactory.h> |
2 | #include <Functions/FunctionBinaryArithmetic.h> |
3 | #include <common/arithmeticOverflow.h> |
4 | |
5 | namespace DB |
6 | { |
7 | |
8 | template <typename A, typename B> |
9 | struct PlusImpl |
10 | { |
11 | using ResultType = typename NumberTraits::ResultOfAdditionMultiplication<A, B>::Type; |
12 | static const constexpr bool allow_decimal = true; |
13 | |
14 | template <typename Result = ResultType> |
15 | static inline NO_SANITIZE_UNDEFINED Result apply(A a, B b) |
16 | { |
17 | /// Next everywhere, static_cast - so that there is no wrong result in expressions of the form Int64 c = UInt32(a) * Int32(-1). |
18 | return static_cast<Result>(a) + b; |
19 | } |
20 | |
21 | /// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false otherwise. |
22 | template <typename Result = ResultType> |
23 | static inline bool apply(A a, B b, Result & c) |
24 | { |
25 | return common::addOverflow(static_cast<Result>(a), b, c); |
26 | } |
27 | |
28 | #if USE_EMBEDDED_COMPILER |
29 | static constexpr bool compilable = true; |
30 | |
31 | static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool) |
32 | { |
33 | return left->getType()->isIntegerTy() ? b.CreateAdd(left, right) : b.CreateFAdd(left, right); |
34 | } |
35 | #endif |
36 | }; |
37 | |
38 | struct NamePlus { static constexpr auto name = "plus" ; }; |
39 | using FunctionPlus = FunctionBinaryArithmetic<PlusImpl, NamePlus>; |
40 | |
41 | void registerFunctionPlus(FunctionFactory & factory) |
42 | { |
43 | factory.registerFunction<FunctionPlus>(); |
44 | } |
45 | |
46 | } |
47 | |