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 MultiplyImpl |
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 | return static_cast<Result>(a) * b; |
18 | } |
19 | |
20 | /// Apply operation and check overflow. It's used for Deciamal operations. @returns true if overflowed, false otherwise. |
21 | template <typename Result = ResultType> |
22 | static inline bool apply(A a, B b, Result & c) |
23 | { |
24 | return common::mulOverflow(static_cast<Result>(a), b, c); |
25 | } |
26 | |
27 | #if USE_EMBEDDED_COMPILER |
28 | static constexpr bool compilable = true; |
29 | |
30 | static inline llvm::Value * compile(llvm::IRBuilder<> & b, llvm::Value * left, llvm::Value * right, bool) |
31 | { |
32 | return left->getType()->isIntegerTy() ? b.CreateMul(left, right) : b.CreateFMul(left, right); |
33 | } |
34 | #endif |
35 | }; |
36 | |
37 | struct NameMultiply { static constexpr auto name = "multiply" ; }; |
38 | using FunctionMultiply = FunctionBinaryArithmetic<MultiplyImpl, NameMultiply>; |
39 | |
40 | void registerFunctionMultiply(FunctionFactory & factory) |
41 | { |
42 | factory.registerFunction<FunctionMultiply>(); |
43 | } |
44 | |
45 | } |
46 | |