From 7df0c873aab3a26bd28d67ace7d2a6f5dbd2f2dc Mon Sep 17 00:00:00 2001 From: Eliran Sinvani Date: Tue, 5 Mar 2019 13:46:15 +0200 Subject: [PATCH] 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 --- cql3/statements/select_statement.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/cql3/statements/select_statement.cc b/cql3/statements/select_statement.cc index a2eb292a09..9c8edae9d9 100644 --- a/cql3/statements/select_statement.cc +++ b/cql3/statements/select_statement.cc @@ -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());