Serenity Operating System
1/*
2 * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
3 * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 */
7
8#include <AK/NumericLimits.h>
9#include <LibIPC/Decoder.h>
10#include <LibIPC/Encoder.h>
11#include <LibSQL/AST/AST.h>
12#include <LibSQL/Serializer.h>
13#include <LibSQL/TupleDescriptor.h>
14#include <LibSQL/Value.h>
15#include <string.h>
16
17namespace SQL {
18
19// We use the upper 4 bits of the encoded type to store extra information about the type. This
20// includes if the value is null, and the encoded size of any integer type. Of course, this encoding
21// only works if the SQL type itself fits in the lower 4 bits.
22enum class SQLTypeWithCount {
23#undef __ENUMERATE_SQL_TYPE
24#define __ENUMERATE_SQL_TYPE(name, type) type,
25 ENUMERATE_SQL_TYPES(__ENUMERATE_SQL_TYPE)
26#undef __ENUMERATE_SQL_TYPE
27 Count,
28};
29
30static_assert(to_underlying(SQLTypeWithCount::Count) <= 0x0f, "Too many SQL types for current encoding");
31
32// Adding to this list is fine, but changing the order of any value here will result in LibSQL
33// becoming unable to read existing .db files. If the order must absolutely be changed, be sure
34// to bump Heap::current_version.
35enum class TypeData : u8 {
36 Null = 1 << 4,
37 Int8 = 2 << 4,
38 Int16 = 3 << 4,
39 Int32 = 4 << 4,
40 Int64 = 5 << 4,
41 Uint8 = 6 << 4,
42 Uint16 = 7 << 4,
43 Uint32 = 8 << 4,
44 Uint64 = 9 << 4,
45};
46
47template<typename Callback>
48static decltype(auto) downsize_integer(Integer auto value, Callback&& callback)
49{
50 if constexpr (IsSigned<decltype(value)>) {
51 if (AK::is_within_range<i8>(value))
52 return callback(static_cast<i8>(value), TypeData::Int8);
53 if (AK::is_within_range<i16>(value))
54 return callback(static_cast<i16>(value), TypeData::Int16);
55 if (AK::is_within_range<i32>(value))
56 return callback(static_cast<i32>(value), TypeData::Int32);
57 return callback(value, TypeData::Int64);
58 } else {
59 if (AK::is_within_range<u8>(value))
60 return callback(static_cast<i8>(value), TypeData::Uint8);
61 if (AK::is_within_range<u16>(value))
62 return callback(static_cast<i16>(value), TypeData::Uint16);
63 if (AK::is_within_range<u32>(value))
64 return callback(static_cast<i32>(value), TypeData::Uint32);
65 return callback(value, TypeData::Uint64);
66 }
67}
68
69template<typename Callback>
70static decltype(auto) downsize_integer(Value const& value, Callback&& callback)
71{
72 VERIFY(value.is_int());
73
74 if (value.value().has<i64>())
75 return downsize_integer(value.value().get<i64>(), forward<Callback>(callback));
76 return downsize_integer(value.value().get<u64>(), forward<Callback>(callback));
77}
78
79template<typename Callback>
80static ResultOr<Value> perform_integer_operation(Value const& lhs, Value const& rhs, Callback&& callback)
81{
82 VERIFY(lhs.is_int());
83 VERIFY(rhs.is_int());
84
85 if (lhs.value().has<i64>()) {
86 if (auto rhs_value = rhs.to_int<i64>(); rhs_value.has_value())
87 return callback(lhs.to_int<i64>().value(), rhs_value.value());
88 } else {
89 if (auto rhs_value = rhs.to_int<u64>(); rhs_value.has_value())
90 return callback(lhs.to_int<u64>().value(), rhs_value.value());
91 }
92
93 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
94}
95
96Value::Value(SQLType type)
97 : m_type(type)
98{
99}
100
101Value::Value(DeprecatedString value)
102 : m_type(SQLType::Text)
103 , m_value(move(value))
104{
105}
106
107Value::Value(double value)
108{
109 if (trunc(value) == value) {
110 if (AK::is_within_range<i64>(value)) {
111 m_type = SQLType::Integer;
112 m_value = static_cast<i64>(value);
113 return;
114 }
115 if (AK::is_within_range<u64>(value)) {
116 m_type = SQLType::Integer;
117 m_value = static_cast<u64>(value);
118 return;
119 }
120 }
121
122 m_type = SQLType::Float;
123 m_value = value;
124}
125
126Value::Value(NonnullRefPtr<TupleDescriptor> descriptor, Vector<Value> values)
127 : m_type(SQLType::Tuple)
128 , m_value(TupleValue { move(descriptor), move(values) })
129{
130}
131
132Value::Value(Value const& other)
133 : m_type(other.m_type)
134 , m_value(other.m_value)
135{
136}
137
138Value::Value(Value&& other)
139 : m_type(other.m_type)
140 , m_value(move(other.m_value))
141{
142}
143
144Value::~Value() = default;
145
146ResultOr<Value> Value::create_tuple(NonnullRefPtr<TupleDescriptor> descriptor)
147{
148 Vector<Value> values;
149 TRY(values.try_resize(descriptor->size()));
150
151 for (size_t i = 0; i < descriptor->size(); ++i)
152 values[i].m_type = descriptor->at(i).type;
153
154 return Value { move(descriptor), move(values) };
155}
156
157ResultOr<Value> Value::create_tuple(Vector<Value> values)
158{
159 auto descriptor = TRY(infer_tuple_descriptor(values));
160 return Value { move(descriptor), move(values) };
161}
162
163SQLType Value::type() const
164{
165 return m_type;
166}
167
168StringView Value::type_name() const
169{
170 switch (type()) {
171#undef __ENUMERATE_SQL_TYPE
172#define __ENUMERATE_SQL_TYPE(name, type) \
173 case SQLType::type: \
174 return name##sv;
175 ENUMERATE_SQL_TYPES(__ENUMERATE_SQL_TYPE)
176#undef __ENUMERATE_SQL_TYPE
177 default:
178 VERIFY_NOT_REACHED();
179 }
180}
181
182bool Value::is_type_compatible_with(SQLType other_type) const
183{
184 switch (type()) {
185 case SQLType::Null:
186 return false;
187 case SQLType::Integer:
188 case SQLType::Float:
189 return other_type == SQLType::Integer || other_type == SQLType::Float;
190 default:
191 break;
192 }
193
194 return type() == other_type;
195}
196
197bool Value::is_null() const
198{
199 return !m_value.has_value();
200}
201
202bool Value::is_int() const
203{
204 return m_value.has_value() && (m_value->has<i64>() || m_value->has<u64>());
205}
206
207DeprecatedString Value::to_deprecated_string() const
208{
209 if (is_null())
210 return "(null)"sv;
211
212 return m_value->visit(
213 [](DeprecatedString const& value) -> DeprecatedString { return value; },
214 [](Integer auto value) -> DeprecatedString { return DeprecatedString::number(value); },
215 [](double value) -> DeprecatedString { return DeprecatedString::number(value); },
216 [](bool value) -> DeprecatedString { return value ? "true"sv : "false"sv; },
217 [](TupleValue const& value) -> DeprecatedString {
218 StringBuilder builder;
219
220 builder.append('(');
221 builder.join(',', value.values);
222 builder.append(')');
223
224 return builder.to_deprecated_string();
225 });
226}
227
228Optional<double> Value::to_double() const
229{
230 if (is_null())
231 return {};
232
233 return m_value->visit(
234 [](DeprecatedString const& value) -> Optional<double> { return value.to_double(); },
235 [](Integer auto value) -> Optional<double> { return static_cast<double>(value); },
236 [](double value) -> Optional<double> { return value; },
237 [](bool value) -> Optional<double> { return static_cast<double>(value); },
238 [](TupleValue const&) -> Optional<double> { return {}; });
239}
240
241Optional<bool> Value::to_bool() const
242{
243 if (is_null())
244 return {};
245
246 return m_value->visit(
247 [](DeprecatedString const& value) -> Optional<bool> {
248 if (value.equals_ignoring_ascii_case("true"sv) || value.equals_ignoring_ascii_case("t"sv))
249 return true;
250 if (value.equals_ignoring_ascii_case("false"sv) || value.equals_ignoring_ascii_case("f"sv))
251 return false;
252 return {};
253 },
254 [](Integer auto value) -> Optional<bool> { return static_cast<bool>(value); },
255 [](double value) -> Optional<bool> { return fabs(value) > NumericLimits<double>::epsilon(); },
256 [](bool value) -> Optional<bool> { return value; },
257 [](TupleValue const& value) -> Optional<bool> {
258 for (auto const& element : value.values) {
259 auto as_bool = element.to_bool();
260 if (!as_bool.has_value())
261 return {};
262 if (!as_bool.value())
263 return false;
264 }
265
266 return true;
267 });
268}
269
270Optional<Vector<Value>> Value::to_vector() const
271{
272 if (is_null() || (type() != SQLType::Tuple))
273 return {};
274
275 auto const& tuple = m_value->get<TupleValue>();
276 return tuple.values;
277}
278
279Value& Value::operator=(Value value)
280{
281 m_type = value.m_type;
282 m_value = move(value.m_value);
283 return *this;
284}
285
286Value& Value::operator=(DeprecatedString value)
287{
288 m_type = SQLType::Text;
289 m_value = move(value);
290 return *this;
291}
292
293Value& Value::operator=(double value)
294{
295 m_type = SQLType::Float;
296 m_value = value;
297 return *this;
298}
299
300ResultOr<void> Value::assign_tuple(NonnullRefPtr<TupleDescriptor> descriptor)
301{
302 Vector<Value> values;
303 TRY(values.try_resize(descriptor->size()));
304
305 for (size_t i = 0; i < descriptor->size(); ++i)
306 values[i].m_type = descriptor->at(i).type;
307
308 m_type = SQLType::Tuple;
309 m_value = TupleValue { move(descriptor), move(values) };
310
311 return {};
312}
313
314ResultOr<void> Value::assign_tuple(Vector<Value> values)
315{
316 if (is_null() || (type() != SQLType::Tuple)) {
317 auto descriptor = TRY(infer_tuple_descriptor(values));
318
319 m_type = SQLType::Tuple;
320 m_value = TupleValue { move(descriptor), move(values) };
321
322 return {};
323 }
324
325 auto& tuple = m_value->get<TupleValue>();
326
327 if (values.size() > tuple.descriptor->size())
328 return Result { SQLCommand::Unknown, SQLErrorCode::InvalidNumberOfValues };
329
330 for (size_t i = 0; i < values.size(); ++i) {
331 if (values[i].type() != tuple.descriptor->at(i).type)
332 return Result { SQLCommand::Unknown, SQLErrorCode::InvalidType, SQLType_name(values[i].type()) };
333 }
334
335 if (values.size() < tuple.descriptor->size()) {
336 size_t original_size = values.size();
337 MUST(values.try_resize(tuple.descriptor->size()));
338
339 for (size_t i = original_size; i < values.size(); ++i)
340 values[i].m_type = tuple.descriptor->at(i).type;
341 }
342
343 m_value = TupleValue { move(tuple.descriptor), move(values) };
344 return {};
345}
346
347size_t Value::length() const
348{
349 if (is_null())
350 return 0;
351
352 // FIXME: This seems to be more of an encoded byte size rather than a length.
353 return m_value->visit(
354 [](DeprecatedString const& value) -> size_t { return sizeof(u32) + value.length(); },
355 [](Integer auto value) -> size_t {
356 return downsize_integer(value, [](auto integer, auto) {
357 return sizeof(integer);
358 });
359 },
360 [](double value) -> size_t { return sizeof(value); },
361 [](bool value) -> size_t { return sizeof(value); },
362 [](TupleValue const& value) -> size_t {
363 auto size = value.descriptor->length() + sizeof(u32);
364
365 for (auto const& element : value.values)
366 size += element.length();
367
368 return size;
369 });
370}
371
372u32 Value::hash() const
373{
374 if (is_null())
375 return 0;
376
377 return m_value->visit(
378 [](DeprecatedString const& value) -> u32 { return value.hash(); },
379 [](Integer auto value) -> u32 {
380 return downsize_integer(value, [](auto integer, auto) {
381 if constexpr (sizeof(decltype(integer)) == 8)
382 return u64_hash(integer);
383 else
384 return int_hash(integer);
385 });
386 },
387 [](double) -> u32 { VERIFY_NOT_REACHED(); },
388 [](bool value) -> u32 { return int_hash(value); },
389 [](TupleValue const& value) -> u32 {
390 u32 hash = 0;
391
392 for (auto const& element : value.values) {
393 if (hash == 0)
394 hash = element.hash();
395 else
396 hash = pair_int_hash(hash, element.hash());
397 }
398
399 return hash;
400 });
401}
402
403int Value::compare(Value const& other) const
404{
405 if (is_null())
406 return -1;
407 if (other.is_null())
408 return 1;
409
410 return m_value->visit(
411 [&](DeprecatedString const& value) -> int { return value.view().compare(other.to_deprecated_string()); },
412 [&](Integer auto value) -> int {
413 auto casted = other.to_int<IntegerType<decltype(value)>>();
414 if (!casted.has_value())
415 return 1;
416
417 if (value == *casted)
418 return 0;
419 return value < *casted ? -1 : 1;
420 },
421 [&](double value) -> int {
422 auto casted = other.to_double();
423 if (!casted.has_value())
424 return 1;
425
426 auto diff = value - *casted;
427 if (fabs(diff) < NumericLimits<double>::epsilon())
428 return 0;
429 return diff < 0 ? -1 : 1;
430 },
431 [&](bool value) -> int {
432 auto casted = other.to_bool();
433 if (!casted.has_value())
434 return 1;
435 return value ^ *casted;
436 },
437 [&](TupleValue const& value) -> int {
438 if (other.is_null() || (other.type() != SQLType::Tuple)) {
439 if (value.values.size() == 1)
440 return value.values[0].compare(other);
441 return 1;
442 }
443
444 auto const& other_value = other.m_value->get<TupleValue>();
445 if (auto result = value.descriptor->compare_ignoring_names(*other_value.descriptor); result != 0)
446 return 1;
447
448 if (value.values.size() != other_value.values.size())
449 return value.values.size() < other_value.values.size() ? -1 : 1;
450
451 for (size_t i = 0; i < value.values.size(); ++i) {
452 auto result = value.values[i].compare(other_value.values[i]);
453 if (result == 0)
454 continue;
455
456 if (value.descriptor->at(i).order == Order::Descending)
457 result = -result;
458 return result;
459 }
460
461 return 0;
462 });
463}
464
465bool Value::operator==(Value const& value) const
466{
467 return compare(value) == 0;
468}
469
470bool Value::operator==(StringView value) const
471{
472 return to_deprecated_string() == value;
473}
474
475bool Value::operator==(double value) const
476{
477 return to_double() == value;
478}
479
480bool Value::operator!=(Value const& value) const
481{
482 return compare(value) != 0;
483}
484
485bool Value::operator<(Value const& value) const
486{
487 return compare(value) < 0;
488}
489
490bool Value::operator<=(Value const& value) const
491{
492 return compare(value) <= 0;
493}
494
495bool Value::operator>(Value const& value) const
496{
497 return compare(value) > 0;
498}
499
500bool Value::operator>=(Value const& value) const
501{
502 return compare(value) >= 0;
503}
504
505template<typename Operator>
506static Result invalid_type_for_numeric_operator(Operator op)
507{
508 if constexpr (IsSame<Operator, AST::BinaryOperator>)
509 return { SQLCommand::Unknown, SQLErrorCode::NumericOperatorTypeMismatch, BinaryOperator_name(op) };
510 else if constexpr (IsSame<Operator, AST::UnaryOperator>)
511 return { SQLCommand::Unknown, SQLErrorCode::NumericOperatorTypeMismatch, UnaryOperator_name(op) };
512 else
513 static_assert(DependentFalse<Operator>);
514}
515
516ResultOr<Value> Value::add(Value const& other) const
517{
518 if (is_int() && other.is_int()) {
519 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
520 Checked result { lhs };
521 result.add(rhs);
522
523 if (result.has_overflow())
524 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
525 return Value { result.value_unchecked() };
526 });
527 }
528
529 auto lhs = to_double();
530 auto rhs = other.to_double();
531
532 if (!lhs.has_value() || !rhs.has_value())
533 return invalid_type_for_numeric_operator(AST::BinaryOperator::Plus);
534 return Value { lhs.value() + rhs.value() };
535}
536
537ResultOr<Value> Value::subtract(Value const& other) const
538{
539 if (is_int() && other.is_int()) {
540 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
541 Checked result { lhs };
542 result.sub(rhs);
543
544 if (result.has_overflow())
545 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
546 return Value { result.value_unchecked() };
547 });
548 }
549
550 auto lhs = to_double();
551 auto rhs = other.to_double();
552
553 if (!lhs.has_value() || !rhs.has_value())
554 return invalid_type_for_numeric_operator(AST::BinaryOperator::Minus);
555 return Value { lhs.value() - rhs.value() };
556}
557
558ResultOr<Value> Value::multiply(Value const& other) const
559{
560 if (is_int() && other.is_int()) {
561 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
562 Checked result { lhs };
563 result.mul(rhs);
564
565 if (result.has_overflow())
566 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
567 return Value { result.value_unchecked() };
568 });
569 }
570
571 auto lhs = to_double();
572 auto rhs = other.to_double();
573
574 if (!lhs.has_value() || !rhs.has_value())
575 return invalid_type_for_numeric_operator(AST::BinaryOperator::Multiplication);
576 return Value { lhs.value() * rhs.value() };
577}
578
579ResultOr<Value> Value::divide(Value const& other) const
580{
581 auto lhs = to_double();
582 auto rhs = other.to_double();
583
584 if (!lhs.has_value() || !rhs.has_value())
585 return invalid_type_for_numeric_operator(AST::BinaryOperator::Division);
586 if (rhs == 0.0)
587 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
588
589 return Value { lhs.value() / rhs.value() };
590}
591
592ResultOr<Value> Value::modulo(Value const& other) const
593{
594 if (!is_int() || !other.is_int())
595 return invalid_type_for_numeric_operator(AST::BinaryOperator::Modulo);
596
597 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
598 Checked result { lhs };
599 result.mod(rhs);
600
601 if (result.has_overflow())
602 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
603 return Value { result.value_unchecked() };
604 });
605}
606
607ResultOr<Value> Value::negate() const
608{
609 if (type() == SQLType::Integer) {
610 auto value = to_int<i64>();
611 if (!value.has_value())
612 return invalid_type_for_numeric_operator(AST::UnaryOperator::Minus);
613
614 return Value { value.value() * -1 };
615 }
616
617 if (type() == SQLType::Float)
618 return Value { -to_double().value() };
619
620 return invalid_type_for_numeric_operator(AST::UnaryOperator::Minus);
621}
622
623ResultOr<Value> Value::shift_left(Value const& other) const
624{
625 if (!is_int() || !other.is_int())
626 return invalid_type_for_numeric_operator(AST::BinaryOperator::ShiftLeft);
627
628 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
629 using LHS = decltype(lhs);
630 using RHS = decltype(rhs);
631
632 static constexpr auto max_shift = static_cast<RHS>(sizeof(LHS) * 8);
633 if (rhs < 0 || rhs >= max_shift)
634 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
635
636 return Value { lhs << rhs };
637 });
638}
639
640ResultOr<Value> Value::shift_right(Value const& other) const
641{
642 if (!is_int() || !other.is_int())
643 return invalid_type_for_numeric_operator(AST::BinaryOperator::ShiftRight);
644
645 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) -> ResultOr<Value> {
646 using LHS = decltype(lhs);
647 using RHS = decltype(rhs);
648
649 static constexpr auto max_shift = static_cast<RHS>(sizeof(LHS) * 8);
650 if (rhs < 0 || rhs >= max_shift)
651 return Result { SQLCommand::Unknown, SQLErrorCode::IntegerOverflow };
652
653 return Value { lhs >> rhs };
654 });
655}
656
657ResultOr<Value> Value::bitwise_or(Value const& other) const
658{
659 if (!is_int() || !other.is_int())
660 return invalid_type_for_numeric_operator(AST::BinaryOperator::BitwiseOr);
661
662 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) {
663 return Value { lhs | rhs };
664 });
665}
666
667ResultOr<Value> Value::bitwise_and(Value const& other) const
668{
669 if (!is_int() || !other.is_int())
670 return invalid_type_for_numeric_operator(AST::BinaryOperator::BitwiseAnd);
671
672 return perform_integer_operation(*this, other, [](auto lhs, auto rhs) {
673 return Value { lhs & rhs };
674 });
675}
676
677ResultOr<Value> Value::bitwise_not() const
678{
679 if (!is_int())
680 return invalid_type_for_numeric_operator(AST::UnaryOperator::BitwiseNot);
681
682 return downsize_integer(*this, [](auto value, auto) {
683 return Value { ~value };
684 });
685}
686
687static u8 encode_type_flags(Value const& value)
688{
689 auto type_flags = to_underlying(value.type());
690
691 if (value.is_null()) {
692 type_flags |= to_underlying(TypeData::Null);
693 } else if (value.is_int()) {
694 downsize_integer(value, [&](auto, auto type_data) {
695 type_flags |= to_underlying(type_data);
696 });
697 }
698
699 return type_flags;
700}
701
702void Value::serialize(Serializer& serializer) const
703{
704 auto type_flags = encode_type_flags(*this);
705 serializer.serialize<u8>(type_flags);
706
707 if (is_null())
708 return;
709
710 if (is_int()) {
711 downsize_integer(*this, [&](auto integer, auto) {
712 serializer.serialize(integer);
713 });
714 return;
715 }
716
717 m_value->visit(
718 [&](TupleValue const& value) {
719 serializer.serialize<TupleDescriptor>(*value.descriptor);
720 serializer.serialize(static_cast<u32>(value.values.size()));
721
722 for (auto const& element : value.values)
723 serializer.serialize<Value>(element);
724 },
725 [&](auto const& value) { serializer.serialize(value); });
726}
727
728void Value::deserialize(Serializer& serializer)
729{
730 auto type_flags = serializer.deserialize<u8>();
731
732 auto type_data = static_cast<TypeData>(type_flags & 0xf0);
733 m_type = static_cast<SQLType>(type_flags & 0x0f);
734
735 if (type_data == TypeData::Null)
736 return;
737
738 switch (m_type) {
739 case SQLType::Null:
740 VERIFY_NOT_REACHED();
741 break;
742 case SQLType::Text:
743 m_value = serializer.deserialize<DeprecatedString>();
744 break;
745 case SQLType::Integer:
746 switch (type_data) {
747 case TypeData::Int8:
748 m_value = static_cast<i64>(serializer.deserialize<i8>(0));
749 break;
750 case TypeData::Int16:
751 m_value = static_cast<i64>(serializer.deserialize<i16>(0));
752 break;
753 case TypeData::Int32:
754 m_value = static_cast<i64>(serializer.deserialize<i32>(0));
755 break;
756 case TypeData::Int64:
757 m_value = static_cast<i64>(serializer.deserialize<i64>(0));
758 break;
759 case TypeData::Uint8:
760 m_value = static_cast<u64>(serializer.deserialize<u8>(0));
761 break;
762 case TypeData::Uint16:
763 m_value = static_cast<u64>(serializer.deserialize<u16>(0));
764 break;
765 case TypeData::Uint32:
766 m_value = static_cast<u64>(serializer.deserialize<u32>(0));
767 break;
768 case TypeData::Uint64:
769 m_value = static_cast<u64>(serializer.deserialize<u64>(0));
770 break;
771 default:
772 VERIFY_NOT_REACHED();
773 break;
774 }
775 break;
776 case SQLType::Float:
777 m_value = serializer.deserialize<double>(0.0);
778 break;
779 case SQLType::Boolean:
780 m_value = serializer.deserialize<bool>(false);
781 break;
782 case SQLType::Tuple: {
783 auto descriptor = serializer.adopt_and_deserialize<TupleDescriptor>();
784 auto size = serializer.deserialize<u32>();
785
786 Vector<Value> values;
787 values.ensure_capacity(size);
788
789 for (size_t i = 0; i < size; ++i)
790 values.unchecked_append(serializer.deserialize<Value>());
791
792 m_value = TupleValue { move(descriptor), move(values) };
793 break;
794 }
795 }
796}
797
798TupleElementDescriptor Value::descriptor() const
799{
800 return { "", "", "", type(), Order::Ascending };
801}
802
803ResultOr<NonnullRefPtr<TupleDescriptor>> Value::infer_tuple_descriptor(Vector<Value> const& values)
804{
805 auto descriptor = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SQL::TupleDescriptor));
806 TRY(descriptor->try_ensure_capacity(values.size()));
807
808 for (auto const& element : values)
809 descriptor->unchecked_append({ ""sv, ""sv, ""sv, element.type(), Order::Ascending });
810
811 return descriptor;
812}
813
814}
815
816template<>
817ErrorOr<void> IPC::encode(Encoder& encoder, SQL::Value const& value)
818{
819 auto type_flags = encode_type_flags(value);
820 TRY(encoder.encode(type_flags));
821
822 if (value.is_null())
823 return {};
824
825 switch (value.type()) {
826 case SQL::SQLType::Null:
827 return {};
828 case SQL::SQLType::Text:
829 return encoder.encode(value.to_deprecated_string());
830 case SQL::SQLType::Integer:
831 return SQL::downsize_integer(value, [&](auto integer, auto) {
832 return encoder.encode(integer);
833 });
834 case SQL::SQLType::Float:
835 return encoder.encode(value.to_double().value());
836 case SQL::SQLType::Boolean:
837 return encoder.encode(value.to_bool().value());
838 case SQL::SQLType::Tuple:
839 return encoder.encode(value.to_vector().value());
840 }
841
842 VERIFY_NOT_REACHED();
843}
844
845template<>
846ErrorOr<SQL::Value> IPC::decode(Decoder& decoder)
847{
848 auto type_flags = TRY(decoder.decode<u8>());
849
850 auto type_data = static_cast<SQL::TypeData>(type_flags & 0xf0);
851 auto type = static_cast<SQL::SQLType>(type_flags & 0x0f);
852
853 if (type_data == SQL::TypeData::Null)
854 return SQL::Value { type };
855
856 switch (type) {
857 case SQL::SQLType::Null:
858 return SQL::Value {};
859 case SQL::SQLType::Text:
860 return SQL::Value { TRY(decoder.decode<DeprecatedString>()) };
861 case SQL::SQLType::Integer:
862 switch (type_data) {
863 case SQL::TypeData::Int8:
864 return SQL::Value { TRY(decoder.decode<i8>()) };
865 case SQL::TypeData::Int16:
866 return SQL::Value { TRY(decoder.decode<i16>()) };
867 case SQL::TypeData::Int32:
868 return SQL::Value { TRY(decoder.decode<i32>()) };
869 case SQL::TypeData::Int64:
870 return SQL::Value { TRY(decoder.decode<i64>()) };
871 case SQL::TypeData::Uint8:
872 return SQL::Value { TRY(decoder.decode<u8>()) };
873 case SQL::TypeData::Uint16:
874 return SQL::Value { TRY(decoder.decode<u16>()) };
875 case SQL::TypeData::Uint32:
876 return SQL::Value { TRY(decoder.decode<u32>()) };
877 case SQL::TypeData::Uint64:
878 return SQL::Value { TRY(decoder.decode<u64>()) };
879 default:
880 break;
881 }
882 break;
883 case SQL::SQLType::Float:
884 return SQL::Value { TRY(decoder.decode<double>()) };
885 case SQL::SQLType::Boolean:
886 return SQL::Value { TRY(decoder.decode<bool>()) };
887 case SQL::SQLType::Tuple: {
888 auto tuple = TRY(decoder.decode<Vector<SQL::Value>>());
889 auto value = SQL::Value::create_tuple(move(tuple));
890
891 if (value.is_error())
892 return Error::from_errno(to_underlying(value.error().error()));
893
894 return value.release_value();
895 }
896 }
897
898 VERIFY_NOT_REACHED();
899}