diff --git a/cql3/operation.hh b/cql3/operation.hh
index 58e44c535e..b0d8e4ee8d 100644
--- a/cql3/operation.hh
+++ b/cql3/operation.hh
@@ -109,7 +109,7 @@ public:
/**
* Execute the operation.
*/
- virtual void execute(mutation& m, const clustering_prefix& row_key, const update_parameters& params) = 0;
+ virtual void execute(mutation& m, const clustering_prefix& prefix, const update_parameters& params) = 0;
/**
* A parsed raw UPDATE operation.
diff --git a/cql3/restrictions/forwarding_primary_key_restrictions.hh b/cql3/restrictions/forwarding_primary_key_restrictions.hh
index e9b5fb770e..c7853b87e2 100644
--- a/cql3/restrictions/forwarding_primary_key_restrictions.hh
+++ b/cql3/restrictions/forwarding_primary_key_restrictions.hh
@@ -31,16 +31,17 @@ namespace cql3 {
namespace restrictions {
/**
- * A primary_key_restrictions which forwards all its method calls to another
- * primary_key_restrictions. Subclasses should override one or more methods to modify the behavior
- * of the backing primary_key_restrictions as desired per the decorator pattern.
+ * A primary_key_restrictions which forwards all its method calls to another
+ * primary_key_restrictions. Subclasses should override one or more methods to modify the behavior
+ * of the backing primary_key_restrictions as desired per the decorator pattern.
*/
-class forwarding_primary_key_restrictions : public primary_key_restrictions {
+template
+class forwarding_primary_key_restrictions : public primary_key_restrictions {
protected:
/**
* Returns the backing delegate instance that methods are forwarded to.
*/
- virtual ::shared_ptr get_delegate() = 0;
+ virtual ::shared_ptr> get_delegate() = 0;
public:
virtual bool uses_function(const sstring& ks_name, const sstring& function_name) override {
@@ -61,11 +62,11 @@ public:
}
#endif
- virtual std::vector values_as_serialized_tuples(const query_options& options) override {
- return get_delegate()->values_as_serialized_tuples(options);
+ virtual std::vector values(const query_options& options) override {
+ return get_delegate()->values(options);
}
- virtual std::vector bounds(const query_options& options) override {
+ virtual std::vector> bounds(const query_options& options) override {
return get_delegate()->bounds(options);
}
@@ -101,7 +102,7 @@ public:
virtual void addIndexExpressionTo(List expressions, QueryOptions options) {
get_delegate()->addIndexExpressionTo(expressions, options);
}
-#endif
+#endif
};
}
diff --git a/cql3/restrictions/primary_key_restrictions.hh b/cql3/restrictions/primary_key_restrictions.hh
index 6312458878..4684081238 100644
--- a/cql3/restrictions/primary_key_restrictions.hh
+++ b/cql3/restrictions/primary_key_restrictions.hh
@@ -47,13 +47,14 @@ namespace restrictions {
* What was in AbstractPrimaryKeyRestrictions was moved here (In pre 1.8 Java interfaces could not have default
* implementations of methods).
*/
+template
class primary_key_restrictions : public restrictions {
public:
virtual void merge_with(::shared_ptr restriction) = 0;
- virtual std::vector values_as_serialized_tuples(const query_options& options) = 0;
+ virtual std::vector values(const query_options& options) = 0;
- virtual std::vector bounds(const query_options& options) = 0;
+ virtual std::vector> bounds(const query_options& options) = 0;
virtual bool is_inclusive(statements::bound b) { return true; }
diff --git a/cql3/restrictions/reverse_primary_key_restrictions.hh b/cql3/restrictions/reverse_primary_key_restrictions.hh
index 2629d14ab9..3b40456fb0 100644
--- a/cql3/restrictions/reverse_primary_key_restrictions.hh
+++ b/cql3/restrictions/reverse_primary_key_restrictions.hh
@@ -33,19 +33,20 @@ namespace restrictions {
/**
* PrimaryKeyRestrictions decorator that reverse the slices.
*/
-class reversed_primary_key_restrictions : public forwarding_primary_key_restrictions {
+template
+class reversed_primary_key_restrictions : public forwarding_primary_key_restrictions {
private:
- ::shared_ptr _restrictions;
+ ::shared_ptr> _restrictions;
protected:
- virtual ::shared_ptr get_delegate() override {
+ virtual ::shared_ptr> get_delegate() override {
return _restrictions;
}
public:
- reversed_primary_key_restrictions(shared_ptr restrictions)
+ reversed_primary_key_restrictions(shared_ptr> restrictions)
: _restrictions(std::move(restrictions))
{ }
- virtual std::vector bounds(const query_options& options) override {
+ virtual std::vector> bounds(const query_options& options) override {
auto ranges = _restrictions->bounds(options);
for (auto&& range : ranges) {
range.reverse();
diff --git a/cql3/restrictions/single_column_primary_key_restrictions.hh b/cql3/restrictions/single_column_primary_key_restrictions.hh
index 2125d8b49f..93f39a9e8e 100644
--- a/cql3/restrictions/single_column_primary_key_restrictions.hh
+++ b/cql3/restrictions/single_column_primary_key_restrictions.hh
@@ -37,19 +37,20 @@ namespace restrictions {
/**
* A set of single column restrictions on a primary key part (partition key or clustering key).
*/
-class single_column_primary_key_restrictions : public primary_key_restrictions {
+template
+class single_column_primary_key_restrictions : public primary_key_restrictions {
+ using range_type = query::range;
+ using range_bound = typename range_type::bound;
private:
schema_ptr _schema;
::shared_ptr _restrictions;
- ::shared_ptr> _tuple;
bool _slice;
bool _contains;
bool _in;
public:
- single_column_primary_key_restrictions(schema_ptr schema, ::shared_ptr> tuple)
+ single_column_primary_key_restrictions(schema_ptr schema)
: _schema(schema)
, _restrictions(::make_shared(schema))
- , _tuple(std::move(tuple))
, _slice(false)
, _contains(false)
, _in(false)
@@ -121,7 +122,7 @@ public:
do_merge_with(::static_pointer_cast(restriction));
}
- virtual std::vector values_as_serialized_tuples(const query_options& options) override {
+ virtual std::vector values(const query_options& options) override {
std::vector> value_vector;
value_vector.reserve(_restrictions->size());
for (auto def : _restrictions->get_column_defs()) {
@@ -140,16 +141,16 @@ public:
value_vector.emplace_back(std::move(values));
}
- std::vector result;
+ std::vector result;
result.reserve(cartesian_product_size(value_vector));
for (auto&& v : make_cartesian_product(value_vector)) {
- result.emplace_back(_tuple->serialize_value(v));
+ result.emplace_back(ValueType::from_exploded(*_schema, v));
}
return result;
}
- virtual std::vector bounds(const query_options& options) override {
- std::vector ranges;
+ virtual std::vector bounds(const query_options& options) override {
+ std::vector ranges;
std::vector> vec_of_values;
// TODO: optimize for all EQ case
@@ -164,26 +165,20 @@ public:
}
if (r->is_slice()) {
- // TODO: make restriction::bounds() return query::range to simplify all this
if (cartesian_product_is_empty(vec_of_values)) {
- auto read_value = [r, &options] (statements::bound b) {
+ auto read_bound = [r, &options, this] (statements::bound b) -> std::experimental::optional {
+ if (!r->has_bound(b)) {
+ return {};
+ }
auto value = r->bounds(b, options)[0];
if (!value) {
throw exceptions::invalid_request_exception(sprint("Invalid null clustering key part %s", r->to_string()));
}
- return *value;
+ return {range_bound(ValueType::from_exploded(*_schema, {*value}), r->is_inclusive(b))};
};
- if (r->has_bound(statements::bound::START) && r->has_bound(statements::bound::END)) {
- ranges.emplace_back(query::range(read_value(statements::bound::START), read_value(statements::bound::END),
- r->is_inclusive(statements::bound::START), r->is_inclusive(statements::bound::END)));
- } else if (r->has_bound(statements::bound::START)) {
- ranges.emplace_back(query::range::make_starting_with(read_value(statements::bound::START),
- r->is_inclusive(statements::bound::START)));
- } else {
- assert(r->has_bound(statements::bound::END));
- ranges.emplace_back(query::range::make_ending_with(read_value(statements::bound::END),
- r->is_inclusive(statements::bound::END)));
- }
+ ranges.emplace_back(range_type(
+ read_bound(statements::bound::START),
+ read_bound(statements::bound::END)));
if (def->type->is_reversed()) {
ranges.back().reverse();
}
@@ -192,31 +187,25 @@ public:
ranges.reserve(cartesian_product_size(vec_of_values));
for (auto&& prefix : make_cartesian_product(vec_of_values)) {
- auto read_bounds = [r, &prefix, &options, this](bytes& value_holder, bool& inclusive_holder, statements::bound bound) {
+ auto read_bound = [r, &prefix, &options, this](statements::bound bound) -> range_bound {
if (r->has_bound(bound)) {
auto value = std::move(r->bounds(bound, options)[0]);
if (!value) {
throw exceptions::invalid_request_exception(sprint("Invalid null clustering key part %s", r->to_string()));
}
prefix.emplace_back(std::move(value));
- value_holder = _tuple->serialize_value(prefix);
+ auto val = ValueType::from_exploded(*_schema, prefix);
prefix.pop_back();
- inclusive_holder = r->is_inclusive(bound);
+ return range_bound(std::move(val), r->is_inclusive(bound));
} else {
- value_holder = _tuple->serialize_value(prefix);
- inclusive_holder = true;
+ return range_bound(ValueType::from_exploded(*_schema, prefix));
}
};
- bytes start_tuple;
- bytes end_tuple;
- bool start_inclusive;
- bool end_inclusive;
+ ranges.emplace_back(range_type(
+ read_bound(statements::bound::START),
+ read_bound(statements::bound::END)));
- read_bounds(start_tuple, start_inclusive, statements::bound::START);
- read_bounds(end_tuple, end_inclusive, statements::bound::END);
- ranges.emplace_back(query::range(std::move(start_tuple), std::move(end_tuple),
- start_inclusive, end_inclusive));
if (def->type->is_reversed()) {
ranges.back().reverse();
}
@@ -239,7 +228,7 @@ public:
ranges.reserve(cartesian_product_size(vec_of_values));
for (auto&& prefix : make_cartesian_product(vec_of_values)) {
- ranges.emplace_back(query::range::make_singular(_tuple->serialize_value(prefix)));
+ ranges.emplace_back(range_type::make_singular(ValueType::from_exploded(*_schema, prefix)));
}
return std::move(ranges);
diff --git a/cql3/restrictions/statement_restrictions.hh b/cql3/restrictions/statement_restrictions.hh
index 7b9df469de..272c960f51 100644
--- a/cql3/restrictions/statement_restrictions.hh
+++ b/cql3/restrictions/statement_restrictions.hh
@@ -50,12 +50,12 @@ private:
/**
* Restrictions on partitioning columns
*/
- ::shared_ptr _partition_key_restrictions;
+ ::shared_ptr> _partition_key_restrictions;
/**
* Restrictions on clustering columns
*/
- ::shared_ptr _clustering_columns_restrictions;
+ ::shared_ptr> _clustering_columns_restrictions;
/**
* Restriction on non-primary key columns (i.e. secondary index restrictions)
@@ -212,14 +212,12 @@ private:
auto& def = restriction->get_column_def();
if (def.is_partition_key()) {
if (!_partition_key_restrictions) {
- _partition_key_restrictions = ::make_shared(_schema,
- _schema->partition_key_prefix_type);
+ _partition_key_restrictions = ::make_shared>(_schema);
}
_partition_key_restrictions->merge_with(restriction);
} else if (def.is_clustering_key()) {
if (!_clustering_columns_restrictions) {
- _clustering_columns_restrictions = ::make_shared(_schema,
- _schema->clustering_key_prefix_type);
+ _clustering_columns_restrictions = ::make_shared>(_schema);
}
_clustering_columns_restrictions->merge_with(restriction);
} else {
@@ -383,9 +381,9 @@ public:
* @return the specified bound of the partition key
* @throws InvalidRequestException if the boundary cannot be retrieved
*/
- std::vector get_partition_key_ranges(const query_options& options) const {
+ std::vector get_partition_key_ranges(const query_options& options) const {
if (!_partition_key_restrictions) {
- return {query::range::make_open_ended_both_sides()};
+ return {query::partition_range::make_open_ended_both_sides()};
}
return _partition_key_restrictions->bounds(options);
}
@@ -510,9 +508,9 @@ public:
#endif
public:
- std::vector get_clustering_bounds(const query_options& options) const {
+ std::vector get_clustering_bounds(const query_options& options) const {
if (!_clustering_columns_restrictions) {
- return {query::range::make_open_ended_both_sides()};
+ return {query::clustering_range::make_open_ended_both_sides()};
}
return _clustering_columns_restrictions->bounds(options);
}
@@ -559,7 +557,8 @@ public:
void reverse() {
if (_clustering_columns_restrictions) {
- _clustering_columns_restrictions = ::make_shared(_clustering_columns_restrictions);
+ _clustering_columns_restrictions = ::make_shared>(
+ _clustering_columns_restrictions);
}
}
};
diff --git a/cql3/statements/modification_statement.cc b/cql3/statements/modification_statement.cc
index 36477325bd..62b3a32307 100644
--- a/cql3/statements/modification_statement.cc
+++ b/cql3/statements/modification_statement.cc
@@ -59,7 +59,6 @@ modification_statement::get_mutations(const query_options& options, bool local,
std::vector mutations;
mutations.reserve(keys->size());
for (auto key : *keys) {
- validation::validate_cql_key(s, key);
mutations.emplace_back(std::move(key), s);
auto& m = mutations.back();
this->add_update_for_key(m, *prefix, *params_ptr);
@@ -70,7 +69,7 @@ modification_statement::get_mutations(const query_options& options, bool local,
future>
modification_statement::make_update_parameters(
- lw_shared_ptr> keys,
+ lw_shared_ptr> keys,
lw_shared_ptr prefix,
const query_options& options,
bool local,
@@ -87,7 +86,7 @@ modification_statement::make_update_parameters(
future
modification_statement::read_required_rows(
- lw_shared_ptr> keys,
+ lw_shared_ptr> keys,
lw_shared_ptr prefix,
bool local,
db::consistency_level cl) {
@@ -181,7 +180,7 @@ modification_statement::create_clustering_prefix_internal(const query_options& o
components.push_back(val);
}
}
- return components;
+ return clustering_prefix(std::move(components));
}
clustering_prefix
@@ -222,9 +221,9 @@ modification_statement::create_clustering_prefix(const query_options& options) {
return create_clustering_prefix_internal(options);
}
-std::vector
+std::vector
modification_statement::build_partition_keys(const query_options& options) {
- std::vector result;
+ std::vector result;
std::vector components;
auto remaining = s->partition_key_size();
@@ -244,9 +243,9 @@ modification_statement::build_partition_keys(const query_options& options) {
throw exceptions::invalid_request_exception(sprint("Invalid null value for partition key part %s", def.name_as_text()));
}
components.push_back(val);
- partition_key key = serialize_value(*s->partition_key_type, components);
+ auto key = partition_key::one::from_exploded(*s, components);
validation::validate_cql_key(s, key);
- result.push_back(key);
+ result.emplace_back(std::move(key));
} else {
for (auto&& val : values) {
if (!val) {
@@ -256,9 +255,9 @@ modification_statement::build_partition_keys(const query_options& options) {
full_components.reserve(components.size() + 1);
auto i = std::copy(components.begin(), components.end(), std::back_inserter(full_components));
*i = val;
- partition_key key = serialize_value(*s->partition_key_type, full_components);
+ auto key = partition_key::one::from_exploded(*s, full_components);
validation::validate_cql_key(s, key);
- result.push_back(key);
+ result.emplace_back(std::move(key));
}
}
} else {
diff --git a/cql3/statements/modification_statement.hh b/cql3/statements/modification_statement.hh
index f573c61c74..2dd1a2288a 100644
--- a/cql3/statements/modification_statement.hh
+++ b/cql3/statements/modification_statement.hh
@@ -255,7 +255,7 @@ private:
public:
void add_key_value(column_definition& def, ::shared_ptr value);
void process_where_clause(std::vector where_clause, ::shared_ptr names);
- std::vector build_partition_keys(const query_options& options);
+ std::vector build_partition_keys(const query_options& options);
private:
clustering_prefix create_clustering_prefix(const query_options& options);
@@ -273,7 +273,7 @@ public:
protected:
future read_required_rows(
- lw_shared_ptr> keys,
+ lw_shared_ptr> keys,
lw_shared_ptr prefix,
bool local,
db::consistency_level cl);
@@ -427,7 +427,7 @@ private:
public:
future> make_update_parameters(
- lw_shared_ptr> keys,
+ lw_shared_ptr> keys,
lw_shared_ptr prefix,
const query_options& options,
bool local,
diff --git a/cql3/statements/select_statement.cc b/cql3/statements/select_statement.cc
index 61c20c763d..1c16aa5c77 100644
--- a/cql3/statements/select_statement.cc
+++ b/cql3/statements/select_statement.cc
@@ -126,7 +126,7 @@ select_statement::process_results(foreign_ptr> resu
for (auto&& e : results->partitions) {
// FIXME: deserialize into views
- auto key = _schema->partition_key_type->deserialize_value(e.first);
+ auto key = e.first.explode(*_schema);
auto& partition = e.second;
if (!partition.static_row.empty() && partition.rows.empty()
@@ -145,7 +145,7 @@ select_statement::process_results(foreign_ptr> resu
}
} else {
for (auto&& e : partition.rows) {
- auto c_key = _schema->clustering_key_type->deserialize_value(e.first);
+ auto c_key = e.first.explode(*_schema);
auto& cells = e.second.cells;
uint32_t static_id = 0;
uint32_t regular_id = 0;
diff --git a/cql3/update_parameters.hh b/cql3/update_parameters.hh
index 91a8a636fc..1c685964eb 100644
--- a/cql3/update_parameters.hh
+++ b/cql3/update_parameters.hh
@@ -36,7 +36,7 @@ namespace cql3 {
class update_parameters final {
public:
using prefetched_rows_type = std::experimental::optional<
- std::unordered_map>;
+ std::unordered_map>;
private:
const gc_clock::duration _ttl;
const prefetched_rows_type _prefetched; // For operation that require a read-before-write
diff --git a/database.cc b/database.cc
index 3c531f3bd9..e79646bc66 100644
--- a/database.cc
+++ b/database.cc
@@ -82,17 +82,17 @@ schema::schema(sstring ks_name, sstring cf_name, std::vector partition_k
column_family::column_family(schema_ptr schema)
: _schema(std::move(schema))
- , partitions(key_compare(_schema->thrift.partition_key_type)) {
+ , partitions(partition_key::one::less_compare(*_schema)) {
}
mutation_partition*
-column_family::find_partition(const bytes& key) {
+column_family::find_partition(const partition_key::one& key) {
auto i = partitions.find(key);
return i == partitions.end() ? nullptr : &i->second;
}
row*
-column_family::find_row(const bytes& partition_key, const bytes& clustering_key) {
+column_family::find_row(const partition_key::one& partition_key, const clustering_key::one& clustering_key) {
mutation_partition* p = find_partition(partition_key);
if (!p) {
return nullptr;
@@ -101,19 +101,18 @@ column_family::find_row(const bytes& partition_key, const bytes& clustering_key)
}
mutation_partition&
-column_family::find_or_create_partition(const bytes& key) {
+column_family::find_or_create_partition(const partition_key::one& key) {
// call lower_bound so we have a hint for the insert, just in case.
auto i = partitions.lower_bound(key);
- if (i == partitions.end() || key != i->first) {
+ if (i == partitions.end() || !key.equal(*_schema, i->first)) {
i = partitions.emplace_hint(i, std::make_pair(std::move(key), mutation_partition(_schema)));
}
return i->second;
}
row&
-column_family::find_or_create_row(const bytes& partition_key, const bytes& clustering_key) {
+column_family::find_or_create_row(const partition_key::one& partition_key, const clustering_key::one& clustering_key) {
mutation_partition& p = find_or_create_partition(partition_key);
- // call lower_bound so we have a hint for the insert, just in case.
return p.clustered_row(clustering_key);
}
@@ -313,6 +312,15 @@ keyspace::find_schema(const sstring& cf_name) {
return cf->_schema;
}
+schema_ptr database::find_schema(const sstring& ks_name, const sstring& cf_name) {
+ auto ks = find_keyspace(ks_name);
+ if (!ks) {
+ return {};
+ }
+
+ return ks->find_schema(cf_name);
+}
+
keyspace*
database::find_keyspace(const sstring& name) {
auto i = keyspaces.find(name);
@@ -364,12 +372,17 @@ merge_column(const column_definition& def,
}
}
+mutation_partition::~mutation_partition() {
+ _rows.clear_and_dispose(std::default_delete());
+ _row_tombstones.clear_and_dispose(std::default_delete());
+}
+
void
mutation_partition::apply(schema_ptr schema, const mutation_partition& p) {
_tombstone.apply(p._tombstone);
- for (auto&& entry : p._row_tombstones) {
- apply_row_tombstone(schema, entry);
+ for (auto&& e : p._row_tombstones) {
+ apply_row_tombstone(schema, e.prefix(), e.t());
}
auto merge_cells = [this, schema] (row& old_row, const row& new_row, auto&& find_column_def) {
@@ -392,63 +405,103 @@ mutation_partition::apply(schema_ptr schema, const mutation_partition& p) {
merge_cells(_static_row, p._static_row, find_static_column_def);
for (auto&& entry : p._rows) {
- auto& key = entry.first;
- auto i = _rows.find(key);
+ auto& key = entry.key();
+ auto i = _rows.find(key, rows_entry::compare(*schema));
if (i == _rows.end()) {
- _rows.emplace_hint(i, entry);
+ auto e = new rows_entry(entry);
+ _rows.insert(i, *e);
} else {
- i->second.t.apply(entry.second.t);
- merge_cells(i->second.cells, entry.second.cells, find_regular_column_def);
+ i->apply(entry.row().t);
+ merge_cells(i->row().cells, entry.row().cells, find_regular_column_def);
}
}
}
tombstone
-mutation_partition::tombstone_for_row(schema_ptr schema, const clustering_key& key) {
+mutation_partition::tombstone_for_row(schema_ptr schema, const clustering_key::one& key) {
tombstone t = _tombstone;
- auto i = _row_tombstones.lower_bound(key);
- if (i != _row_tombstones.end() && schema->clustering_key_prefix_type->is_prefix_of(i->first, key)) {
- t.apply(i->second);
+ auto c = row_tombstones_entry::key_comparator(
+ clustering_key::one::prefix_view_type::less_compare_with_prefix(*schema));
+
+ // _row_tombstones contains only strict prefixes
+ for (unsigned prefix_len = 1; prefix_len < schema->clustering_key_size(); ++prefix_len) {
+ auto i = _row_tombstones.find(key.prefix_view(*schema, prefix_len), c);
+ if (i != _row_tombstones.end()) {
+ t.apply(i->t());
+ }
}
- auto j = _rows.find(key);
+ auto j = _rows.find(key, rows_entry::compare(*schema));
if (j != _rows.end()) {
- t.apply(j->second.t);
+ t.apply(j->row().t);
}
return t;
}
void
-mutation_partition::apply_row_tombstone(schema_ptr schema, std::pair row_tombstone) {
- auto& prefix = row_tombstone.first;
- auto i = _row_tombstones.lower_bound(prefix);
- if (i == _row_tombstones.end() || !schema->clustering_key_prefix_type->equal(prefix, i->first)) {
- _row_tombstones.emplace_hint(i, std::move(row_tombstone));
- } else if (row_tombstone.second > i->second) {
- i->second = row_tombstone.second;
+mutation_partition::apply_row_tombstone(schema_ptr schema, clustering_key::prefix::one prefix, tombstone t) {
+ assert(!prefix.is_full(*schema));
+ auto i = _row_tombstones.lower_bound(prefix, row_tombstones_entry::compare(*schema));
+ if (i == _row_tombstones.end() || !prefix.equal(*schema, i->prefix())) {
+ auto e = new row_tombstones_entry(std::move(prefix), t);
+ _row_tombstones.insert(i, *e);
+ } else {
+ i->apply(t);
}
}
void
mutation_partition::apply_delete(schema_ptr schema, const clustering_prefix& prefix, tombstone t) {
- if (prefix.empty()) {
+ if (!prefix) {
apply(t);
- } else if (prefix.size() == schema->clustering_key_size()) {
- _rows[schema->clustering_key_type->serialize_value(prefix)].t.apply(t);
+ } else if (prefix.is_full(*schema)) {
+ apply_delete(schema, clustering_key::one::from_clustering_prefix(*schema, prefix), t);
} else {
- apply_row_tombstone(schema, {schema->clustering_key_prefix_type->serialize_value(prefix), t});
+ apply_row_tombstone(schema, clustering_key::prefix::one::from_clustering_prefix(*schema, prefix), t);
}
}
+void
+mutation_partition::apply_delete(schema_ptr schema, clustering_key::one&& key, tombstone t) {
+ auto i = _rows.lower_bound(key, rows_entry::compare(*schema));
+ if (i == _rows.end() || !i->key().equal(*schema, key)) {
+ auto e = new rows_entry(std::move(key));
+ e->row().apply(t);
+ _rows.insert(i, *e);
+ } else {
+ i->row().apply(t);
+ }
+}
+
+rows_entry*
+mutation_partition::find_entry(schema_ptr schema, const clustering_key::prefix::one& key) {
+ auto i = _rows.find(key, rows_entry::compare_prefix(*schema));
+ if (i == _rows.end()) {
+ return nullptr;
+ }
+ return &*i;
+}
+
row*
-mutation_partition::find_row(const clustering_key& key) {
+mutation_partition::find_row(const clustering_key::one& key) {
auto i = _rows.find(key);
if (i == _rows.end()) {
return nullptr;
}
- return &i->second.cells;
+ return &i->row().cells;
+}
+
+row&
+mutation_partition::clustered_row(const clustering_key::one& key) {
+ auto i = _rows.find(key);
+ if (i == _rows.end()) {
+ auto e = new rows_entry(key);
+ _rows.insert(i, *e);
+ return e->row().cells;
+ }
+ return i->row().cells;
}
bool column_definition::is_compact_value() const {
@@ -457,7 +510,7 @@ bool column_definition::is_compact_value() const {
}
std::ostream& operator<<(std::ostream& os, const mutation& m) {
- return fprint(os, "{mutation: schema %p key %s data %s}", m.schema.get(), m.key, m.p);
+ return fprint(os, "{mutation: schema %p key %s data %s}", m.schema.get(), static_cast(m.key), m.p);
}
std::ostream& operator<<(std::ostream& os, const mutation_partition& mp) {
@@ -475,24 +528,27 @@ column_family::get_partition_slice(mutation_partition& partition, const query::p
if (!range.is_singular()) {
fail(unimplemented::cause::RANGE_QUERIES);
}
- auto& key = range.start();
- if (!_schema->clustering_key_prefix_type->is_full(key)) {
+ auto& key = range.start_value();
+ if (!key.is_full(*_schema)) {
fail(unimplemented::cause::RANGE_QUERIES);
}
- auto row = partition.find_row(key);
+
+ rows_entry* row = partition.find_entry(_schema, key);
if (!row) {
continue;
}
+ auto&& cells = &row->row().cells;
+
// FIXME: handle removed rows properly. In CQL rows are separate entities (can be live or dead).
- auto row_tombstone = partition.tombstone_for_row(_schema, key);
+ auto row_tombstone = partition.tombstone_for_row(_schema, row->key());
query::result::row result_row;
result_row.cells.reserve(slice.regular_columns.size());
for (auto id : slice.regular_columns) {
- auto i = row->find(id);
- if (i == row->end()) {
+ auto i = cells->find(id);
+ if (i == cells->end()) {
result_row.cells.emplace_back();
} else {
auto def = _schema->regular_column_at(id);
@@ -510,7 +566,7 @@ column_family::get_partition_slice(mutation_partition& partition, const query::p
}
}
}
- result.rows.emplace_back(key, std::move(result_row));
+ result.rows.emplace_back(row->key(), std::move(result_row));
--limit;
}
@@ -532,10 +588,7 @@ column_family::query(const query::read_command& cmd) {
uint32_t limit = cmd.row_limit;
for (auto&& range : cmd.partition_ranges) {
if (range.is_singular()) {
- auto& key = range.start();
- if (!_schema->partition_key_prefix_type->is_full(key)) {
- fail(unimplemented::cause::RANGE_QUERIES);
- }
+ auto& key = range.start_value();
auto partition = find_partition(key);
if (!partition) {
return make_ready_future>(result);
diff --git a/database.hh b/database.hh
index ebc650b473..486ca42788 100644
--- a/database.hh
+++ b/database.hh
@@ -19,7 +19,6 @@
#include
#include