123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992 |
- /*
- * Copyright (c) 2021, Jan de Visser <jan@de-visser.net>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <LibSQL/Serialize.h>
- #include <LibSQL/Value.h>
- #include <math.h>
- #include <string.h>
- namespace SQL {
- Value::Value(SQLType sql_type)
- {
- setup(sql_type);
- }
- void Value::setup(SQLType type)
- {
- switch (type) {
- #undef __ENUMERATE_SQL_TYPE
- #define __ENUMERATE_SQL_TYPE(name, cardinal, type, impl, size) \
- case SQLType::type: \
- m_impl.set<type##Impl>(type##Impl()); \
- break;
- ENUMERATE_SQL_TYPES(__ENUMERATE_SQL_TYPE)
- #undef __ENUMERATE_SQL_TYPE
- default:
- VERIFY_NOT_REACHED();
- }
- }
- Value::Value(SQLType sql_type, Value const& value)
- : Value(sql_type)
- {
- assign(value);
- }
- Value::Value(SQLType sql_type, String const& string)
- : Value(sql_type)
- {
- assign(string);
- }
- Value::Value(SQLType sql_type, char const* string)
- : Value(sql_type)
- {
- assign(String(string));
- }
- Value::Value(SQLType sql_type, int integer)
- : Value(sql_type)
- {
- assign(integer);
- }
- Value::Value(SQLType sql_type, double dbl)
- : Value(sql_type)
- {
- assign(dbl);
- }
- Value::Value(SQLType sql_type, bool boolean)
- : Value(sql_type)
- {
- assign(boolean);
- }
- Value::Value(String const& string)
- : Value(SQLType::Text)
- {
- assign(string);
- }
- Value::Value(char const* string)
- : Value(SQLType::Text)
- {
- assign(String(string));
- }
- Value::Value(int integer)
- : Value(SQLType::Integer)
- {
- assign(integer);
- }
- Value::Value(double dbl)
- : Value(SQLType::Float)
- {
- assign(dbl);
- }
- Value::Value(bool boolean)
- : Value(SQLType::Boolean)
- {
- assign(boolean);
- }
- Value Value::create_tuple(NonnullRefPtr<TupleDescriptor> const& tuple_descriptor)
- {
- return Value(Value::SetImplementationSingleton, TupleImpl(tuple_descriptor));
- }
- Value Value::create_array(SQLType element_type, Optional<size_t> const& max_size)
- {
- return Value(Value::SetImplementationSingleton, ArrayImpl(element_type, max_size));
- }
- Value const& Value::null()
- {
- static Value s_null(SQLType::Null);
- return s_null;
- }
- bool Value::is_null() const
- {
- return m_impl.visit([&](auto& impl) { return impl.is_null(); });
- }
- SQLType Value::type() const
- {
- return m_impl.visit([&](auto& impl) { return impl.type(); });
- }
- String Value::type_name() const
- {
- return m_impl.visit([&](auto& impl) { return impl.type_name(); });
- }
- BaseTypeImpl Value::downcast_to_basetype() const
- {
- return m_impl.downcast<NullImpl, TextImpl, IntegerImpl, FloatImpl, BooleanImpl>();
- }
- String Value::to_string() const
- {
- if (is_null())
- return "(null)";
- return m_impl.visit([&](auto& impl) { return impl.to_string(); });
- }
- Optional<int> Value::to_int() const
- {
- if (is_null())
- return {};
- return m_impl.visit([&](auto& impl) { return impl.to_int(); });
- }
- Optional<u32> Value::to_u32() const
- {
- if (is_null())
- return {};
- auto ret = to_int();
- if (ret.has_value())
- return static_cast<u32>(ret.value());
- return {};
- }
- Optional<double> Value::to_double() const
- {
- if (is_null())
- return {};
- return m_impl.visit([&](auto& impl) { return impl.to_double(); });
- }
- Optional<bool> Value::to_bool() const
- {
- if (is_null())
- return {};
- return m_impl.visit([&](auto& impl) { return impl.to_bool(); });
- }
- Optional<Vector<Value>> Value::to_vector() const
- {
- if (is_null())
- return {};
- Vector<Value> vector;
- if (m_impl.visit([&](auto& impl) { return impl.to_vector(vector); }))
- return vector;
- else
- return {};
- }
- Value::operator String() const
- {
- return to_string();
- }
- Value::operator int() const
- {
- auto i = to_int();
- VERIFY(i.has_value());
- return i.value();
- }
- Value::operator u32() const
- {
- auto i = to_u32();
- VERIFY(i.has_value());
- return i.value();
- }
- Value::operator double() const
- {
- auto d = to_double();
- VERIFY(d.has_value());
- return d.value();
- }
- Value::operator bool() const
- {
- auto b = to_bool();
- VERIFY(b.has_value());
- return b.value();
- }
- void Value::assign(Value const& other_value)
- {
- m_impl.visit([&](auto& impl) { impl.assign(other_value); });
- }
- void Value::assign(String const& string_value)
- {
- m_impl.visit([&](auto& impl) { impl.assign_string(string_value); });
- }
- void Value::assign(int const& int_value)
- {
- m_impl.visit([&](auto& impl) { impl.assign_int(int_value); });
- }
- void Value::assign(double const& double_value)
- {
- m_impl.visit([&](auto& impl) { impl.assign_double(double_value); });
- }
- void Value::assign(bool const& bool_value)
- {
- m_impl.visit([&](auto& impl) { impl.assign_bool(bool_value); });
- }
- void Value::assign(Vector<Value> const& values)
- {
- m_impl.visit([&](auto& impl) { impl.assign_vector(values); });
- }
- Value& Value::operator=(Value const& other)
- {
- if (this != &other) {
- if (other.is_null()) {
- assign(null());
- } else {
- VERIFY(can_cast(other));
- assign(other);
- }
- }
- return (*this);
- }
- Value& Value::operator=(String const& value)
- {
- assign(value);
- return (*this);
- }
- Value& Value::operator=(char const* value)
- {
- assign(String(value));
- return (*this);
- }
- Value& Value::operator=(int value)
- {
- assign(value);
- return (*this);
- }
- Value& Value::operator=(u32 value)
- {
- assign(static_cast<int>(value));
- return (*this);
- }
- Value& Value::operator=(double value)
- {
- assign(value);
- return (*this);
- }
- Value& Value::operator=(bool value)
- {
- assign(value);
- return (*this);
- }
- Value& Value::operator=(Vector<Value> const& vector)
- {
- assign(vector);
- return (*this);
- }
- size_t Value::length() const
- {
- return m_impl.visit([&](auto& impl) { return impl.length(); });
- }
- u32 Value::hash() const
- {
- return (is_null()) ? 0u : m_impl.visit([&](auto& impl) { return impl.hash(); });
- }
- bool Value::can_cast(Value const& other_value) const
- {
- if (type() == other_value.type())
- return true;
- return m_impl.visit([&](auto& impl) { return impl.can_cast(other_value); });
- }
- int Value::compare(Value const& other) const
- {
- if (is_null())
- return -1;
- if (other.is_null())
- return 1;
- return m_impl.visit([&](auto& impl) { return impl.compare(other); });
- }
- bool Value::operator==(Value const& other) const
- {
- return compare(other) == 0;
- }
- bool Value::operator==(String const& string_value) const
- {
- return to_string() == string_value;
- }
- bool Value::operator==(int int_value) const
- {
- auto i = to_int();
- if (!i.has_value())
- return false;
- return i.value() == int_value;
- }
- bool Value::operator==(double double_value) const
- {
- auto d = to_double();
- if (!d.has_value())
- return false;
- return d.value() == double_value;
- }
- bool Value::operator!=(Value const& other) const
- {
- return compare(other) != 0;
- }
- bool Value::operator<(Value const& other) const
- {
- return compare(other) < 0;
- }
- bool Value::operator<=(Value const& other) const
- {
- return compare(other) <= 0;
- }
- bool Value::operator>(Value const& other) const
- {
- return compare(other) > 0;
- }
- bool Value::operator>=(Value const& other) const
- {
- return compare(other) >= 0;
- }
- void Value::serialize_to(ByteBuffer& buffer) const
- {
- u8 type_flags = (u8)type();
- if (is_null())
- type_flags |= (u8)SQLType::Null;
- SQL::serialize_to(buffer, type_flags);
- if (!is_null())
- m_impl.visit([&](auto& impl) { impl.serialize(buffer); });
- }
- void Value::deserialize(ByteBuffer& buffer, size_t& offset_at)
- {
- m_impl.visit([&](auto& impl) { impl.deserialize(buffer, offset_at); });
- }
- Value Value::deserialize_from(ByteBuffer& buffer, size_t& at_offset)
- {
- u8 type_flags;
- SQL::deserialize_from(buffer, at_offset, type_flags);
- bool is_null = false;
- if ((type_flags & (u8)SQLType::Null) && (type_flags != (u8)SQLType::Null)) {
- type_flags &= ~((u8)SQLType::Null);
- is_null = true;
- }
- auto type = (SQLType)type_flags;
- VERIFY(!is_null || (type != SQLType::Tuple && type != SQLType::Array));
- Value ret(type);
- if (!is_null) {
- ret.deserialize(buffer, at_offset);
- }
- return ret;
- }
- // -----------------------------------------------------------------
- bool NullImpl::can_cast(Value const& value)
- {
- return value.is_null();
- }
- int NullImpl::compare(Value const& other)
- {
- return other.type() == SQLType::Null;
- }
- // -----------------------------------------------------------------
- String TextImpl::to_string() const
- {
- return value();
- }
- Optional<int> TextImpl::to_int() const
- {
- if (!m_value.has_value())
- return {};
- return value().to_int();
- }
- Optional<double> TextImpl::to_double() const
- {
- if (!m_value.has_value())
- return {};
- char* end_ptr;
- double ret = strtod(value().characters(), &end_ptr);
- if (end_ptr == value().characters()) {
- return {};
- }
- return ret;
- }
- Optional<bool> TextImpl::to_bool() const
- {
- if (!m_value.has_value())
- return {};
- if (value().equals_ignoring_case("true") || value().equals_ignoring_case("t"))
- return true;
- if (value().equals_ignoring_case("false") || value().equals_ignoring_case("f"))
- return false;
- return {};
- }
- void TextImpl::assign(Value const& other_value)
- {
- if (other_value.type() == SQLType::Null) {
- m_value = {};
- } else {
- m_value = other_value.to_string();
- }
- }
- void TextImpl::assign_string(String const& string_value)
- {
- m_value = string_value;
- }
- void TextImpl::assign_int(int int_value)
- {
- m_value = String::number(int_value);
- }
- void TextImpl::assign_double(double double_value)
- {
- m_value = String::number(double_value);
- }
- void TextImpl::assign_bool(bool bool_value)
- {
- m_value = (bool_value) ? "true" : "false";
- }
- size_t TextImpl::length() const
- {
- return (is_null()) ? 0 : sizeof(u32) + min(value().length(), 64) + 1;
- }
- int TextImpl::compare(Value const& other) const
- {
- if (is_null())
- return -1;
- auto s1 = value();
- auto s2 = other.to_string();
- if (s1 == s2)
- return 0;
- return (s1 < s2) ? -1 : 1;
- }
- u32 TextImpl::hash() const
- {
- return value().hash();
- }
- String IntegerImpl::to_string() const
- {
- return String::formatted("{}", value());
- }
- Optional<int> IntegerImpl::to_int() const
- {
- return value();
- }
- Optional<double> IntegerImpl::to_double() const
- {
- return static_cast<double>(value());
- }
- Optional<bool> IntegerImpl::to_bool() const
- {
- return value() != 0;
- }
- void IntegerImpl::assign(Value const& other_value)
- {
- auto i = other_value.to_int();
- if (!i.has_value())
- m_value = {};
- else
- m_value = i.value();
- }
- void IntegerImpl::assign_string(String const& string_value)
- {
- auto i = string_value.to_int();
- if (!i.has_value())
- m_value = {};
- else
- m_value = i.value();
- }
- void IntegerImpl::assign_int(int int_value)
- {
- m_value = int_value;
- }
- void IntegerImpl::assign_double(double double_value)
- {
- m_value = static_cast<int>(round(double_value));
- }
- void IntegerImpl::assign_bool(bool bool_value)
- {
- m_value = (bool_value) ? 1 : 0;
- }
- bool IntegerImpl::can_cast(Value const& other_value)
- {
- return other_value.to_int().has_value();
- }
- int IntegerImpl::compare(Value const& other) const
- {
- auto casted = other.to_int();
- if (!casted.has_value()) {
- return 1;
- }
- return value() - casted.value();
- }
- u32 IntegerImpl::hash() const
- {
- return int_hash(value());
- }
- String FloatImpl::to_string() const
- {
- return String::formatted("{}", value());
- }
- Optional<int> FloatImpl::to_int() const
- {
- return static_cast<int>(round(value()));
- }
- Optional<double> FloatImpl::to_double() const
- {
- return value();
- }
- void FloatImpl::assign(Value const& other_value)
- {
- auto i = other_value.to_double();
- if (!i.has_value())
- m_value = {};
- else
- m_value = i.value();
- }
- void FloatImpl::assign_string(String const& string_value)
- {
- char* end_ptr;
- auto dbl = strtod(string_value.characters(), &end_ptr);
- if (end_ptr == string_value.characters())
- m_value = {};
- else
- m_value = dbl;
- }
- void FloatImpl::assign_int(int int_value)
- {
- m_value = int_value;
- }
- void FloatImpl::assign_double(double double_value)
- {
- m_value = double_value;
- }
- bool FloatImpl::can_cast(Value const& other_value)
- {
- return other_value.to_double().has_value();
- }
- int FloatImpl::compare(Value const& other) const
- {
- auto casted = other.to_double();
- if (!casted.has_value()) {
- return 1;
- }
- auto diff = value() - casted.value();
- return (diff < NumericLimits<double>::epsilon()) ? 0 : ((diff > 0) ? 1 : -1);
- }
- String BooleanImpl::to_string() const
- {
- return (value()) ? "true" : "false";
- }
- Optional<int> BooleanImpl::to_int() const
- {
- return (value()) ? 1 : 0;
- }
- Optional<double> BooleanImpl::to_double()
- {
- return {};
- }
- Optional<bool> BooleanImpl::to_bool() const
- {
- return value();
- }
- void BooleanImpl::assign(Value const& other_value)
- {
- auto b = other_value.to_bool();
- if (!b.has_value())
- m_value = {};
- else
- m_value = b.value();
- }
- void BooleanImpl::assign_string(String const& string_value)
- {
- return assign(Value(string_value));
- }
- void BooleanImpl::assign_int(int int_value)
- {
- m_value = (int_value != 0);
- }
- void BooleanImpl::assign_double(double)
- {
- m_value = {};
- }
- void BooleanImpl::assign_bool(bool bool_value)
- {
- m_value = bool_value;
- }
- bool BooleanImpl::can_cast(Value const& other_value)
- {
- return other_value.to_bool().has_value();
- }
- int BooleanImpl::compare(Value const& other) const
- {
- auto casted = other.to_bool();
- if (!casted.has_value()) {
- return 1;
- }
- return value() ^ casted.value(); // xor - zero if both true or both false, 1 otherwise.
- }
- u32 BooleanImpl::hash() const
- {
- return int_hash(value());
- }
- void ContainerValueImpl::assign_vector(Vector<Value> const& vector_values)
- {
- if (!validate_before_assignment(vector_values)) {
- m_value = {};
- return;
- }
- m_value = Vector<BaseTypeImpl>();
- for (auto& value : vector_values) {
- if (!append(value)) {
- m_value = {};
- return;
- }
- }
- if (!validate_after_assignment())
- m_value = {};
- }
- bool ContainerValueImpl::to_vector(Vector<Value>& vector) const
- {
- vector.clear();
- for (auto& value : value()) {
- vector.empend(Value(value));
- }
- return true;
- }
- Vector<String> ContainerValueImpl::to_string_vector() const
- {
- Vector<String> ret;
- for (auto& value : value()) {
- ret.append(Value(value).to_string());
- }
- return ret;
- }
- String ContainerValueImpl::to_string() const
- {
- StringBuilder builder;
- builder.append("(");
- StringBuilder joined;
- joined.join(", ", to_string_vector());
- builder.append(joined.string_view());
- builder.append(")");
- return builder.build();
- }
- u32 ContainerValueImpl::hash() const
- {
- u32 ret = 0u;
- for (auto& value : value()) {
- Value v(value);
- // This is an extension of the pair_int_hash function from AK/HashFunctions.h:
- if (!ret)
- ret = v.hash();
- else
- ret = int_hash((ret * 209) ^ (v.hash() * 413));
- }
- return ret;
- }
- bool ContainerValueImpl::append(Value const& value)
- {
- if (value.type() == SQLType::Tuple || value.type() == SQLType::Array)
- return false;
- return append(value.downcast_to_basetype());
- }
- bool ContainerValueImpl::append(BaseTypeImpl const& impl)
- {
- if (m_max_size.has_value() && (size() >= m_max_size.value()))
- return false;
- if (!validate(impl))
- return false;
- m_value.value().empend(impl);
- return true;
- }
- void ContainerValueImpl::serialize_values(ByteBuffer& buffer) const
- {
- serialize_to(buffer, (u32)size());
- for (auto& value : value()) {
- Value(value).serialize_to(buffer);
- }
- }
- void ContainerValueImpl::deserialize_values(ByteBuffer& buffer, size_t& at_offset)
- {
- u32 sz;
- deserialize_from(buffer, at_offset, sz);
- m_value = Vector<BaseTypeImpl>();
- for (auto ix = 0u; ix < sz; ix++) {
- append(Value::deserialize_from(buffer, at_offset));
- }
- }
- void TupleImpl::assign(Value const& other)
- {
- if (other.type() != SQLType::Tuple) {
- m_value = {};
- return;
- }
- auto& other_impl = other.get_impl<TupleImpl>({});
- auto other_descriptor = other_impl.m_descriptor;
- if (m_descriptor && other_descriptor && m_descriptor->compare_ignoring_names(*other_descriptor)) {
- m_value = {};
- return;
- }
- assign_vector(other.to_vector().value());
- }
- size_t TupleImpl::length() const
- {
- return (m_descriptor) ? m_descriptor->data_length() : 0;
- }
- bool TupleImpl::can_cast(Value const& other_value) const
- {
- if (other_value.type() != SQLType::Tuple)
- return false;
- return (m_descriptor == other_value.get_impl<TupleImpl>({}).m_descriptor);
- }
- int TupleImpl::compare(Value const& other) const
- {
- if (other.type() != SQLType::Tuple)
- return 1;
- auto& other_impl = other.get_impl<TupleImpl>({});
- if (m_descriptor && other_impl.m_descriptor && m_descriptor->compare_ignoring_names(*other_impl.m_descriptor))
- return 1;
- auto other_values = other_impl.value();
- if (size() != other_impl.size())
- return (int)value().size() - (int)other_impl.size();
- for (auto ix = 0u; ix < value().size(); ix++) {
- auto ret = Value(value()[ix]).compare(Value(other_impl.value()[ix]));
- if (ret != 0) {
- if (m_descriptor && (ix < m_descriptor->size()) && (*m_descriptor)[ix].order == Order::Descending)
- ret = -ret;
- return ret;
- }
- }
- return 0;
- }
- void TupleImpl::serialize(ByteBuffer& buffer) const
- {
- if (m_descriptor) {
- serialize_to(buffer, (u32)m_descriptor->size());
- for (auto& tuple_element : *m_descriptor) {
- u8 elem_type = (u8)tuple_element.type;
- serialize_to(buffer, elem_type);
- u8 elem_order = (u8)tuple_element.order;
- serialize_to(buffer, elem_order);
- }
- } else {
- serialize_to(buffer, (u32)-1);
- }
- serialize_values(buffer);
- }
- void TupleImpl::deserialize(ByteBuffer& buffer, size_t& at_offset)
- {
- u32 sz;
- deserialize_from(buffer, at_offset, sz);
- if (sz != (u32)-1) {
- NonnullRefPtr<TupleDescriptor> serialized_descriptor = adopt_ref(*new TupleDescriptor);
- for (auto ix = 0u; ix < sz; ix++) {
- u8 elem_type, elem_order;
- deserialize_from(buffer, at_offset, elem_type);
- deserialize_from(buffer, at_offset, elem_order);
- serialized_descriptor->empend("", (SQLType)elem_type, (Order)elem_order);
- }
- m_descriptor = serialized_descriptor;
- m_max_size = m_descriptor->size();
- } else {
- m_descriptor = nullptr;
- m_max_size = {};
- }
- deserialize_values(buffer, at_offset);
- }
- bool TupleImpl::validate(BaseTypeImpl const& value)
- {
- if (!m_descriptor)
- return true;
- auto required_type = (*m_descriptor)[size()].type;
- return Value(value).type() == required_type;
- }
- bool TupleImpl::validate_after_assignment()
- {
- if (!m_descriptor)
- return true;
- for (auto ix = value().size(); ix < m_descriptor->size(); ++ix) {
- auto required_type = (*m_descriptor)[ix].type;
- append(Value(required_type));
- }
- return true;
- }
- void ArrayImpl::assign(Value const& other)
- {
- if (other.type() != SQLType::Array) {
- m_value = {};
- return;
- }
- auto& other_impl = other.get_impl<ArrayImpl>({});
- if (m_max_size != other_impl.m_max_size || m_element_type != other_impl.m_element_type) {
- m_value = {};
- return;
- }
- assign_vector(other.to_vector().value());
- }
- size_t ArrayImpl::length() const
- {
- size_t ret = 0;
- for (auto& value : value()) {
- ret += Value(value).length();
- }
- return ret;
- }
- bool ArrayImpl::can_cast(Value const& other_value) const
- {
- if (other_value.type() != SQLType::Array)
- return false;
- auto& other_impl = other_value.get_impl<ArrayImpl>({});
- return (m_max_size != other_impl.m_max_size || m_element_type != other_impl.m_element_type);
- }
- int ArrayImpl::compare(Value const& other) const
- {
- if (other.type() != SQLType::Array)
- return 1;
- auto other_impl = other.get_impl<ArrayImpl>({});
- if (other_impl.m_element_type != m_element_type)
- return 1;
- if (other_impl.m_max_size.has_value() && m_max_size.has_value() && other_impl.m_max_size != m_max_size)
- return (int)m_max_size.value() - (int)other_impl.m_max_size.value();
- if (size() != other_impl.size())
- return (int)size() - (int)other_impl.size();
- for (auto ix = 0u; ix < size(); ix++) {
- auto ret = Value(value()[ix]).compare(Value(other_impl.value()[ix]));
- if (ret != 0) {
- return ret;
- }
- }
- return 0;
- }
- void ArrayImpl::serialize(ByteBuffer& buffer) const
- {
- serialize_to(buffer, (u8)m_element_type);
- if (m_max_size.has_value())
- serialize_to(buffer, (u32)m_max_size.value());
- else
- serialize_to(buffer, (u32)0);
- serialize_values(buffer);
- }
- void ArrayImpl::deserialize(ByteBuffer& buffer, size_t& at_offset)
- {
- u8 elem_type;
- deserialize_from(buffer, at_offset, elem_type);
- m_element_type = (SQLType)elem_type;
- u32 max_sz;
- deserialize_from(buffer, at_offset, max_sz);
- if (max_sz)
- m_max_size = max_sz;
- else
- m_max_size = {};
- deserialize_values(buffer, at_offset);
- }
- bool ArrayImpl::validate(BaseTypeImpl const& impl)
- {
- return Value(impl).type() == m_element_type;
- }
- }
|