diff --git a/cql3/restrictions/statement_restrictions.cc b/cql3/restrictions/statement_restrictions.cc index 5d1fcf7d1d..0f395cb501 100644 --- a/cql3/restrictions/statement_restrictions.cc +++ b/cql3/restrictions/statement_restrictions.cc @@ -636,19 +636,6 @@ void error_if_exceeds(size_t size, size_t limit) { /// Computes partition-key ranges from expressions, which contains EQ/IN for every partition column. dht::partition_range_vector partition_ranges_from_singles( const std::vector& expressions, const query_options& options, const schema& schema) { - if (std::ranges::all_of(expressions, [] (const expression& e) { return find(e, oper_t::EQ); })) { - // Special case to avoid a vector of vectors, which makes for a couple of extra allocations per request. - std::vector pk_value(schema.partition_key_size()); - for (const auto& e : expressions) { - const auto col = std::get(find(e, oper_t::EQ)->lhs).col; - const auto vals = std::get(possible_lhs_values(col, e, options)); - if (vals.empty()) { // Case of C=1 AND C=2. - return {}; - } - pk_value[schema.position(*col)] = std::move(vals[0]); - } - return {range_from_bytes(schema, pk_value)}; - } const size_t size_limit = options.get_cql_config().restrictions.partition_key_restrictions_max_cartesian_product_size; // Each element is a vector of that column's possible values: @@ -679,6 +666,22 @@ dht::partition_range_vector partition_ranges_from_singles( return ranges; } +/// Computes partition-key ranges from EQ restrictions on each partition column. Returns a single singleton range if +/// the EQ restrictions are not mutually conflicting. Otherwise, returns an empty vector. +dht::partition_range_vector partition_ranges_from_EQs( + const std::vector& eq_expressions, const query_options& options, const schema& schema) { + std::vector pk_value(schema.partition_key_size()); + for (const auto& e : eq_expressions) { + const auto col = std::get(find(e, oper_t::EQ)->lhs).col; + const auto vals = std::get(possible_lhs_values(col, e, options)); + if (vals.empty()) { // Case of C=1 AND C=2. + return {}; + } + pk_value[schema.position(*col)] = std::move(vals[0]); + } + return {range_from_bytes(schema, pk_value)}; +} + } // anonymous namespace dht::partition_range_vector statement_restrictions::get_partition_key_ranges(const query_options& options) const { @@ -692,6 +695,9 @@ dht::partition_range_vector statement_restrictions::get_partition_key_ranges(con format("Unexpected size of token restrictions: {}", _partition_range_restrictions.size())); } return partition_ranges_from_token(_partition_range_restrictions[0], options); + } else if (_partition_range_is_simple) { + // Special case to avoid extra allocations required for a Cartesian product. + return partition_ranges_from_EQs(_partition_range_restrictions, options, *_schema); } return partition_ranges_from_singles(_partition_range_restrictions, options, *_schema); }