20 [
this, &out](
const Boolean&) { out << (
as_b() ?
"TRUE" :
"FALSE"); },
21 [
this, &out](
const CharacterSequence &cs) { out <<
'"'; out.write(as<const char*>(), cs.length); out <<
'"'; },
22 [
this, &out](
const Date&) {
23 const int32_t date =
as_i();
24 const auto oldfill = out.fill(
'0');
25 const auto oldfmt = out.flags();
27 << std::setw(date >> 9 > 0 ? 4 : 5) << (date >> 9) <<
'-'
28 << std::setw(2) << ((date >> 5) & 0xF) <<
'-'
29 << std::setw(2) << (date & 0x1F);
34 const time_t time =
as_i();
39 [
this, &out](
const Numeric &n) {
45 case Numeric::N_Decimal: {
46 const int64_t div =
powi(10L, n.scale);
47 const int64_t pre =
as_i() / div;
48 const int64_t post =
as_i() % div;
50 auto old_fill = out.fill(
'0');
51 out << std::setw(n.scale) << post;
56 case Numeric::N_Float:
68void Value::dump(std::ostream &out)
const { out << *
this << std::endl; }
78#ifdef M_ENABLE_SANITY_FIELDS
82 std::size_t additional_bytes = 0;
84 if (
auto cs = cast<const CharacterSequence>(e.type))
85 additional_bytes += cs->length + 1;
87 values_ = (
Value*) malloc(S.num_entries() *
sizeof(
Value) + additional_bytes);
88 uint8_t *p =
reinterpret_cast<uint8_t*
>(values_) + S.num_entries() *
sizeof(
Value);
89 for (std::size_t i = 0; i != S.num_entries(); ++i) {
90 if (
auto cs = cast<const CharacterSequence>(S[i].type)) {
91 new (&values_[i])
Value(p);
95 new (&values_[i])
Value();
102#ifdef M_ENABLE_SANITY_FIELDS
103 : num_values_(types.size())
106 std::size_t additional_bytes = 0;
107 for (
auto &ty : types) {
108 if (
auto cs = cast<const CharacterSequence>(ty))
109 additional_bytes += cs->length + 1;
111 values_ = (
Value*) malloc(types.size() *
sizeof(
Value) + additional_bytes);
112 uint8_t *p =
reinterpret_cast<uint8_t*
>(values_) + types.size() *
sizeof(
Value);
113 for (std::size_t i = 0; i != types.size(); ++i) {
114 if (
auto cs = cast<const CharacterSequence>(types[i])) {
115 new (&values_[i])
Value(p);
118 new (&values_[i])
Value();
127 for (std::size_t i = 0; i != S.
num_entries(); ++i) {
128 if (S[i].type->is_character_sequence()) {
129 strcpy(
reinterpret_cast<char*
>(cpy[i].as_p()),
reinterpret_cast<char*
>((*
this)[i].as_p()));
132 cpy.
set(i, (*
this)[i]);
141 for (std::size_t i = 0; i != schema.
num_entries(); ++i) {
142 if (i != 0) out <<
',';
150void Tuple::dump(std::ostream &out)
const { out << *
this << std::endl; }
#define M_unreachable(MSG)
T M_EXPORT powi(const T base, const U exp)
Power function for integral types.
auto visit(Callable &&callable, Base &obj, m::tag< Callable > &&=m::tag< Callable >())
Generic implementation to visit a class hierarchy, with similar syntax as std::visit.
The type of character strings, both fixed length and varying length.
The numeric type represents integer and floating-point types of different precision and scale.
A Schema represents a sequence of identifiers, optionally with a prefix, and their associated types.
std::size_t num_entries() const
Returns the number of entries in this Schema.
Value * values_
the Values in this Tuple
void print(std::ostream &out, const Schema &schema) const
Print this Tuple using the given schema.
Tuple clone(const Schema &S) const
Create a clone of this Tuple interpreted using the Schema S.
bool is_null(std::size_t idx) const
Returns true iff the Value at index idx is NULL.
void not_null(std::size_t idx)
Sets the Value at index idx to not-NULL.
void set(std::size_t idx, Value val)
Assigns the Value val to this Tuple at index idx and clears the respective NULL bit.
This class represents types in the SQL type system.
This class holds a SQL attribute value.
auto & as_f()
Returns a reference to the value interpreted as of type float.
M_LCOV_EXCL_STOP void print(std::ostream &out, const Type &ty) const
Interpret this Value as of Type ty and print a human-readable representation to out.
auto & as_b()
Returns a reference to the value interpreted as of type bool.
auto & as_d()
Returns a reference to the value interpreted as of type double.
auto & as_i()
Returns a reference to the value interpreted as of type int64_t.