1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/function/cast/default_casts.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/types.hpp"
12#include "duckdb/common/types/vector.hpp"
13#include "duckdb/common/helper.hpp"
14#include "duckdb/common/optional_ptr.hpp"
15#include "duckdb/function/scalar_function.hpp"
16
17namespace duckdb {
18
19class CastFunctionSet;
20struct FunctionLocalState;
21
22//! Extra data that can be attached to a bind function of a cast, and is available during binding
23struct BindCastInfo {
24 DUCKDB_API virtual ~BindCastInfo();
25
26 template <class TARGET>
27 TARGET &Cast() {
28 D_ASSERT(dynamic_cast<TARGET *>(this));
29 return reinterpret_cast<TARGET &>(*this);
30 }
31 template <class TARGET>
32 const TARGET &Cast() const {
33 D_ASSERT(dynamic_cast<const TARGET *>(this));
34 return reinterpret_cast<const TARGET &>(*this);
35 }
36};
37
38//! Extra data that can be returned by the bind of a cast, and is available during execution of a cast
39struct BoundCastData {
40 DUCKDB_API virtual ~BoundCastData();
41
42 DUCKDB_API virtual unique_ptr<BoundCastData> Copy() const = 0;
43
44 template <class TARGET>
45 TARGET &Cast() {
46 D_ASSERT(dynamic_cast<TARGET *>(this));
47 return reinterpret_cast<TARGET &>(*this);
48 }
49 template <class TARGET>
50 const TARGET &Cast() const {
51 D_ASSERT(dynamic_cast<const TARGET *>(this));
52 return reinterpret_cast<const TARGET &>(*this);
53 }
54};
55
56struct CastParameters {
57 CastParameters() {
58 }
59 CastParameters(BoundCastData *cast_data, bool strict, string *error_message,
60 optional_ptr<FunctionLocalState> local_state)
61 : cast_data(cast_data), strict(strict), error_message(error_message), local_state(local_state) {
62 }
63 CastParameters(CastParameters &parent, optional_ptr<BoundCastData> cast_data,
64 optional_ptr<FunctionLocalState> local_state)
65 : cast_data(cast_data), strict(parent.strict), error_message(parent.error_message), local_state(local_state) {
66 }
67
68 //! The bound cast data (if any)
69 optional_ptr<BoundCastData> cast_data;
70 //! whether or not to enable strict casting
71 bool strict = false;
72 // out: error message in case cast has failed
73 string *error_message = nullptr;
74 //! Local state
75 optional_ptr<FunctionLocalState> local_state;
76};
77
78struct CastLocalStateParameters {
79 CastLocalStateParameters(optional_ptr<ClientContext> context_p, optional_ptr<BoundCastData> cast_data_p)
80 : context(context_p), cast_data(cast_data_p) {
81 }
82 CastLocalStateParameters(ClientContext &context_p, optional_ptr<BoundCastData> cast_data_p)
83 : context(&context_p), cast_data(cast_data_p) {
84 }
85 CastLocalStateParameters(CastLocalStateParameters &parent, optional_ptr<BoundCastData> cast_data_p)
86 : context(parent.context), cast_data(cast_data_p) {
87 }
88
89 optional_ptr<ClientContext> context;
90 //! The bound cast data (if any)
91 optional_ptr<BoundCastData> cast_data;
92};
93
94typedef bool (*cast_function_t)(Vector &source, Vector &result, idx_t count, CastParameters &parameters);
95typedef unique_ptr<FunctionLocalState> (*init_cast_local_state_t)(CastLocalStateParameters &parameters);
96
97struct BoundCastInfo {
98 DUCKDB_API
99 BoundCastInfo(
100 cast_function_t function, unique_ptr<BoundCastData> cast_data = nullptr,
101 init_cast_local_state_t init_local_state = nullptr); // NOLINT: allow explicit cast from cast_function_t
102 cast_function_t function;
103 init_cast_local_state_t init_local_state;
104 unique_ptr<BoundCastData> cast_data;
105
106public:
107 BoundCastInfo Copy() const;
108};
109
110struct BindCastInput {
111 DUCKDB_API BindCastInput(CastFunctionSet &function_set, optional_ptr<BindCastInfo> info,
112 optional_ptr<ClientContext> context);
113
114 CastFunctionSet &function_set;
115 optional_ptr<BindCastInfo> info;
116 optional_ptr<ClientContext> context;
117
118public:
119 DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target);
120};
121
122struct DefaultCasts {
123 DUCKDB_API static BoundCastInfo GetDefaultCastFunction(BindCastInput &input, const LogicalType &source,
124 const LogicalType &target);
125
126 DUCKDB_API static bool NopCast(Vector &source, Vector &result, idx_t count, CastParameters &parameters);
127 DUCKDB_API static bool TryVectorNullCast(Vector &source, Vector &result, idx_t count, CastParameters &parameters);
128 DUCKDB_API static bool ReinterpretCast(Vector &source, Vector &result, idx_t count, CastParameters &parameters);
129
130private:
131 static BoundCastInfo BlobCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
132 static BoundCastInfo BitCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
133 static BoundCastInfo DateCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
134 static BoundCastInfo DecimalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
135 static BoundCastInfo EnumCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
136 static BoundCastInfo IntervalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
137 static BoundCastInfo ListCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
138 static BoundCastInfo NumericCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
139 static BoundCastInfo MapCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
140 static BoundCastInfo PointerCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
141 static BoundCastInfo StringCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
142 static BoundCastInfo StructCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
143 static BoundCastInfo TimeCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
144 static BoundCastInfo TimeTzCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
145 static BoundCastInfo TimestampCastSwitch(BindCastInput &input, const LogicalType &source,
146 const LogicalType &target);
147 static BoundCastInfo TimestampTzCastSwitch(BindCastInput &input, const LogicalType &source,
148 const LogicalType &target);
149 static BoundCastInfo TimestampNsCastSwitch(BindCastInput &input, const LogicalType &source,
150 const LogicalType &target);
151 static BoundCastInfo TimestampMsCastSwitch(BindCastInput &input, const LogicalType &source,
152 const LogicalType &target);
153 static BoundCastInfo TimestampSecCastSwitch(BindCastInput &input, const LogicalType &source,
154 const LogicalType &target);
155 static BoundCastInfo UnionCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
156 static BoundCastInfo UUIDCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target);
157
158 static BoundCastInfo ImplicitToUnionCast(BindCastInput &input, const LogicalType &source,
159 const LogicalType &target);
160};
161
162} // namespace duckdb
163