cql3: statement_restrictions: forbid querying a single-column inequality restriction on a multi-column restriction
CQL supports multi-column inequality restrictions in the form
(ck1, ck2, ck3) >= (:v1, :v2, :v3)
These restriction shape is only allowed on clustering keys, and
is translated into a partition_slice allowing the primary index
to efficiently select the part of the partition that satisfies the
restriction.
The possible_lhs_values() values function allows extracting
single-column restrictions from this and similar tuple restrictions.
For example, the multi-column restriction
(ck1, ck2, ck3) = (:v1, :v2, :v3)
implies that ck2 = :v2. If we have an index on ck2, and if we don't
further have a restriction on the partition key, then it is
advantageous to use the index to select rows, and then filter
on ck1 and ck3 to satisfy the full restriction.
For the inquality restriction, we can only infer a restriction on the
first column due to lexicographical comparison. We can see that, given
(ck1, ck2, ck3) >= (:v1, :v2, :v3)
then
ck1 >= :v1
ck2 = unbounded
ck3 = unbounded
and possible_lhs_values() indeed computes this.
However, this is never used in practice, and it makes further refactoring
difficult. If we want to convert an boolean factor of the where clause
to a predicate on a column or tuple of columns, we cannot do so because
we can actually generate two predicates: one on the tuple and one on the
first column.
Since it's not used, remove it.
This code was first introduced in d33053b841 ("cql3/restrictions: Add
free functions over new classes")
(search for "if (column_index_on_lhs > 0) {").
It does not directly correspond to pre-expression code.
Closes scylladb/scylladb#25757
This commit is contained in:
@@ -327,12 +327,10 @@ static value_set possible_lhs_values(const column_definition* cdef,
|
||||
if (oper.op == oper_t::EQ) {
|
||||
return value_list{std::move(*val)};
|
||||
}
|
||||
if (column_index_on_lhs > 0) {
|
||||
// A multi-column comparison restricts only the first column, because
|
||||
// comparison is lexicographical.
|
||||
return unbounded_value_set;
|
||||
}
|
||||
return to_range(oper.op, std::move(*val));
|
||||
// While an inequality like (ck1, ck2) >= (:v1, v2) implies that ck1 >= :v1 (but does
|
||||
// not imply an independent constrain on ck2), we can't make use of this constraint downstream.
|
||||
// We don't in fact call here when this happens, so just error out.
|
||||
on_internal_error(rlogger, "possible_lhs_values: trying to solve for single column on tuple inequality");
|
||||
} else if (oper.op == oper_t::IN) {
|
||||
return get_IN_values(oper.rhs, column_index_on_lhs, options, type->as_less_comparator());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user