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