Kùzu C++ API
Loading...
Searching...
No Matches
type_utils.h
Go to the documentation of this file.
1#pragma once
2
3#include <type_traits>
4
5#include "assert.h"
6#include "blob.h"
7#include "date_t.h"
8#include "int128_t.h"
9#include "interval_t.h"
10#include "ku_string.h"
11#include "timestamp_t.h"
12#include "types.h"
13#include "uuid.h"
14
15namespace kuzu {
16namespace common {
17
18class ValueVector;
19
20template<class... Funcs>
21struct overload : Funcs... {
22 explicit overload(Funcs... funcs) : Funcs(funcs)... {}
23 using Funcs::operator()...;
24};
25
26class TypeUtils {
27public:
28 static std::string entryToString(const LogicalType& dataType, const uint8_t* value,
29 ValueVector* vector);
30
31 template<typename T>
32 static inline std::string toString(const T& val, void* /*valueVector*/ = nullptr) {
33 static_assert(std::is_same<T, int64_t>::value || std::is_same<T, int32_t>::value ||
34 std::is_same<T, int16_t>::value || std::is_same<T, int8_t>::value ||
35 std::is_same<T, uint64_t>::value || std::is_same<T, uint32_t>::value ||
36 std::is_same<T, uint16_t>::value || std::is_same<T, uint8_t>::value ||
37 std::is_same<T, double>::value || std::is_same<T, float>::value);
38 return std::to_string(val);
39 }
40 static std::string nodeToString(const struct_entry_t& val, ValueVector* vector);
41 static std::string relToString(const struct_entry_t& val, ValueVector* vector);
42
43 static inline void encodeOverflowPtr(uint64_t& overflowPtr, page_idx_t pageIdx,
44 uint32_t pageOffset) {
45 memcpy(&overflowPtr, &pageIdx, 4);
46 memcpy(((uint8_t*)&overflowPtr) + 4, &pageOffset, 4);
47 }
48 static inline void decodeOverflowPtr(uint64_t overflowPtr, page_idx_t& pageIdx,
49 uint32_t& pageOffset) {
50 pageIdx = 0;
51 memcpy(&pageIdx, &overflowPtr, 4);
52 memcpy(&pageOffset, ((uint8_t*)&overflowPtr) + 4, 4);
53 }
54
55 template<typename T>
57 if constexpr (std::is_same_v<T, int64_t>) {
59 } else if constexpr (std::is_same_v<T, int32_t>) {
61 } else if constexpr (std::is_same_v<T, int16_t>) {
63 } else if constexpr (std::is_same_v<T, int8_t>) {
65 } else if constexpr (std::is_same_v<T, uint64_t>) {
67 } else if constexpr (std::is_same_v<T, uint32_t>) {
69 } else if constexpr (std::is_same_v<T, uint16_t>) {
71 } else if constexpr (std::is_same_v<T, uint8_t>) {
73 } else if constexpr (std::is_same_v<T, float>) {
75 } else if constexpr (std::is_same_v<T, double>) {
77 } else if constexpr (std::is_same_v<T, int128_t>) {
79 } else if constexpr (std::is_same_v<T, interval_t>) {
81 } else if constexpr (std::same_as<T, ku_string_t> || std::same_as<T, std::string> ||
82 std::same_as<T, std::string_view>) {
84 } else {
86 }
87 }
88
89 /*
90 * TypeUtils::visit can be used to call generic code on all or some Logical and Physical type
91 * variants with access to type information.
92 *
93 * E.g.
94 *
95 * std::string result;
96 * visit(dataType, [&]<typename T>(T) {
97 * if constexpr(std::is_same_v<T, ku_string_t>()) {
98 * result = vector->getValue<ku_string_t>(0).getAsString();
99 * } else if (std::integral<T>) {
100 * result = std::to_string(vector->getValue<T>(0));
101 * } else {
102 * KU_UNREACHABLE;
103 * }
104 * });
105 *
106 * or
107 * std::string result;
108 * visit(dataType,
109 * [&](ku_string_t) {
110 * result = vector->getValue<ku_string_t>(0);
111 * },
112 * [&]<std::integral T>(T) {
113 * result = std::to_string(vector->getValue<T>(0));
114 * },
115 * [](auto) { KU_UNREACHABLE; }
116 * );
117 *
118 * Note that when multiple functions are provided, at least one function must match all data
119 * types.
120 *
121 * Also note that implicit conversions may occur with the multi-function variant
122 * if you don't include a generic auto function to cover types which aren't explicitly included.
123 * See https://en.cppreference.com/w/cpp/utility/variant/visit
124 */
125 template<typename... Fs>
126 static inline auto visit(const LogicalType& dataType, Fs... funcs) {
127 // Note: arguments are used only for type deduction and have no meaningful value.
128 // They should be optimized out by the compiler
129 auto func = overload(funcs...);
130 switch (dataType.getLogicalTypeID()) {
131 /* NOLINTBEGIN(bugprone-branch-clone)*/
133 return func(int8_t());
135 return func(uint8_t());
137 return func(int16_t());
139 return func(uint16_t());
141 return func(int32_t());
143 return func(uint32_t());
146 return func(int64_t());
148 return func(uint64_t());
150 return func(bool());
152 return func(int128_t());
154 return func(double());
156 return func(float());
158 switch (dataType.getPhysicalType()) {
160 return func(int16_t());
162 return func(int32_t());
164 return func(int64_t());
166 return func(int128_t());
167 default:
169 }
171 return func(interval_t());
173 return func(internalID_t());
175 return func(ku_string_t());
177 return func(date_t());
179 return func(timestamp_ns_t());
181 return func(timestamp_ms_t());
183 return func(timestamp_sec_t());
185 return func(timestamp_tz_t());
187 return func(timestamp_t());
189 return func(blob_t());
191 return func(ku_uuid_t());
194 return func(list_entry_t());
196 return func(map_entry_t());
201 return func(struct_entry_t());
203 return func(union_entry_t());
204 /* NOLINTEND(bugprone-branch-clone)*/
208 // Unsupported type
210 // Needed for return type deduction to work
211 return func(uint8_t());
212 }
213 }
214
215 template<typename... Fs>
216 static inline auto visit(PhysicalTypeID dataType, Fs&&... funcs) {
217 // Note: arguments are used only for type deduction and have no meaningful value.
218 // They should be optimized out by the compiler
219 auto func = overload(funcs...);
220 switch (dataType) {
221 /* NOLINTBEGIN(bugprone-branch-clone)*/
223 return func(int8_t());
225 return func(uint8_t());
227 return func(int16_t());
229 return func(uint16_t());
231 return func(int32_t());
233 return func(uint32_t());
235 return func(int64_t());
237 return func(uint64_t());
239 return func(bool());
241 return func(int128_t());
243 return func(double());
245 return func(float());
247 return func(interval_t());
249 return func(internalID_t());
251 return func(ku_string_t());
254 return func(list_entry_t());
256 return func(struct_entry_t());
257 /* NOLINTEND(bugprone-branch-clone)*/
260 // Unsupported type
262 // Needed for return type deduction to work
263 return func(uint8_t());
264 default:
266 }
267 }
268};
269
270// Forward declaration of template specializations.
271template<>
272std::string TypeUtils::toString(const int128_t& val, void* valueVector);
273template<>
274std::string TypeUtils::toString(const bool& val, void* valueVector);
275template<>
276std::string TypeUtils::toString(const internalID_t& val, void* valueVector);
277template<>
278std::string TypeUtils::toString(const date_t& val, void* valueVector);
279template<>
280std::string TypeUtils::toString(const timestamp_ns_t& val, void* valueVector);
281template<>
282std::string TypeUtils::toString(const timestamp_ms_t& val, void* valueVector);
283template<>
284std::string TypeUtils::toString(const timestamp_sec_t& val, void* valueVector);
285template<>
286std::string TypeUtils::toString(const timestamp_tz_t& val, void* valueVector);
287template<>
288std::string TypeUtils::toString(const timestamp_t& val, void* valueVector);
289template<>
290std::string TypeUtils::toString(const interval_t& val, void* valueVector);
291template<>
292std::string TypeUtils::toString(const ku_string_t& val, void* valueVector);
293template<>
294std::string TypeUtils::toString(const blob_t& val, void* valueVector);
295template<>
296std::string TypeUtils::toString(const ku_uuid_t& val, void* valueVector);
297template<>
298std::string TypeUtils::toString(const list_entry_t& val, void* valueVector);
299template<>
300std::string TypeUtils::toString(const map_entry_t& val, void* valueVector);
301template<>
302std::string TypeUtils::toString(const struct_entry_t& val, void* valueVector);
303template<>
304std::string TypeUtils::toString(const union_entry_t& val, void* valueVector);
305
306} // namespace common
307} // namespace kuzu
#define KU_UNREACHABLE
Definition assert.h:28
Definition types.h:201
KUZU_API LogicalTypeID getLogicalTypeID() const
Definition types.h:224
KUZU_API PhysicalTypeID getPhysicalType() const
Definition types.h:227
Definition type_utils.h:26
static auto visit(const LogicalType &dataType, Fs... funcs)
Definition type_utils.h:126
static std::string entryToString(const LogicalType &dataType, const uint8_t *value, ValueVector *vector)
static void decodeOverflowPtr(uint64_t overflowPtr, page_idx_t &pageIdx, uint32_t &pageOffset)
Definition type_utils.h:48
static std::string relToString(const struct_entry_t &val, ValueVector *vector)
static auto visit(PhysicalTypeID dataType, Fs &&... funcs)
Definition type_utils.h:216
static constexpr common::PhysicalTypeID getPhysicalTypeIDForType()
Definition type_utils.h:56
static void encodeOverflowPtr(uint64_t &overflowPtr, page_idx_t pageIdx, uint32_t pageOffset)
Definition type_utils.h:43
static std::string nodeToString(const struct_entry_t &val, ValueVector *vector)
static std::string toString(const T &val, void *=nullptr)
Definition type_utils.h:32
Definition value_vector.h:20
PhysicalTypeID
Definition types.h:171
uint32_t page_idx_t
Definition types.h:26
struct KUZU_API int128_t
Definition int128_t.h:17
Definition alter_type.h:5
Definition blob.h:8
Definition date_t.h:11
Definition int128_t.h:20
Definition internal_id_t.h:31
Definition interval_t.h:30
Definition ku_string.h:12
Definition uuid.h:11
Definition types.h:70
Definition types.h:82
Definition type_utils.h:21
overload(Funcs... funcs)
Definition type_utils.h:22
Definition types.h:78
Definition timestamp_t.h:49
Definition timestamp_t.h:46
Definition timestamp_t.h:52
Definition timestamp_t.h:10
Definition timestamp_t.h:43
Definition types.h:86