mutable
A Database System for Research and Fast Prototyping
Loading...
Searching...
No Matches
Type.cpp
Go to the documentation of this file.
2
3
4using namespace m;
5
6
7
8constexpr const char * Numeric::KIND_TO_STR_[];
9
10/*======================================================================================================================
11 * SQL Types
12 *====================================================================================================================*/
13
14constexpr const char *Type::CATEGORY_TO_STR_[];
15
16uint64_t std::hash<m::Type>::operator()(const m::Type &type) const { return type.hash(); }
17
19
21void Type::dump() const { dump(std::cerr); }
23
24const Numeric * m::arithmetic_join(const Numeric *lhs, const Numeric *rhs)
25{
27 static constexpr double LOG_2_OF_10 = 3.321928094887362;
28
29 /* Combining a vector with a scalar yields a vector. */
30 Type::category_t category = std::max(lhs->category, rhs->category);
31
32 /* N_Decimal is always "more precise" than N_Float. N_Float is always more precise than N_Int. */
33 Numeric::kind_t kind = std::max(lhs->kind, rhs->kind);
34
35 /* Compute the precision in bits. */
36 unsigned precision_lhs, precision_rhs;
37 switch (lhs->kind) {
38 case Numeric::N_Int: precision_lhs = 8 * lhs->precision; break;
39 case Numeric::N_Float: precision_lhs = lhs->precision; break;
40 case Numeric::N_Decimal: precision_lhs = std::ceil(LOG_2_OF_10 * lhs->precision); break;
41 }
42 switch (rhs->kind) {
43 case Numeric::N_Int: precision_rhs = 8 * rhs->precision; break;
44 case Numeric::N_Float: precision_rhs = rhs->precision; break;
45 case Numeric::N_Decimal: precision_rhs = std::ceil(LOG_2_OF_10 * rhs->precision); break;
46 }
47 int precision = std::max(precision_lhs, precision_rhs);
48 int scale = std::max(lhs->scale, rhs->scale);
49
50 switch (kind) {
51 case Numeric::N_Int: return Type::Get_Integer(category, precision / 8);
52 case Numeric::N_Float: {
53 if (precision == 32) return Type::Get_Float(category);
54 M_insist(precision == 64, "Illegal floating-point precision");
55 return Type::Get_Double(category);
56 }
57
58 case Numeric::N_Decimal: return Type::Get_Decimal(category, precision / LOG_2_OF_10, scale);
59 }
60}
61
62/*===== Factory Methods ==============================================================================================*/
63
65
67
68Type::Pooled<Boolean> Type::Get_Boolean(category_t category) { return types_(Boolean{category}); }
69
70Type::Pooled<Bitmap> Type::Get_Bitmap(category_t category, std::size_t length)
71{
72 return types_(Bitmap{category, length});
73}
74
75Type::Pooled<CharacterSequence> Type::Get_Char(category_t category, std::size_t length)
76{
77 return types_(CharacterSequence{category, length, false});
78}
79
80Type::Pooled<CharacterSequence> Type::Get_Varchar(category_t category, std::size_t length)
81{
82 return types_(CharacterSequence{category, length, true});
83}
84
85Type::Pooled<Date> Type::Get_Date(category_t category) { return types_(Date{category}); }
86
87Type::Pooled<DateTime> Type::Get_Datetime(category_t category) { return types_(DateTime{category}); }
88
89Type::Pooled<Numeric> Type::Get_Decimal(category_t category, unsigned digits, unsigned scale)
90{
91 return types_(Numeric{category, Numeric::N_Decimal, digits, scale});
92}
93
94Type::Pooled<Numeric> Type::Get_Integer(category_t category, unsigned num_bytes)
95{
96 return types_(Numeric{category, Numeric::N_Int, num_bytes, 0});
97}
98
100{
101 return types_(Numeric{category, Numeric::N_Float, 32, 0});
102}
103
105{
106 return types_(Numeric{category, Numeric::N_Float, 64, 0});
107}
108
109Type::Pooled<FnType> Type::Get_Function(const Type *return_type, std::vector<const Type*> parameter_types)
110{
111 return types_(FnType{return_type, parameter_types});
112}
113
114/*===== Type visitor =================================================================================================*/
115
116#define ACCEPT(TYPE) \
117 void TYPE::accept(TypeVisitor &v) { v(*this); } \
118 void TYPE::accept(ConstTypeVisitor &v) const { v(*this); }
120#undef ACCEPT
121
122/*===== Comparison ===================================================================================================*/
123
124bool ErrorType::operator==(const Type &other) const { return is<const ErrorType>(&other); }
125
126bool NoneType::operator==(const Type &other) const { return is<const NoneType>(&other); }
127
128bool Boolean::operator==(const Type &other) const
129{
130 if (auto o = cast<const Boolean>(&other))
131 return this->category == o->category;
132 return false;
133}
134
135bool Bitmap::operator==(const Type &other) const
136{
137 if (auto o = cast<const Bitmap>(&other))
138 return this->category == o->category and this->length == o->length;
139 return false;
140}
141
142bool CharacterSequence::operator==(const Type &other) const
143{
144 if (auto o = cast<const CharacterSequence>(&other))
145 return this->category == o->category and this->is_varying == o->is_varying and this->length == o->length;
146 return false;
147}
148
149bool Date::operator==(const Type &other) const
150{
151 if (auto o = cast<const Date>(&other))
152 return this->category == o->category;
153 return false;
154}
155
156bool DateTime::operator==(const Type &other) const
157{
158 if (auto o = cast<const DateTime>(&other))
159 return this->category == o->category;
160 return false;
161}
162
163bool Numeric::operator==(const Type &other) const
164{
165 if (auto o = cast<const Numeric>(&other)) {
166 return this->category == o->category and
167 this->kind == o->kind and
168 this->precision == o->precision and
169 this->scale == o->scale;
170 }
171 return false;
172}
173
174bool FnType::operator==(const Type &other) const
175{
176 if (auto o = cast<const FnType>(&other)) {
177 if (this->return_type != o->return_type) return false; // return types must match
178 if (this->parameter_types.size() != o->parameter_types.size()) return false; // parameter count must match
179 for (std::size_t i = 0, end = parameter_types.size(); i != end; ++i)
180 if (this->parameter_types[i] != o->parameter_types[i]) return false; // parameters must have same type
181 return true;
182 }
183 return false;
184}
185
186/*===== Hash =========================================================================================================*/
187
188uint64_t ErrorType::hash() const { return 0; }
189
190uint64_t NoneType::hash() const { return -1UL; }
191
192uint64_t Boolean::hash() const { return 0b10UL | uint64_t(category); }
193
194uint64_t Bitmap::hash() const
195{
196 return uint64_t(length) << 1 | uint64_t(category);
197}
198
199uint64_t CharacterSequence::hash() const
200{
201 return uint64_t(length) << 2 | uint64_t(is_varying) << 1 | uint64_t(category);
202}
203
204uint64_t Date::hash() const { return 0b100UL | uint64_t(category); }
205
206uint64_t DateTime::hash() const { return 0b1000UL | uint64_t(category); }
207
208uint64_t Numeric::hash() const
209{
210 return ((uint64_t(precision) << 32) ^ (uint64_t(scale) << 3) ^ (uint64_t(kind) << 1)) | uint64_t(category);
211}
212
213uint64_t FnType::hash() const
214{
215 auto h = return_type->hash();
216 for (auto p : parameter_types)
217 h = (h << 7) ^ p->hash();
218 return h;
219}
220
221/*===== Scalar & Vector Conversion ===================================================================================*/
222
223const PrimitiveType * Boolean::as_scalar() const { return Type::Get_Boolean(TY_Scalar); }
224
225const PrimitiveType * Boolean::as_vectorial() const { return Type::Get_Boolean(TY_Vector); }
226
227const PrimitiveType * Bitmap::as_scalar() const
228{
229 if (is_scalar()) return this;
230 return as<const Bitmap>(&*types_(Bitmap(TY_Scalar, length)));
231}
233{
234 if (is_vectorial()) return this;
235 return as<const Bitmap>(&*types_(Bitmap(TY_Vector, length)));
236}
237
239{
240 if (is_scalar()) return this;
241 return as<const CharacterSequence>(&*types_(CharacterSequence(TY_Scalar, length, is_varying)));
242}
244{
245 if (is_vectorial()) return this;
246 return as<const CharacterSequence>(&*types_(CharacterSequence(TY_Vector, length, is_varying)));
247}
248
249const PrimitiveType * Date::as_scalar() const { return Type::Get_Date(TY_Scalar); }
250
251const PrimitiveType * Date::as_vectorial() const { return Type::Get_Date(TY_Vector); }
252
253const PrimitiveType * DateTime::as_scalar() const { return Type::Get_Datetime(TY_Scalar); }
254
255const PrimitiveType * DateTime::as_vectorial() const { return Type::Get_Datetime(TY_Vector); }
256
257const PrimitiveType * Numeric::as_scalar() const
258{
259 return as<const Numeric>(&*types_(Numeric(TY_Scalar, kind, precision, scale)));
260}
262{
263 return as<const Numeric>(&*types_(Numeric(TY_Vector, kind, precision, scale)));
264}
265
266/*===== Pretty Printing ==============================================================================================*/
267
269void ErrorType::print(std::ostream &out) const { out << "[ErrorType]"; }
270
271void NoneType::print(std::ostream &out) const { out << "[none]"; }
272
273void Boolean::print(std::ostream &out) const { out << "BOOL"; }
274
275void Bitmap::print(std::ostream &out) const { out << "BITMAP" << '(' << length << ')'; }
276
277void CharacterSequence::print(std::ostream &out) const
278{
279 out << ( is_varying ? "VARCHAR" : "CHAR" ) << '(' << length << ')';
280}
281
282void Date::print(std::ostream &out) const { out << "DATE"; }
283
284void DateTime::print(std::ostream &out) const { out << "DATETIME"; }
285
286void Numeric::print(std::ostream &out) const
287{
288 switch (kind) {
289 case N_Int:
290 out << "INT(" << precision << ')';
291 break;
292
293 case N_Float:
294 if (precision == 32) out << "FLOAT";
295 else if (precision == 64) out << "DOUBLE";
296 else out << "[IllegalFloatingPoint]";
297 break;
298
299 case N_Decimal: {
300 out << "DECIMAL(" << precision << ", " << scale << ')';
301 break;
302 }
303 }
304}
305
306void FnType::print(std::ostream &out) const
307{
308 out << '(';
309 for (auto it = parameter_types.cbegin(), end = parameter_types.cend(); it != end; ++it) {
310 if (it != parameter_types.cbegin()) out << ", ";
311 out << **it;
312 }
313 out << ") -> " << *return_type;
314}
316
317/*===== Dump =========================================================================================================*/
318
320void ErrorType::dump(std::ostream &out) const { out << "[ErrorType]" << std::endl; }
321
322void NoneType::dump(std::ostream &out) const { out << "[NoneType]" << std::endl; }
323
324void Boolean::dump(std::ostream &out) const
325{
326 out << "Boolean{ category = " << CATEGORY_TO_STR_[category] << " }" << std::endl;
327}
328
329void Bitmap::dump(std::ostream &out) const
330{
331 out << "Bitmap{ category = " << CATEGORY_TO_STR_[category] << ", length = " << length << " }" << std::endl;
332}
333
334void CharacterSequence::dump(std::ostream &out) const
335{
336 out << "CharacterSequence{ category = " << CATEGORY_TO_STR_[category] << ", is_varying = "
337 << (is_varying ? "true" : "false") << ", length = " << length << " }" << std::endl;
338}
339
340void Date::dump(std::ostream &out) const
341{
342 out << "Date{ category = " << CATEGORY_TO_STR_[category] << " }" << std::endl;
343}
344
345void DateTime::dump(std::ostream &out) const
346{
347 out << "DateTime{ category = " << CATEGORY_TO_STR_[category] << " }" << std::endl;
348}
349
350void Numeric::dump(std::ostream &out) const
351{
352 out << "Numeric{ category = " << CATEGORY_TO_STR_[category] << ", kind = " << Numeric::KIND_TO_STR_[kind]
353 << ", precision = " << precision << ", scale = " << scale << " }" << std::endl;
354}
355
356void FnType::dump(std::ostream &out) const
357{
358 out << "FnType{\n return_type: ";
359 return_type->dump(out);
360 out << " parameter_types: {\n";
361 for (auto p :parameter_types) {
362 out << " ";
363 p->dump(out);
364 }
365 out << '}' << std::endl;
366}
#define ACCEPT(CLASS)
#define M_TYPE_LIST(X)
Definition: Type.hpp:486
#define M_insist(...)
Definition: macro.hpp:129
‍mutable namespace
Definition: Backend.hpp:10
const Numeric * arithmetic_join(const Numeric *lhs, const Numeric *rhs)
Definition: Type.cpp:24
and
Definition: enum_ops.hpp:12
The bitmap type.
Definition: Type.hpp:259
uint64_t length
the number of elements
Definition: Type.hpp:262
void dump() const
Definition: Type.cpp:21
bool operator==(const Type &other) const override
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
uint64_t hash() const override
Compute the 64 bit hash of this Type.
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
The boolean type.
Definition: Type.hpp:230
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
void dump() const
Definition: Type.cpp:21
uint64_t hash() const override
Compute the 64 bit hash of this Type.
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
bool operator==(const Type &other) const override
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
The type of character strings, both fixed length and varying length.
Definition: Type.hpp:290
bool operator==(const Type &other) const override
std::size_t length
the maximum length of the string in bytes
Definition: Type.hpp:293
void dump() const
Definition: Type.cpp:21
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
bool is_varying
true if varying, false otherwise; corresponds to Char(N) and Varchar(N)
Definition: Type.hpp:294
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
uint64_t hash() const override
Compute the 64 bit hash of this Type.
The date type.
Definition: Type.hpp:364
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
bool operator==(const Type &other) const override
void dump() const
Definition: Type.cpp:21
uint64_t hash() const override
Compute the 64 bit hash of this Type.
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
The date type.
Definition: Type.hpp:335
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
void dump() const
Definition: Type.cpp:21
uint64_t hash() const override
Compute the 64 bit hash of this Type.
bool operator==(const Type &other) const override
This Type is assigned when parsing of a data type fails or when semantic analysis detects a type erro...
Definition: Type.hpp:181
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
void dump() const
Definition: Type.cpp:21
uint64_t hash() const override
Compute the 64 bit hash of this Type.
bool operator==(const Type &other) const override
The function type defines the type and count of the arguments and the type of the return value of a S...
Definition: Type.hpp:456
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
uint64_t hash() const override
Compute the 64 bit hash of this Type.
std::vector< const Type * > parameter_types
‍the type of the return value
Definition: Type.hpp:460
void dump() const
Definition: Type.cpp:21
const Type * return_type
Definition: Type.hpp:459
bool operator==(const Type &other) const override
A Type that represents the absence of any other type.
Definition: Type.hpp:204
void dump() const
Definition: Type.cpp:21
bool operator==(const Type &other) const override
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
uint64_t hash() const override
Compute the 64 bit hash of this Type.
The numeric type represents integer and floating-point types of different precision and scale.
Definition: Type.hpp:393
unsigned precision
The precision gives the maximum number of digits that can be represented by that type.
Definition: Type.hpp:414
void dump() const
Definition: Type.cpp:21
void print(std::ostream &out) const override
Print a textual representation of this Type to out.
bool operator==(const Type &other) const override
unsigned scale
the number of decimal digits right of the decimal point
Definition: Type.hpp:415
static constexpr const char * KIND_TO_STR_[]
Definition: Type.hpp:405
virtual const PrimitiveType * as_scalar() const override
Convert this PrimitiveType to its scalar equivalent.
uint64_t hash() const override
Compute the 64 bit hash of this Type.
virtual const PrimitiveType * as_vectorial() const override
Convert this PrimitiveType to its vectorial equivalent.
A pool implements an implicitly garbage-collected set of instances of a class hierarchy.
Definition: Pool.hpp:81
A data type representing a pooled (or internalized) object.
Definition: Pool.hpp:168
PrimitiveTypes represent Types of values.
Definition: Type.hpp:159
bool is_scalar() const
Returns true iff this PrimitiveType is scalar, i.e. if it is for a single value.
Definition: Type.hpp:168
category_t category
whether this type is scalar or vector
Definition: Type.hpp:160
bool is_vectorial() const
Returns true iff this PrimitiveType is vectorial, i.e. if it is for a sequence of values.
Definition: Type.hpp:170
This class represents types in the SQL type system.
Definition: Type.hpp:46
static Pooled< CharacterSequence > Get_Char(category_t category, std::size_t length)
Returns a CharacterSequence type of the given category and fixed length.
Definition: Type.cpp:75
static Pooled< NoneType > Get_None()
Returns a NoneType.
Definition: Type.cpp:66
static Pooled< Bitmap > Get_Bitmap(category_t category, std::size_t length)
Returns a Bitmap type of the given category and length.
Definition: Type.cpp:70
static Pooled< Numeric > Get_Double(category_t category)
Returns a Numeric type of given category for 64 bit floating-points.
Definition: Type.cpp:104
static M_LCOV_EXCL_STOP Pooled< ErrorType > Get_Error()
Returns a ErrorType.
Definition: Type.cpp:64
static constexpr const char * CATEGORY_TO_STR_[]
‍declaration for constexpr static field, see C++17 inline variables
Definition: Type.hpp:50
void dump() const
Definition: Type.cpp:21
static Pooled< Numeric > Get_Decimal(category_t category, unsigned digits, unsigned scale)
Returns a Numeric type for decimals of given category, decimal digits, and scale.
Definition: Type.cpp:89
static Pooled< Date > Get_Date(category_t category)
Returns a Date type of the given category.
Definition: Type.cpp:85
static Pooled< Boolean > Get_Boolean(category_t category)
Returns a Boolean type of the given category.
Definition: Type.cpp:68
static Pooled< DateTime > Get_Datetime(category_t category)
Returns a DateTime type of the given category.
Definition: Type.cpp:87
virtual uint64_t hash() const =0
Compute the 64 bit hash of this Type.
static Pooled< Numeric > Get_Float(category_t category)
Returns a Numeric type of given category for 32 bit floating-points.
Definition: Type.cpp:99
virtual void dump(std::ostream &out) const =0
static Pool< Type > types_
a pool of internalized, parameterized types
Definition: Type.hpp:54
static Pooled< Numeric > Get_Integer(category_t category, unsigned num_bytes)
Returns a Numeric type for integrals of given category and num_bytes bytes.
Definition: Type.cpp:94
static Pooled< CharacterSequence > Get_Varchar(category_t category, std::size_t length)
Returns a CharacterSequence type of the given category and varying length.
Definition: Type.cpp:80
static Pooled< FnType > Get_Function(const Type *return_type, std::vector< const Type * > parameter_types)
Returns a FnType for a function with parameter types parameter_types and return type return_type.
Definition: Type.cpp:109