mirror of
https://github.com/scylladb/scylladb.git
synced 2026-06-01 04:26:48 +00:00
cql3/restrictions: Complete implementation of is_satisfied_by()
This patch implements the is_satisfied_by() function for the remaining types of restrictions, lifting the function declaration to abstract_restrictions. Signed-off-by: Duarte Nunes <duarte@scylladb.com>
This commit is contained in:
@@ -94,6 +94,26 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the specified row satisfied this restriction.
|
||||
* Assumes the row is live, but not all cells. If a cell
|
||||
* isn't live and there's a restriction on its column,
|
||||
* then the function returns false.
|
||||
*
|
||||
* @param schema the schema the row belongs to
|
||||
* @param key the partition key
|
||||
* @param ckey the clustering key
|
||||
* @param cells the remaining row columns
|
||||
* @return the restriction resulting of the merge
|
||||
* @throws InvalidRequestException if the restrictions cannot be merged
|
||||
*/
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const = 0;
|
||||
|
||||
protected:
|
||||
#if 0
|
||||
protected static ByteBuffer validateIndexedValue(ColumnSpecification columnSpec,
|
||||
|
||||
@@ -85,6 +85,20 @@ public:
|
||||
do_merge_with(as_pkr);
|
||||
}
|
||||
|
||||
bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const override {
|
||||
for (auto&& range : bounds_ranges(options)) {
|
||||
if (!range.contains(ckey, clustering_key_prefix::prefix_equal_tri_compare(schema))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void do_merge_with(::shared_ptr<primary_key_restrictions<clustering_key_prefix>> other) = 0;
|
||||
|
||||
|
||||
@@ -336,6 +336,17 @@ public:
|
||||
sstring to_string() const override {
|
||||
return sprint("Restrictions(%s)", join(", ", get_column_defs()));
|
||||
}
|
||||
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const override {
|
||||
return boost::algorithm::all_of(
|
||||
_restrictions->restrictions() | boost::adaptors::map_values,
|
||||
[&] (auto&& r) { return r->is_satisfied_by(schema, key, ckey, cells, options, now); });
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -71,26 +71,6 @@ public:
|
||||
return _column_def;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the specified row satisfied this restriction.
|
||||
* Assumes the row is live, but not all cells. If a cell
|
||||
* isn't live and there's a restriction on its column,
|
||||
* then the function returns false.
|
||||
*
|
||||
* @param schema the schema the row belongs to
|
||||
* @param key the partition key
|
||||
* @param ckey the clustering key
|
||||
* @param cells the remaining row columns
|
||||
* @return the restriction resulting of the merge
|
||||
* @throws InvalidRequestException if the restrictions cannot be merged
|
||||
*/
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const = 0;
|
||||
|
||||
#if 0
|
||||
@Override
|
||||
public void addIndexExpressionTo(List<IndexExpression> expressions,
|
||||
|
||||
@@ -90,6 +90,14 @@ public:
|
||||
sstring to_string() const override {
|
||||
return "Initial restrictions";
|
||||
}
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const override {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
@@ -406,25 +414,34 @@ void statement_restrictions::validate_secondary_index_selections(bool selects_on
|
||||
}
|
||||
}
|
||||
|
||||
static bytes_view_opt do_get_value(const schema& schema,
|
||||
const column_definition& cdef,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
gc_clock::time_point now) {
|
||||
switch(cdef.kind) {
|
||||
case column_kind::partition_key:
|
||||
return key.get_component(schema, cdef.component_index());
|
||||
case column_kind::clustering_key:
|
||||
return ckey.get_component(schema, cdef.component_index());
|
||||
default:
|
||||
auto cell = cells.find_cell(cdef.id);
|
||||
if (!cell) {
|
||||
return stdx::nullopt;
|
||||
}
|
||||
assert(cdef.is_atomic());
|
||||
auto c = cell->as_atomic_cell();
|
||||
return c.is_dead(now) ? stdx::nullopt : bytes_view_opt(c.value());
|
||||
}
|
||||
}
|
||||
|
||||
bytes_view_opt single_column_restriction::get_value(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
gc_clock::time_point now) const {
|
||||
switch(_column_def.kind) {
|
||||
case column_kind::partition_key:
|
||||
return key.get_component(schema, _column_def.component_index());
|
||||
case column_kind::clustering_key:
|
||||
return ckey.get_component(schema, _column_def.component_index());
|
||||
default:
|
||||
auto cell = cells.find_cell(_column_def.id);
|
||||
if (!cell) {
|
||||
return stdx::nullopt;
|
||||
}
|
||||
assert(_column_def.is_atomic());
|
||||
auto c = cell->as_atomic_cell();
|
||||
return c.is_dead(now) ? stdx::nullopt : bytes_view_opt(c.value());
|
||||
}
|
||||
return do_get_value(schema, _column_def, key, ckey, cells, std::move(now));
|
||||
}
|
||||
|
||||
bool single_column_restriction::EQ::is_satisfied_by(const schema& schema,
|
||||
@@ -463,6 +480,23 @@ bool single_column_restriction::IN::is_satisfied_by(const schema& schema,
|
||||
});
|
||||
}
|
||||
|
||||
static query::range<bytes_view> to_range(const term_slice& slice, const query_options& options) {
|
||||
using range_type = query::range<bytes_view>;
|
||||
auto extract_bound = [&] (statements::bound bound) -> stdx::optional<range_type::bound> {
|
||||
if (!slice.has_bound(bound)) {
|
||||
return { };
|
||||
}
|
||||
auto value = slice.bound(bound)->bind_and_get(options);
|
||||
if (!value) {
|
||||
return { };
|
||||
}
|
||||
return { range_type::bound(*value, slice.is_inclusive(bound)) };
|
||||
};
|
||||
return range_type(
|
||||
extract_bound(statements::bound::START),
|
||||
extract_bound(statements::bound::END));
|
||||
}
|
||||
|
||||
bool single_column_restriction::slice::is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
@@ -476,26 +510,7 @@ bool single_column_restriction::slice::is_satisfied_by(const schema& schema,
|
||||
if (!cell_value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
using range_type = query::range<bytes_view>;
|
||||
auto extract_bound = [&] (statements::bound bound) -> stdx::optional<range_type::bound> {
|
||||
if (!_slice.has_bound(bound)) {
|
||||
return { };
|
||||
}
|
||||
auto value = _slice.bound(bound)->bind_and_get(options);
|
||||
if (!value) {
|
||||
return { };
|
||||
}
|
||||
return { range_type::bound(*value, _slice.is_inclusive(bound)) };
|
||||
};
|
||||
auto range = range_type(
|
||||
extract_bound(statements::bound::START),
|
||||
extract_bound(statements::bound::END));
|
||||
if (_column_def.type->is_reversed()) {
|
||||
range.reverse();
|
||||
}
|
||||
|
||||
return range.contains(*cell_value, _column_def.type->as_tri_comparator());
|
||||
return to_range(_slice, options).contains(*cell_value, _column_def.type->as_tri_comparator());
|
||||
}
|
||||
|
||||
bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
@@ -627,5 +642,46 @@ bool single_column_restriction::contains::is_satisfied_by(const schema& schema,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool token_restriction::EQ::is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const {
|
||||
bool satisfied = false;
|
||||
auto cdef = _column_definitions.begin();
|
||||
for (auto&& operand : values(options)) {
|
||||
if (operand) {
|
||||
auto cell_value = do_get_value(schema, **cdef, key, ckey, cells, now);
|
||||
satisfied = cell_value && (*cdef)->type->compare(*operand, *cell_value) == 0;
|
||||
}
|
||||
if (!satisfied) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return satisfied;
|
||||
}
|
||||
|
||||
bool token_restriction::slice::is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const {
|
||||
bool satisfied = false;
|
||||
auto range = to_range(_slice, options);
|
||||
for (auto* cdef : _column_definitions) {
|
||||
auto cell_value = do_get_value(schema, *cdef, key, ckey, cells, now);
|
||||
if (!cell_value) {
|
||||
return false;
|
||||
}
|
||||
satisfied = range.contains(*cell_value, cdef->type->as_tri_comparator());
|
||||
if (!satisfied) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return satisfied;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,13 @@ public:
|
||||
sstring to_string() const override {
|
||||
return sprint("EQ(%s)", _value->to_string());
|
||||
}
|
||||
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const override;
|
||||
};
|
||||
|
||||
class token_restriction::slice final : public token_restriction {
|
||||
@@ -246,6 +253,13 @@ public:
|
||||
sstring to_string() const override {
|
||||
return sprint("SLICE%s", _slice);
|
||||
}
|
||||
|
||||
virtual bool is_satisfied_by(const schema& schema,
|
||||
const partition_key& key,
|
||||
const clustering_key_prefix& ckey,
|
||||
const row& cells,
|
||||
const query_options& options,
|
||||
gc_clock::time_point now) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user