transport: sort bound ranges in read reques in order to conform to cql definitions

According to the cql definitions, if no ORDER BY clause is present,
records should be returned ordered by the clustering keys. Since the
backend returns the ranges according to their order of appearance
in the request, the bounds should be sorted before sending it to the
backend. This kind of sorting is needed in queries that generates more
than one bound to be read, examples to such queris are:
1. a SELECT query with an IN clause.
2. a SELECT query on a mixed order tupple of columns (see #2050).
The assumption this commit makes is the correctness of the bounds
list, that is, the bounds are non overlapping. If this wasn't true, multiple
occurences of the same reccord could have returned for certain queries.

Tests:
1. Unit tests release
2. All dtest that requires #2050 and #2029

Fixes #2029

Signed-off-by: Eliran Sinvani <eliransin@scylladb.com>
This commit is contained in:
Eliran Sinvani
2019-03-05 13:46:15 +02:00
parent da0a25859b
commit 7df0c873aa

View File

@@ -220,7 +220,14 @@ select_statement::make_partition_slice(const query_options& options)
std::move(static_columns), {}, _opts, nullptr, options.get_cql_serialization_format());
}
auto bounds = _restrictions->get_clustering_bounds(options);
auto bounds =_restrictions->get_clustering_bounds(options);
if (bounds.size() > 1) {
auto comparer = position_in_partition::less_compare(*_schema);
auto bounds_sorter = [&comparer] (const query::clustering_range& lhs, const query::clustering_range& rhs) {
return comparer(position_in_partition_view::for_range_start(lhs), position_in_partition_view::for_range_start(rhs));
};
std::sort(bounds.begin(), bounds.end(), bounds_sorter);
}
if (_is_reversed) {
_opts.set(query::partition_slice::option::reversed);
std::reverse(bounds.begin(), bounds.end());