1//===----------------------------------------------------------------------===//
2// DuckDB
3//
4// duckdb/common/types.hpp
5//
6//
7//===----------------------------------------------------------------------===//
8
9#pragma once
10
11#include "duckdb/common/assert.hpp"
12#include "duckdb/common/constants.hpp"
13
14#include <type_traits>
15
16namespace duckdb {
17
18class Serializer;
19class Deserializer;
20
21struct blob_t {
22 data_ptr_t data;
23 idx_t size;
24};
25
26struct string_t;
27
28template <class T> using child_list_t = std::vector<std::pair<std::string, T>>;
29template <class T> using buffer_ptr = std::shared_ptr<T>;
30
31template <class T, typename... Args> buffer_ptr<T> make_buffer(Args &&... args) {
32 return std::make_shared<T>(std::forward<Args>(args)...);
33}
34
35struct list_entry_t {
36 list_entry_t() = default;
37 list_entry_t(uint64_t offset, uint64_t length) : offset(offset), length(length) {
38 }
39
40 uint64_t offset;
41 uint64_t length;
42};
43
44//===--------------------------------------------------------------------===//
45// Internal Types
46//===--------------------------------------------------------------------===//
47
48// taken from arrow's type.h
49enum class TypeId : uint8_t {
50 /// A NULL type having no physical storage
51 NA = 0,
52
53 /// Boolean as 1 bit, LSB bit-packed ordering
54 BOOL = 1,
55
56 /// Unsigned 8-bit little-endian integer
57 UINT8 = 2,
58
59 /// Signed 8-bit little-endian integer
60 INT8 = 3,
61
62 /// Unsigned 16-bit little-endian integer
63 UINT16 = 4,
64
65 /// Signed 16-bit little-endian integer
66 INT16 = 5,
67
68 /// Unsigned 32-bit little-endian integer
69 UINT32 = 6,
70
71 /// Signed 32-bit little-endian integer
72 INT32 = 7,
73
74 /// Unsigned 64-bit little-endian integer
75 UINT64 = 8,
76
77 /// Signed 64-bit little-endian integer
78 INT64 = 9,
79
80 /// 2-byte floating point value
81 HALF_FLOAT = 10,
82
83 /// 4-byte floating point value
84 FLOAT = 11,
85
86 /// 8-byte floating point value
87 DOUBLE = 12,
88
89 /// UTF8 variable-length string as List<Char>
90 STRING = 13,
91
92 /// Variable-length bytes (no guarantee of UTF8-ness)
93 BINARY = 14,
94
95 /// Fixed-size binary. Each value occupies the same number of bytes
96 FIXED_SIZE_BINARY = 15,
97
98 /// int32_t days since the UNIX epoch
99 DATE32 = 16,
100
101 /// int64_t milliseconds since the UNIX epoch
102 DATE64 = 17,
103
104 /// Exact timestamp encoded with int64 since UNIX epoch
105 /// Default unit millisecond
106 TIMESTAMP = 18,
107
108 /// Time as signed 32-bit integer, representing either seconds or
109 /// milliseconds since midnight
110 TIME32 = 19,
111
112 /// Time as signed 64-bit integer, representing either microseconds or
113 /// nanoseconds since midnight
114 TIME64 = 20,
115
116 /// YEAR_MONTH or DAY_TIME interval in SQL style
117 INTERVAL = 21,
118
119 /// Precision- and scale-based decimal type. Storage type depends on the
120 /// parameters.
121 DECIMAL = 22,
122
123 /// A list of some logical data type
124 LIST = 23,
125
126 /// Struct of logical types
127 STRUCT = 24,
128
129 /// Unions of logical types
130 UNION = 25,
131
132 /// Dictionary-encoded type, also called "categorical" or "factor"
133 /// in other programming languages. Holds the dictionary value
134 /// type but not the dictionary itself, which is part of the
135 /// ArrayData struct
136 DICTIONARY = 26,
137
138 /// Map, a repeated struct logical type
139 MAP = 27,
140
141 /// Custom data type, implemented by user
142 EXTENSION = 28,
143
144 /// Fixed size list of some logical type
145 FIXED_SIZE_LIST = 29,
146
147 /// Measure of elapsed time in either seconds, milliseconds, microseconds
148 /// or nanoseconds.
149 DURATION = 30,
150
151 /// Like STRING, but with 64-bit offsets
152 LARGE_STRING = 31,
153
154 /// Like BINARY, but with 64-bit offsets
155 LARGE_BINARY = 32,
156
157 /// Like LIST, but with 64-bit offsets
158 LARGE_LIST = 33,
159
160 // DuckDB Extensions
161 VARCHAR = 200, // our own string representation, different from STRING and LARGE_STRING above
162 VARBINARY = 201,
163 POINTER = 202,
164 HASH = 203,
165
166 INVALID = 255
167};
168
169//===--------------------------------------------------------------------===//
170// SQL Types
171//===--------------------------------------------------------------------===//
172enum class SQLTypeId : uint8_t {
173 INVALID = 0,
174 SQLNULL = 1, /* NULL type, used for constant NULL */
175 UNKNOWN = 2, /* unknown type, used for parameter expressions */
176 ANY = 3, /* ANY type, used for functions that accept any type as parameter */
177
178 BOOLEAN = 10,
179 TINYINT = 11,
180 SMALLINT = 12,
181 INTEGER = 13,
182 BIGINT = 14,
183 DATE = 15,
184 TIME = 16,
185 TIMESTAMP = 17,
186 FLOAT = 18,
187 DOUBLE = 19,
188 DECIMAL = 20,
189 CHAR = 21,
190 VARCHAR = 22,
191 VARBINARY = 23,
192 BLOB = 24,
193
194 STRUCT = 100,
195 LIST = 101
196};
197
198struct SQLType {
199 SQLTypeId id;
200 uint16_t width;
201 uint8_t scale;
202 string collation;
203
204 // TODO serialize this
205 child_list_t<SQLType> child_type;
206
207 SQLType(SQLTypeId id = SQLTypeId::INVALID, uint16_t width = 0, uint8_t scale = 0, string collation = string())
208 : id(id), width(width), scale(scale), collation(move(collation)) {
209 }
210
211 bool operator==(const SQLType &rhs) const {
212 return id == rhs.id && width == rhs.width && scale == rhs.scale;
213 }
214 bool operator!=(const SQLType &rhs) const {
215 return !(*this == rhs);
216 }
217
218 //! Serializes a SQLType to a stand-alone binary blob
219 void Serialize(Serializer &serializer);
220 //! Deserializes a blob back into an SQLType
221 static SQLType Deserialize(Deserializer &source);
222
223 bool IsIntegral() const;
224 bool IsNumeric() const;
225 bool IsMoreGenericThan(SQLType &other) const;
226
227public:
228 static const SQLType SQLNULL;
229 static const SQLType BOOLEAN;
230 static const SQLType TINYINT;
231 static const SQLType SMALLINT;
232 static const SQLType INTEGER;
233 static const SQLType BIGINT;
234 static const SQLType FLOAT;
235 static const SQLType DOUBLE;
236 static const SQLType DATE;
237 static const SQLType TIMESTAMP;
238 static const SQLType TIME;
239 static const SQLType VARCHAR;
240 static const SQLType VARBINARY;
241 static const SQLType STRUCT;
242 static const SQLType LIST;
243 static const SQLType ANY;
244 static const SQLType BLOB;
245
246 //! A list of all NUMERIC types (integral and floating point types)
247 static const vector<SQLType> NUMERIC;
248 //! A list of all INTEGRAL types
249 static const vector<SQLType> INTEGRAL;
250 //! A list of ALL SQL types
251 static const vector<SQLType> ALL_TYPES;
252};
253
254string SQLTypeIdToString(SQLTypeId type);
255string SQLTypeToString(SQLType type);
256
257SQLType MaxSQLType(SQLType left, SQLType right);
258SQLType TransformStringToSQLType(string str);
259
260//! Gets the internal type associated with the given SQL type
261TypeId GetInternalType(SQLType type);
262//! Returns the "simplest" SQL type corresponding to the given type id (e.g. TypeId::INT32 -> SQLTypeId::INTEGER)
263SQLType SQLTypeFromInternalType(TypeId type);
264
265//! Returns the TypeId for the given type
266template <class T> TypeId GetTypeId() {
267 if (std::is_same<T, bool>()) {
268 return TypeId::BOOL;
269 } else if (std::is_same<T, int8_t>()) {
270 return TypeId::INT8;
271 } else if (std::is_same<T, int16_t>()) {
272 return TypeId::INT16;
273 } else if (std::is_same<T, int32_t>()) {
274 return TypeId::INT32;
275 } else if (std::is_same<T, int64_t>()) {
276 return TypeId::INT64;
277 } else if (std::is_same<T, uint64_t>()) {
278 return TypeId::HASH;
279 } else if (std::is_same<T, uintptr_t>()) {
280 return TypeId::POINTER;
281 } else if (std::is_same<T, float>()) {
282 return TypeId::FLOAT;
283 } else if (std::is_same<T, double>()) {
284 return TypeId::DOUBLE;
285 } else if (std::is_same<T, const char *>() || std::is_same<T, char *>()) {
286 return TypeId::VARCHAR;
287 } else {
288 return TypeId::INVALID;
289 }
290}
291
292template <class T> bool IsValidType() {
293 return GetTypeId<T>() != TypeId::INVALID;
294}
295
296//! The TypeId used by the row identifiers column
297extern const TypeId ROW_TYPE;
298
299string TypeIdToString(TypeId type);
300idx_t GetTypeIdSize(TypeId type);
301bool TypeIsConstantSize(TypeId type);
302bool TypeIsIntegral(TypeId type);
303bool TypeIsNumeric(TypeId type);
304bool TypeIsInteger(TypeId type);
305
306template <class T> bool IsIntegerType() {
307 return TypeIsIntegral(GetTypeId<T>());
308}
309
310bool ApproxEqual(float l, float r);
311bool ApproxEqual(double l, double r);
312
313}; // namespace duckdb
314