cql3: value_view: switch to fragmented_temporary_buffer::view
This commit is contained in:
@@ -77,12 +77,14 @@ int64_t attributes::get_timestamp(int64_t now, const query_options& options) {
|
||||
if (tval.is_unset_value()) {
|
||||
return now;
|
||||
}
|
||||
return with_linearized(*tval, [] (bytes_view val) {
|
||||
try {
|
||||
data_type_for<int64_t>()->validate(*tval);
|
||||
data_type_for<int64_t>()->validate(val);
|
||||
} catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception("Invalid timestamp value");
|
||||
}
|
||||
return value_cast<int64_t>(data_type_for<int64_t>()->deserialize(*tval));
|
||||
return value_cast<int64_t>(data_type_for<int64_t>()->deserialize(val));
|
||||
});
|
||||
}
|
||||
|
||||
int32_t attributes::get_time_to_live(const query_options& options) {
|
||||
@@ -96,14 +98,16 @@ int32_t attributes::get_time_to_live(const query_options& options) {
|
||||
if (tval.is_unset_value()) {
|
||||
return 0;
|
||||
}
|
||||
auto ttl = with_linearized(*tval, [] (bytes_view val) {
|
||||
try {
|
||||
data_type_for<int32_t>()->validate(*tval);
|
||||
data_type_for<int32_t>()->validate(val);
|
||||
}
|
||||
catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception("Invalid TTL value");
|
||||
}
|
||||
|
||||
auto ttl = value_cast<int32_t>(data_type_for<int32_t>()->deserialize(*tval));
|
||||
return value_cast<int32_t>(data_type_for<int32_t>()->deserialize(val));
|
||||
});
|
||||
if (ttl < 0) {
|
||||
throw exceptions::invalid_request_exception("A TTL must be greater or equal to 0");
|
||||
}
|
||||
|
||||
@@ -225,7 +225,9 @@ public:
|
||||
} else if (value.is_unset_value()) {
|
||||
return;
|
||||
}
|
||||
auto increment = value_cast<int64_t>(long_type->deserialize_value(*value));
|
||||
auto increment = with_linearized(*value, [] (bytes_view value_view) {
|
||||
return value_cast<int64_t>(long_type->deserialize_value(value_view));
|
||||
});
|
||||
m.set_cell(prefix, column, make_counter_update_cell(increment, params));
|
||||
}
|
||||
};
|
||||
@@ -240,7 +242,9 @@ public:
|
||||
} else if (value.is_unset_value()) {
|
||||
return;
|
||||
}
|
||||
auto increment = value_cast<int64_t>(long_type->deserialize_value(*value));
|
||||
auto increment = with_linearized(*value, [] (bytes_view value_view) {
|
||||
return value_cast<int64_t>(long_type->deserialize_value(value_view));
|
||||
});
|
||||
if (increment == std::numeric_limits<int64_t>::min()) {
|
||||
throw exceptions::invalid_request_exception(sprint("The negation of %d overflows supported counter precision (signed 8 bytes integer)", increment));
|
||||
}
|
||||
|
||||
@@ -461,9 +461,9 @@ function_call::make_terminal(shared_ptr<function> fun, cql3::raw_value result, c
|
||||
}
|
||||
|
||||
auto ctype = static_pointer_cast<const collection_type_impl>(fun->return_type());
|
||||
bytes_view res;
|
||||
fragmented_temporary_buffer::view res;
|
||||
if (result) {
|
||||
res = *result;
|
||||
res = fragmented_temporary_buffer::view(bytes_view(*result));
|
||||
}
|
||||
if (&ctype->_kind == &collection_type_impl::kind::list) {
|
||||
return make_shared(lists::value::from_serialized(std::move(res), static_pointer_cast<const list_type_impl>(ctype), sf));
|
||||
|
||||
@@ -115,11 +115,12 @@ lists::literal::to_string() const {
|
||||
}
|
||||
|
||||
lists::value
|
||||
lists::value::from_serialized(bytes_view v, list_type type, cql_serialization_format sf) {
|
||||
lists::value::from_serialized(const fragmented_temporary_buffer::view& val, list_type type, cql_serialization_format sf) {
|
||||
try {
|
||||
// Collections have this small hack that validate cannot be called on a serialized object,
|
||||
// but compose does the validation (so we're fine).
|
||||
// FIXME: deserializeForNativeProtocol()?!
|
||||
return with_linearized(val, [&] (bytes_view v) {
|
||||
auto l = value_cast<list_type_impl::native_type>(type->deserialize(v, sf));
|
||||
std::vector<bytes_opt> elements;
|
||||
elements.reserve(l.size());
|
||||
@@ -128,6 +129,7 @@ lists::value::from_serialized(bytes_view v, list_type type, cql_serialization_fo
|
||||
elements.push_back(element.is_null() ? bytes_opt() : bytes_opt(type->get_elements_type()->decompose(element)));
|
||||
}
|
||||
return value(std::move(elements));
|
||||
});
|
||||
} catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception(e.what());
|
||||
}
|
||||
@@ -285,7 +287,9 @@ lists::setter_by_index::execute(mutation& m, const clustering_key_prefix& prefix
|
||||
return;
|
||||
}
|
||||
|
||||
auto idx = net::ntoh(int32_t(*unaligned_cast<int32_t>(index->begin())));
|
||||
auto idx = with_linearized(*index, [] (bytes_view v) {
|
||||
return value_cast<int32_t>(data_type_for<int32_t>()->deserialize(v));
|
||||
});
|
||||
auto&& existing_list_opt = params.get_prefetched_list(m.key().view(), prefix.view(), column);
|
||||
if (!existing_list_opt) {
|
||||
throw exceptions::invalid_request_exception("Attempted to set an element on a list which is null");
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
explicit value(std::vector<bytes_opt> elements)
|
||||
: _elements(std::move(elements)) {
|
||||
}
|
||||
static value from_serialized(bytes_view v, list_type type, cql_serialization_format sf);
|
||||
static value from_serialized(const fragmented_temporary_buffer::view& v, list_type type, cql_serialization_format sf);
|
||||
virtual cql3::raw_value get(const query_options& options) override;
|
||||
virtual bytes get_with_protocol_version(cql_serialization_format sf) override;
|
||||
bool equals(shared_ptr<list_type_impl> lt, const value& v);
|
||||
|
||||
14
cql3/maps.cc
14
cql3/maps.cc
@@ -152,18 +152,20 @@ maps::literal::to_string() const {
|
||||
}
|
||||
|
||||
maps::value
|
||||
maps::value::from_serialized(bytes_view value, map_type type, cql_serialization_format sf) {
|
||||
maps::value::from_serialized(const fragmented_temporary_buffer::view& fragmented_value, map_type type, cql_serialization_format sf) {
|
||||
try {
|
||||
// Collections have this small hack that validate cannot be called on a serialized object,
|
||||
// but compose does the validation (so we're fine).
|
||||
// FIXME: deserialize_for_native_protocol?!
|
||||
return with_linearized(fragmented_value, [&] (bytes_view value) {
|
||||
auto m = value_cast<map_type_impl::native_type>(type->deserialize(value, sf));
|
||||
std::map<bytes, bytes, serialized_compare> map(type->get_keys_type()->as_less_comparator());
|
||||
for (auto&& e : m) {
|
||||
map.emplace(type->get_keys_type()->decompose(e.first),
|
||||
type->get_values_type()->decompose(e.second));
|
||||
}
|
||||
return { std::move(map) };
|
||||
return maps::value { std::move(map) };
|
||||
});
|
||||
} catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception(e.what());
|
||||
}
|
||||
@@ -233,10 +235,10 @@ maps::delayed_value::bind(const query_options& options) {
|
||||
if (key_bytes.is_unset_value()) {
|
||||
throw exceptions::invalid_request_exception("unset value is not supported inside collections");
|
||||
}
|
||||
if (key_bytes->size() > std::numeric_limits<uint16_t>::max()) {
|
||||
if (key_bytes->size_bytes() > std::numeric_limits<uint16_t>::max()) {
|
||||
throw exceptions::invalid_request_exception(sprint("Map key is too long. Map keys are limited to %d bytes but %d bytes keys provided",
|
||||
std::numeric_limits<uint16_t>::max(),
|
||||
key_bytes->size()));
|
||||
key_bytes->size_bytes()));
|
||||
}
|
||||
auto value_bytes = value->bind_and_get(options);
|
||||
if (value_bytes.is_null()) {
|
||||
@@ -331,7 +333,7 @@ maps::do_put(mutation& m, const clustering_key_prefix& prefix, const update_para
|
||||
|
||||
auto ctype = static_pointer_cast<const map_type_impl>(column.type);
|
||||
for (auto&& e : map_value->map) {
|
||||
mut.cells.emplace_back(e.first, params.make_cell(*ctype->get_values_type(), e.second, atomic_cell::collection_member::yes));
|
||||
mut.cells.emplace_back(e.first, params.make_cell(*ctype->get_values_type(), fragmented_temporary_buffer::view(e.second), atomic_cell::collection_member::yes));
|
||||
}
|
||||
auto col_mut = ctype->serialize_mutation_form(std::move(mut));
|
||||
m.set_cell(prefix, column, std::move(col_mut));
|
||||
@@ -342,7 +344,7 @@ maps::do_put(mutation& m, const clustering_key_prefix& prefix, const update_para
|
||||
} else {
|
||||
auto v = map_type_impl::serialize_partially_deserialized_form({map_value->map.begin(), map_value->map.end()},
|
||||
cql_serialization_format::internal());
|
||||
m.set_cell(prefix, column, params.make_cell(*column.type, std::move(v)));
|
||||
m.set_cell(prefix, column, params.make_cell(*column.type, fragmented_temporary_buffer::view(std::move(v))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
value(std::map<bytes, bytes, serialized_compare> map)
|
||||
: map(std::move(map)) {
|
||||
}
|
||||
static value from_serialized(bytes_view value, map_type type, cql_serialization_format sf);
|
||||
static value from_serialized(const fragmented_temporary_buffer::view& value, map_type type, cql_serialization_format sf);
|
||||
virtual cql3::raw_value get(const query_options& options) override;
|
||||
virtual bytes get_with_protocol_version(cql_serialization_format sf);
|
||||
bool equals(map_type mt, const value& v);
|
||||
|
||||
@@ -156,7 +156,7 @@ cql3::raw_value_view query_options::make_temporary(cql3::raw_value value) const
|
||||
auto value_view = *value;
|
||||
auto ptr = _temporaries.write_place_holder(value_view.size());
|
||||
std::copy_n(value_view.data(), value_view.size(), ptr);
|
||||
return cql3::raw_value_view::make_value(bytes_view{ptr, value_view.size()});
|
||||
return cql3::raw_value_view::make_value(fragmented_temporary_buffer::view(bytes_view{ptr, value_view.size()}));
|
||||
}
|
||||
return cql3::raw_value_view::make_null();
|
||||
}
|
||||
@@ -254,7 +254,7 @@ void query_options::fill_value_views()
|
||||
{
|
||||
for (auto&& value : _values) {
|
||||
if (value) {
|
||||
_value_views.emplace_back(cql3::raw_value_view::make_value(bytes_view{*value}));
|
||||
_value_views.emplace_back(cql3::raw_value_view::make_value(fragmented_temporary_buffer::view(bytes_view{*value})));
|
||||
} else {
|
||||
_value_views.emplace_back(cql3::raw_value_view::make_null());
|
||||
}
|
||||
|
||||
@@ -588,7 +588,8 @@ static query::range<bytes_view> to_range(const term_slice& slice, const query_op
|
||||
if (!value) {
|
||||
return { };
|
||||
}
|
||||
return { range_type::bound(*value, slice.is_inclusive(bound)) };
|
||||
auto value_view = options.linearize(*value);
|
||||
return { range_type::bound(value_view, slice.is_inclusive(bound)) };
|
||||
};
|
||||
return range_type(
|
||||
extract_bound(statements::bound::START),
|
||||
@@ -653,10 +654,12 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
if (!val) {
|
||||
continue;
|
||||
}
|
||||
auto found = std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
auto found = with_linearized(*val, [&] (bytes_view bv) {
|
||||
return std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
return element.second.value().with_linearized([&] (bytes_view value_bv) {
|
||||
return element_type->compare(value_bv, *val) == 0;
|
||||
return element_type->compare(value_bv, bv) == 0;
|
||||
});
|
||||
});
|
||||
});
|
||||
if (found == end) {
|
||||
return false;
|
||||
@@ -667,8 +670,10 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
if (!k) {
|
||||
continue;
|
||||
}
|
||||
auto found = std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first, *k) == 0;
|
||||
auto found = with_linearized(*k, [&] (bytes_view bv) {
|
||||
return std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first, bv) == 0;
|
||||
});
|
||||
});
|
||||
if (found == end) {
|
||||
return false;
|
||||
@@ -680,14 +685,18 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
if (!map_key || !map_value) {
|
||||
continue;
|
||||
}
|
||||
auto found = std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first, *map_key) == 0;
|
||||
auto found = with_linearized(*map_key, [&] (bytes_view map_key_bv) {
|
||||
return std::find_if(elements.begin(), end, [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first, map_key_bv) == 0;
|
||||
});
|
||||
});
|
||||
if (found == end) {
|
||||
return false;
|
||||
}
|
||||
auto cmp = found->second.value().with_linearized([&] (bytes_view value_bv) {
|
||||
return element_type->compare(value_bv, *map_value);
|
||||
auto cmp = with_linearized(*map_value, [&] (bytes_view map_value_bv) {
|
||||
return found->second.value().with_linearized([&] (bytes_view value_bv) {
|
||||
return element_type->compare(value_bv, map_value_bv);
|
||||
});
|
||||
});
|
||||
if (cmp != 0) {
|
||||
return false;
|
||||
@@ -704,13 +713,14 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
return _column_def.type->deserialize(cell_value_bv);
|
||||
});
|
||||
for (auto&& value : _values) {
|
||||
auto val = value->bind_and_get(options);
|
||||
if (!val) {
|
||||
auto fragmented_val = value->bind_and_get(options);
|
||||
if (!fragmented_val) {
|
||||
continue;
|
||||
}
|
||||
return with_linearized(*fragmented_val, [&] (bytes_view val) {
|
||||
auto exists_in = [&](auto&& range) {
|
||||
auto found = std::find_if(range.begin(), range.end(), [&] (auto&& element) {
|
||||
return element_type->compare(element.serialize(), *val) == 0;
|
||||
return element_type->compare(element.serialize(), val) == 0;
|
||||
});
|
||||
return found != range.end();
|
||||
};
|
||||
@@ -728,6 +738,8 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
if (col_type->is_map()) {
|
||||
auto& data_map = value_cast<map_type_impl::native_type>(deserialized);
|
||||
@@ -736,8 +748,10 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
if (!k) {
|
||||
continue;
|
||||
}
|
||||
auto found = std::find_if(data_map.begin(), data_map.end(), [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first.serialize(), *k) == 0;
|
||||
auto found = with_linearized(*k, [&] (bytes_view k_bv) {
|
||||
return std::find_if(data_map.begin(), data_map.end(), [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first.serialize(), k_bv) == 0;
|
||||
});
|
||||
});
|
||||
if (found == data_map.end()) {
|
||||
return false;
|
||||
@@ -749,10 +763,15 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
if (!map_key || !map_value) {
|
||||
continue;
|
||||
}
|
||||
auto found = std::find_if(data_map.begin(), data_map.end(), [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first.serialize(), *map_key) == 0;
|
||||
auto found = with_linearized(*map_key, [&] (bytes_view map_key_bv) {
|
||||
return std::find_if(data_map.begin(), data_map.end(), [&] (auto&& element) {
|
||||
return map_key_type->compare(element.first.serialize(), map_key_bv) == 0;
|
||||
});
|
||||
});
|
||||
if (found == data_map.end() || element_type->compare(found->second.serialize(), *map_value) != 0) {
|
||||
if (found == data_map.end()
|
||||
|| with_linearized(*map_value, [&] (bytes_view map_value_bv) {
|
||||
return element_type->compare(found->second.serialize(), map_value_bv);
|
||||
}) != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
10
cql3/sets.cc
10
cql3/sets.cc
@@ -120,17 +120,19 @@ sets::literal::to_string() const {
|
||||
}
|
||||
|
||||
sets::value
|
||||
sets::value::from_serialized(bytes_view v, set_type type, cql_serialization_format sf) {
|
||||
sets::value::from_serialized(const fragmented_temporary_buffer::view& val, set_type type, cql_serialization_format sf) {
|
||||
try {
|
||||
// Collections have this small hack that validate cannot be called on a serialized object,
|
||||
// but compose does the validation (so we're fine).
|
||||
// FIXME: deserializeForNativeProtocol?!
|
||||
return with_linearized(val, [&] (bytes_view v) {
|
||||
auto s = value_cast<set_type_impl::native_type>(type->deserialize(v, sf));
|
||||
std::set<bytes, serialized_compare> elements(type->get_elements_type()->as_less_comparator());
|
||||
for (auto&& element : s) {
|
||||
elements.insert(elements.end(), type->get_elements_type()->decompose(element));
|
||||
}
|
||||
return value(std::move(elements));
|
||||
});
|
||||
} catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception(e.what());
|
||||
}
|
||||
@@ -198,10 +200,10 @@ sets::delayed_value::bind(const query_options& options) {
|
||||
return constants::UNSET_VALUE;
|
||||
}
|
||||
// We don't support value > 64K because the serialization format encode the length as an unsigned short.
|
||||
if (b->size() > std::numeric_limits<uint16_t>::max()) {
|
||||
if (b->size_bytes() > std::numeric_limits<uint16_t>::max()) {
|
||||
throw exceptions::invalid_request_exception(sprint("Set value is too long. Set values are limited to %d bytes but %d bytes value provided",
|
||||
std::numeric_limits<uint16_t>::max(),
|
||||
b->size()));
|
||||
b->size_bytes()));
|
||||
}
|
||||
|
||||
buffers.insert(buffers.end(), std::move(to_bytes(*b)));
|
||||
@@ -279,7 +281,7 @@ sets::adder::do_add(mutation& m, const clustering_key_prefix& row_key, const upd
|
||||
auto v = set_type->serialize_partially_deserialized_form(
|
||||
{set_value->_elements.begin(), set_value->_elements.end()},
|
||||
cql_serialization_format::internal());
|
||||
m.set_cell(row_key, column, params.make_cell(*column.type, std::move(v)));
|
||||
m.set_cell(row_key, column, params.make_cell(*column.type, fragmented_temporary_buffer::view(v)));
|
||||
} else {
|
||||
m.set_cell(row_key, column, params.make_dead_cell());
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
value(std::set<bytes, serialized_compare> elements)
|
||||
: _elements(std::move(elements)) {
|
||||
}
|
||||
static value from_serialized(bytes_view v, set_type type, cql_serialization_format sf);
|
||||
static value from_serialized(const fragmented_temporary_buffer::view& v, set_type type, cql_serialization_format sf);
|
||||
virtual cql3::raw_value get(const query_options& options) override;
|
||||
virtual bytes get_with_protocol_version(cql_serialization_format sf) override;
|
||||
bool equals(set_type st, const value& v);
|
||||
|
||||
@@ -333,9 +333,10 @@ int32_t select_statement::get_limit(const query_options& options) const {
|
||||
if (val.is_unset_value()) {
|
||||
return std::numeric_limits<int32_t>::max();
|
||||
}
|
||||
return with_linearized(*val, [&] (bytes_view bv) {
|
||||
try {
|
||||
int32_type->validate(*val);
|
||||
auto l = value_cast<int32_t>(int32_type->deserialize(*val));
|
||||
int32_type->validate(bv);
|
||||
auto l = value_cast<int32_t>(int32_type->deserialize(bv));
|
||||
if (l <= 0) {
|
||||
throw exceptions::invalid_request_exception("LIMIT must be strictly positive");
|
||||
}
|
||||
@@ -343,6 +344,7 @@ int32_t select_statement::get_limit(const query_options& options) const {
|
||||
} catch (const marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception("Invalid limit value");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool select_statement::needs_post_query_ordering() const {
|
||||
|
||||
@@ -172,7 +172,9 @@ void update_statement::add_update_for_key(mutation& m, const query::clustering_r
|
||||
}
|
||||
|
||||
modification_statement::json_cache_opt insert_prepared_json_statement::maybe_prepare_json_cache(const query_options& options) {
|
||||
sstring json_string = utf8_type->to_string(_term->bind_and_get(options).data().value().to_string());
|
||||
sstring json_string = with_linearized(_term->bind_and_get(options).data().value(), [&] (bytes_view value) {
|
||||
return utf8_type->to_string(value.to_string());
|
||||
});
|
||||
return json_helpers::parse(std::move(json_string), s->all_columns(), options.get_cql_serialization_format());
|
||||
}
|
||||
|
||||
@@ -181,20 +183,20 @@ insert_prepared_json_statement::execute_set_value(mutation& m, const clustering_
|
||||
if (!value) {
|
||||
m.set_cell(prefix, column, std::move(operation::make_dead_cell(params)));
|
||||
} else if (!column.type->is_collection()) {
|
||||
constants::setter::execute(m, prefix, params, column, raw_value_view::make_value(bytes_view(*value)));
|
||||
constants::setter::execute(m, prefix, params, column, raw_value_view::make_value(fragmented_temporary_buffer::view(*value)));
|
||||
return;
|
||||
}
|
||||
|
||||
auto& k = static_pointer_cast<const collection_type_impl>(column.type)->_kind;
|
||||
cql_serialization_format sf = params._options.get_cql_serialization_format();
|
||||
if (&k == &collection_type_impl::kind::list) {
|
||||
auto list_terminal = make_shared<lists::value>(lists::value::from_serialized(*value, dynamic_pointer_cast<const list_type_impl>(column.type), sf));
|
||||
auto list_terminal = make_shared<lists::value>(lists::value::from_serialized(fragmented_temporary_buffer::view(*value), dynamic_pointer_cast<const list_type_impl>(column.type), sf));
|
||||
lists::setter::execute(m, prefix, params, column, std::move(list_terminal));
|
||||
} else if (&k == &collection_type_impl::kind::set) {
|
||||
auto set_terminal = make_shared<sets::value>(sets::value::from_serialized(*value, dynamic_pointer_cast<const set_type_impl>(column.type), sf));
|
||||
auto set_terminal = make_shared<sets::value>(sets::value::from_serialized(fragmented_temporary_buffer::view(*value), dynamic_pointer_cast<const set_type_impl>(column.type), sf));
|
||||
sets::setter::execute(m, prefix, params, column, std::move(set_terminal));
|
||||
} else if (&k == &collection_type_impl::kind::map) {
|
||||
auto map_terminal = make_shared<maps::value>(maps::value::from_serialized(*value, dynamic_pointer_cast<const map_type_impl>(column.type), sf));
|
||||
auto map_terminal = make_shared<maps::value>(maps::value::from_serialized(fragmented_temporary_buffer::view(*value), dynamic_pointer_cast<const map_type_impl>(column.type), sf));
|
||||
maps::setter::execute(m, prefix, params, column, std::move(map_terminal));
|
||||
} else {
|
||||
throw exceptions::invalid_request_exception("Incorrect value kind in JSON INSERT statement");
|
||||
|
||||
@@ -159,8 +159,10 @@ public:
|
||||
_elements.push_back(e ? bytes_opt(bytes(e->begin(), e->size())) : bytes_opt());
|
||||
}
|
||||
}
|
||||
static value from_serialized(bytes_view buffer, tuple_type type) {
|
||||
return value(type->split(buffer));
|
||||
static value from_serialized(const fragmented_temporary_buffer::view& buffer, tuple_type type) {
|
||||
return with_linearized(buffer, [&] (bytes_view view) {
|
||||
return value(type->split(view));
|
||||
});
|
||||
}
|
||||
virtual cql3::raw_value get(const query_options& options) override {
|
||||
return cql3::raw_value::make_value(tuple_type_impl::build_value(_elements));
|
||||
@@ -251,10 +253,11 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static in_value from_serialized(bytes_view value, list_type type, const query_options& options) {
|
||||
static in_value from_serialized(const fragmented_temporary_buffer::view& value_view, list_type type, const query_options& options) {
|
||||
try {
|
||||
// Collections have this small hack that validate cannot be called on a serialized object,
|
||||
// but the deserialization does the validation (so we're fine).
|
||||
return with_linearized(value_view, [&] (bytes_view value) {
|
||||
auto l = value_cast<list_type_impl::native_type>(type->deserialize(value, options.get_cql_serialization_format()));
|
||||
auto ttype = dynamic_pointer_cast<const tuple_type_impl>(type->get_elements_type());
|
||||
assert(ttype);
|
||||
@@ -265,6 +268,7 @@ public:
|
||||
elements.emplace_back(ttype->split(ttype->decompose(element)));
|
||||
}
|
||||
return in_value(elements);
|
||||
});
|
||||
} catch (marshal_exception& e) {
|
||||
throw exceptions::invalid_request_exception(e.what());
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <seastar/util/variant_utils.hh>
|
||||
|
||||
#include "utils/fragmented_temporary_buffer.hh"
|
||||
|
||||
namespace cql3 {
|
||||
|
||||
struct null_value {
|
||||
@@ -42,7 +44,7 @@ struct unset_value {
|
||||
///
|
||||
/// \see raw_value
|
||||
struct raw_value_view {
|
||||
boost::variant<bytes_view, null_value, unset_value> _data;
|
||||
boost::variant<fragmented_temporary_buffer::view, null_value, unset_value> _data;
|
||||
|
||||
raw_value_view(null_value&& data)
|
||||
: _data{std::move(data)}
|
||||
@@ -50,10 +52,7 @@ struct raw_value_view {
|
||||
raw_value_view(unset_value&& data)
|
||||
: _data{std::move(data)}
|
||||
{}
|
||||
raw_value_view(bytes_view&& data)
|
||||
: _data{std::move(data)}
|
||||
{}
|
||||
raw_value_view(const bytes_view& data)
|
||||
raw_value_view(fragmented_temporary_buffer::view data)
|
||||
: _data{data}
|
||||
{}
|
||||
public:
|
||||
@@ -63,10 +62,7 @@ public:
|
||||
static raw_value_view make_unset_value() {
|
||||
return raw_value_view{std::move(unset_value{})};
|
||||
}
|
||||
static raw_value_view make_value(bytes_view &&view) {
|
||||
return raw_value_view{std::move(view)};
|
||||
}
|
||||
static raw_value_view make_value(const bytes_view& view) {
|
||||
static raw_value_view make_value(fragmented_temporary_buffer::view view) {
|
||||
return raw_value_view{view};
|
||||
}
|
||||
bool is_null() const {
|
||||
@@ -78,20 +74,20 @@ public:
|
||||
bool is_value() const {
|
||||
return _data.which() == 0;
|
||||
}
|
||||
bytes_view_opt data() const {
|
||||
std::optional<fragmented_temporary_buffer::view> data() const {
|
||||
if (_data.which() == 0) {
|
||||
return boost::get<bytes_view>(_data);
|
||||
return boost::get<fragmented_temporary_buffer::view>(_data);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return _data.which() == 0;
|
||||
}
|
||||
const bytes_view* operator->() const {
|
||||
return &boost::get<bytes_view>(_data);
|
||||
const fragmented_temporary_buffer::view* operator->() const {
|
||||
return &boost::get<fragmented_temporary_buffer::view>(_data);
|
||||
}
|
||||
const bytes_view& operator*() const {
|
||||
return boost::get<bytes_view>(_data);
|
||||
const fragmented_temporary_buffer::view& operator*() const {
|
||||
return boost::get<fragmented_temporary_buffer::view>(_data);
|
||||
}
|
||||
|
||||
bool operator==(const raw_value_view& other) const {
|
||||
@@ -108,8 +104,11 @@ public:
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const raw_value_view& value) {
|
||||
seastar::visit(value._data, [&] (bytes_view v) {
|
||||
os << "{ value: " << v << " }";
|
||||
seastar::visit(value._data, [&] (fragmented_temporary_buffer::view v) {
|
||||
os << "{ value: ";
|
||||
using boost::range::for_each;
|
||||
for_each(v, [&os] (bytes_view bv) { os << bv; });
|
||||
os << " }";
|
||||
}, [&] (null_value) {
|
||||
os << "{ null }";
|
||||
}, [&] (unset_value) {
|
||||
@@ -153,7 +152,7 @@ public:
|
||||
if (view.is_unset_value()) {
|
||||
return make_unset_value();
|
||||
}
|
||||
return make_value(to_bytes(*view));
|
||||
return make_value(linearized(*view));
|
||||
}
|
||||
static raw_value make_value(bytes&& bytes) {
|
||||
return raw_value{std::move(bytes)};
|
||||
@@ -193,7 +192,7 @@ public:
|
||||
}
|
||||
raw_value_view to_view() const {
|
||||
switch (_data.which()) {
|
||||
case 0: return raw_value_view::make_value(bytes_view{boost::get<bytes>(_data)});
|
||||
case 0: return raw_value_view::make_value(fragmented_temporary_buffer::view(bytes_view{boost::get<bytes>(_data)}));
|
||||
case 1: return raw_value_view::make_null();
|
||||
default: return raw_value_view::make_unset_value();
|
||||
}
|
||||
@@ -202,10 +201,19 @@ public:
|
||||
|
||||
}
|
||||
|
||||
inline bytes to_bytes(const cql3::raw_value_view& view)
|
||||
{
|
||||
return linearized(*view);
|
||||
}
|
||||
|
||||
inline bytes_opt to_bytes_opt(const cql3::raw_value_view& view) {
|
||||
return to_bytes_opt(view.data());
|
||||
auto buffer_view = view.data();
|
||||
if (buffer_view) {
|
||||
return bytes_opt(linearized(*buffer_view));
|
||||
}
|
||||
return bytes_opt();
|
||||
}
|
||||
|
||||
inline bytes_opt to_bytes_opt(const cql3::raw_value& value) {
|
||||
return value.data();
|
||||
return to_bytes_opt(value.to_view());
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ sstring trace_state::raw_value_to_sstring(const cql3::raw_value_view& v, const d
|
||||
} else if (v.is_unset_value()) {
|
||||
return "unset value";
|
||||
} else {
|
||||
const bytes_view& val = *v;
|
||||
return with_linearized(*v, [&] (bytes_view val) {
|
||||
sstring str_rep;
|
||||
|
||||
if (t) {
|
||||
@@ -278,6 +278,7 @@ sstring trace_state::raw_value_to_sstring(const cql3::raw_value_view& v, const d
|
||||
} else {
|
||||
return str_rep;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
throw exceptions::protocol_exception(sprint("invalid value length: %d", len));
|
||||
}
|
||||
}
|
||||
return cql3::raw_value_view::make_value(_in.read_bytes_view(len, *_linearization_buffer, exception_thrower()));
|
||||
return cql3::raw_value_view::make_value(_in.read_view(len, exception_thrower()));
|
||||
}
|
||||
|
||||
void read_name_and_value_list(uint8_t version, std::vector<sstring_view>& names, std::vector<cql3::raw_value_view>& values) {
|
||||
|
||||
Reference in New Issue
Block a user