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