cql3: Ensure LIKE filtering for partition columns

Partition columns are implicitly filtered whenever possible, avoiding
expensive post-processing.  But there are exceptions, eg, when
partition key is only partially restricted, or for CONTAINS
expressions.  Here we add LIKE to this list of exceptions.

Also fix compute_bounds() to punt on LIKE restrictions, which cannot
be translated into meaningful bounds.

Signed-off-by: Dejan Mircevski <dejan@scylladb.com>
This commit is contained in:
Dejan Mircevski
2019-06-26 21:17:20 +02:00
parent 63cec653e5
commit 1c583de8bb
4 changed files with 19 additions and 2 deletions

View File

@@ -82,6 +82,10 @@ public:
return false;
}
virtual bool is_LIKE() const {
return false;
}
virtual bool has_bound(statements::bound b) const override {
return true;
}

View File

@@ -91,7 +91,8 @@ public:
}
virtual bool needs_filtering(const schema& schema) const {
return !empty() && !is_on_token() && (has_unrestricted_components(schema) || is_contains() || is_slice());
return !empty() && !is_on_token() &&
(has_unrestricted_components(schema) || is_contains() || is_slice() || is_LIKE());
}
// NOTICE(sarna): This function is useless for partition key restrictions,

View File

@@ -72,6 +72,7 @@ private:
bool _slice;
bool _contains;
bool _in;
bool _like;
public:
single_column_primary_key_restrictions(schema_ptr schema, bool allow_filtering)
: _schema(schema)
@@ -80,6 +81,7 @@ public:
, _slice(false)
, _contains(false)
, _in(false)
, _like(false)
{ }
// Convert another primary key restrictions type into this type, possibly using different schema
@@ -91,6 +93,7 @@ public:
, _slice(other._slice)
, _contains(other._contains)
, _in(other._in)
, _like(other._like)
{
for (const auto& entry : other._restrictions->restrictions()) {
const column_definition* other_cdef = entry.first;
@@ -123,6 +126,10 @@ public:
return _in;
}
virtual bool is_LIKE() const override {
return _like;
}
virtual bool is_all_eq() const override {
return _restrictions->is_all_eq();
}
@@ -160,6 +167,7 @@ public:
_slice |= restriction->is_slice();
_in |= restriction->is_IN();
_contains |= restriction->is_contains();
_like |= restriction->is_LIKE();
_restrictions->add_restriction(restriction);
}
@@ -264,7 +272,7 @@ private:
const column_definition* def = e.first;
auto&& r = e.second;
if (vec_of_values.size() != _schema->position(*def) || r->is_contains()) {
if (vec_of_values.size() != _schema->position(*def) || r->is_contains() || r->is_LIKE()) {
// The prefixes built so far are the longest we can build,
// the rest of the constraints will have to be applied using filtering.
break;

View File

@@ -415,6 +415,10 @@ public:
return index.supports_expression(_column_def, cql3::operator_type::LIKE);
}
virtual bool is_LIKE() const override {
return true;
}
virtual sstring to_string() const override {
return format("LIKE({})", _value->to_string());
}