From 88bd5ea1b77ca72c77264ebc31f970a52fd5b150 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 15 Mar 2026 12:44:44 +0200 Subject: [PATCH] cql3: statement_restrictions: track clustering-has-slice incrementally Replace has_slice(_clustering_columns_restrictions), which walks the accumulated expression tree looking for slice operators, with a local bool ck_has_slice set when any clustering predicate with is_slice is added. Updated at all three clustering insertion points: multi-column first assignment, multi-column slice conjunction, and single-column conjunction. --- cql3/restrictions/statement_restrictions.cc | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cql3/restrictions/statement_restrictions.cc b/cql3/restrictions/statement_restrictions.cc index ee51b466a0..2b03356dfd 100644 --- a/cql3/restrictions/statement_restrictions.cc +++ b/cql3/restrictions/statement_restrictions.cc @@ -1385,6 +1385,7 @@ statement_restrictions::statement_restrictions(private_tag, bool ck_is_empty = true; bool has_mc_clustering = false; + bool ck_has_slice = false; for (auto& pred : predicates) { if (pred.is_not_null_single_column) { auto* col = require_on_single_column(pred); @@ -1399,6 +1400,9 @@ statement_restrictions::statement_restrictions(private_tag, _clustering_columns_restrictions = pred.filter; ck_is_empty = false; has_mc_clustering = true; + if (pred.is_slice) { + ck_has_slice = true; + } } else { if (!has_mc_clustering) { @@ -1412,7 +1416,7 @@ statement_restrictions::statement_restrictions(private_tag, throw exceptions::invalid_request_exception(format("{} cannot be restricted by more than one relation if it includes a IN", expr::get_columns_in_commons(_clustering_columns_restrictions, pred.filter))); } else if (pred.is_slice) { - if (!expr::has_slice(_clustering_columns_restrictions)) { + if (!ck_has_slice) { throw exceptions::invalid_request_exception(format("Column \"{}\" cannot be restricted by both an equality and an inequality relation", expr::get_columns_in_commons(_clustering_columns_restrictions, pred.filter))); } @@ -1447,6 +1451,7 @@ statement_restrictions::statement_restrictions(private_tag, } _clustering_columns_restrictions = expr::make_conjunction(_clustering_columns_restrictions, pred.filter); + ck_has_slice = true; } else { throw exceptions::invalid_request_exception(format("Unsupported multi-column relation: ", pred.filter)); } @@ -1495,7 +1500,7 @@ statement_restrictions::statement_restrictions(private_tag, const column_definition* last_column = expr::get_last_column_def(_clustering_columns_restrictions); if (last_column != nullptr && !allow_filtering) { - if (has_slice(_clustering_columns_restrictions) && schema->position(*new_column) > schema->position(*last_column)) { + if (ck_has_slice && schema->position(*new_column) > schema->position(*last_column)) { throw exceptions::invalid_request_exception(format("Clustering column \"{}\" cannot be restricted (preceding column \"{}\" is restricted by a non-EQ relation)", new_column->name_as_text(), last_column->name_as_text())); } @@ -1510,6 +1515,9 @@ statement_restrictions::statement_restrictions(private_tag, _clustering_columns_restrictions = expr::make_conjunction(_clustering_columns_restrictions, pred.filter); ck_is_empty = false; + if (pred.is_slice) { + ck_has_slice = true; + } } else { _nonprimary_key_restrictions = expr::make_conjunction(_nonprimary_key_restrictions, pred.filter); }