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
15namespace duckdb {
16
17struct interval_t;
18
19struct 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
26template <>
27float MultiplyOperator::Operation(float left, float right);
28template <>
29double MultiplyOperator::Operation(double left, double right);
30template <>
31interval_t MultiplyOperator::Operation(interval_t left, int64_t right);
32template <>
33interval_t MultiplyOperator::Operation(int64_t left, interval_t right);
34
35struct 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
42template <>
43bool TryMultiplyOperator::Operation(uint8_t left, uint8_t right, uint8_t &result);
44template <>
45bool TryMultiplyOperator::Operation(uint16_t left, uint16_t right, uint16_t &result);
46template <>
47bool TryMultiplyOperator::Operation(uint32_t left, uint32_t right, uint32_t &result);
48template <>
49bool TryMultiplyOperator::Operation(uint64_t left, uint64_t right, uint64_t &result);
50
51template <>
52bool TryMultiplyOperator::Operation(int8_t left, int8_t right, int8_t &result);
53template <>
54bool TryMultiplyOperator::Operation(int16_t left, int16_t right, int16_t &result);
55template <>
56bool TryMultiplyOperator::Operation(int32_t left, int32_t right, int32_t &result);
57template <>
58DUCKDB_API bool TryMultiplyOperator::Operation(int64_t left, int64_t right, int64_t &result);
59template <>
60DUCKDB_API bool TryMultiplyOperator::Operation(hugeint_t left, hugeint_t right, hugeint_t &result);
61
62struct 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
74struct 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
81template <>
82bool TryDecimalMultiply::Operation(int16_t left, int16_t right, int16_t &result);
83template <>
84bool TryDecimalMultiply::Operation(int32_t left, int32_t right, int32_t &result);
85template <>
86bool TryDecimalMultiply::Operation(int64_t left, int64_t right, int64_t &result);
87template <>
88bool TryDecimalMultiply::Operation(hugeint_t left, hugeint_t right, hugeint_t &result);
89
90struct 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
103template <>
104hugeint_t DecimalMultiplyOverflowCheck::Operation(hugeint_t left, hugeint_t right);
105
106} // namespace duckdb
107