1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/common/operator/multiply.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/types.hpp" |
12 | #include "duckdb/common/exception.hpp" |
13 | #include "duckdb/common/type_util.hpp" |
14 | |
15 | namespace duckdb { |
16 | |
17 | struct interval_t; |
18 | |
19 | struct MultiplyOperator { |
20 | template <class TA, class TB, class TR> |
21 | static inline TR Operation(TA left, TB right) { |
22 | return left * right; |
23 | } |
24 | }; |
25 | |
26 | template <> |
27 | float MultiplyOperator::Operation(float left, float right); |
28 | template <> |
29 | double MultiplyOperator::Operation(double left, double right); |
30 | template <> |
31 | interval_t MultiplyOperator::Operation(interval_t left, int64_t right); |
32 | template <> |
33 | interval_t MultiplyOperator::Operation(int64_t left, interval_t right); |
34 | |
35 | struct TryMultiplyOperator { |
36 | template <class TA, class TB, class TR> |
37 | static inline bool Operation(TA left, TB right, TR &result) { |
38 | throw InternalException("Unimplemented type for TryMultiplyOperator" ); |
39 | } |
40 | }; |
41 | |
42 | template <> |
43 | bool TryMultiplyOperator::Operation(uint8_t left, uint8_t right, uint8_t &result); |
44 | template <> |
45 | bool TryMultiplyOperator::Operation(uint16_t left, uint16_t right, uint16_t &result); |
46 | template <> |
47 | bool TryMultiplyOperator::Operation(uint32_t left, uint32_t right, uint32_t &result); |
48 | template <> |
49 | bool TryMultiplyOperator::Operation(uint64_t left, uint64_t right, uint64_t &result); |
50 | |
51 | template <> |
52 | bool TryMultiplyOperator::Operation(int8_t left, int8_t right, int8_t &result); |
53 | template <> |
54 | bool TryMultiplyOperator::Operation(int16_t left, int16_t right, int16_t &result); |
55 | template <> |
56 | bool TryMultiplyOperator::Operation(int32_t left, int32_t right, int32_t &result); |
57 | template <> |
58 | DUCKDB_API bool TryMultiplyOperator::Operation(int64_t left, int64_t right, int64_t &result); |
59 | template <> |
60 | DUCKDB_API bool TryMultiplyOperator::Operation(hugeint_t left, hugeint_t right, hugeint_t &result); |
61 | |
62 | struct MultiplyOperatorOverflowCheck { |
63 | template <class TA, class TB, class TR> |
64 | static inline TR Operation(TA left, TB right) { |
65 | TR result; |
66 | if (!TryMultiplyOperator::Operation(left, right, result)) { |
67 | throw OutOfRangeException("Overflow in multiplication of %s (%d * %d)!" , TypeIdToString(GetTypeId<TA>()), |
68 | left, right); |
69 | } |
70 | return result; |
71 | } |
72 | }; |
73 | |
74 | struct TryDecimalMultiply { |
75 | template <class TA, class TB, class TR> |
76 | static inline bool Operation(TA left, TB right, TR &result) { |
77 | throw InternalException("Unimplemented type for TryDecimalMultiply" ); |
78 | } |
79 | }; |
80 | |
81 | template <> |
82 | bool TryDecimalMultiply::Operation(int16_t left, int16_t right, int16_t &result); |
83 | template <> |
84 | bool TryDecimalMultiply::Operation(int32_t left, int32_t right, int32_t &result); |
85 | template <> |
86 | bool TryDecimalMultiply::Operation(int64_t left, int64_t right, int64_t &result); |
87 | template <> |
88 | bool TryDecimalMultiply::Operation(hugeint_t left, hugeint_t right, hugeint_t &result); |
89 | |
90 | struct DecimalMultiplyOverflowCheck { |
91 | template <class TA, class TB, class TR> |
92 | static inline TR Operation(TA left, TB right) { |
93 | TR result; |
94 | if (!TryDecimalMultiply::Operation<TA, TB, TR>(left, right, result)) { |
95 | throw OutOfRangeException("Overflow in multiplication of DECIMAL(18) (%d * %d). You might want to add an " |
96 | "explicit cast to a bigger decimal." , |
97 | left, right); |
98 | } |
99 | return result; |
100 | } |
101 | }; |
102 | |
103 | template <> |
104 | hugeint_t DecimalMultiplyOverflowCheck::Operation(hugeint_t left, hugeint_t right); |
105 | |
106 | } // namespace duckdb |
107 | |