diff --git a/db/view/view.cc b/db/view/view.cc index 426debcc4c..48bebe0b15 100644 --- a/db/view/view.cc +++ b/db/view/view.cc @@ -40,6 +40,7 @@ */ #include +#include #include "clustering_bounds_comparator.hh" #include "cql3/statements/select_statement.hh" @@ -124,6 +125,15 @@ bool view::may_be_affected_by(const ::schema& base, const dht::decorated_key& ke return affected; } +bool view::matches_view_filter(const ::schema& base, const partition_key& key, const clustering_row& update, gc_clock::time_point now) const { + return clustering_prefix_matches(base, key, update.key()) && + boost::algorithm::all_of( + select_statement().get_restrictions()->get_non_pk_restriction() | boost::adaptors::map_values, + [&] (auto&& r) { + return r->is_satisfied_by(base, key, update.key(), update.cells(), cql3::query_options({ }), now); + }); +} + } // namespace view } // namespace db diff --git a/db/view/view.hh b/db/view/view.hh index 0a9ab3f26c..7d0c1bd82d 100644 --- a/db/view/view.hh +++ b/db/view/view.hh @@ -22,6 +22,7 @@ #pragma once #include "dht/i_partitioner.hh" +#include "gc_clock.hh" #include "query-request.hh" #include "schema.hh" #include "stdx.hh" @@ -81,6 +82,23 @@ public: */ bool may_be_affected_by(const ::schema& base, const dht::decorated_key& key, const rows_entry& update) const; + /** + * Whether a given base row matches the view filter (and thus if the view should have a corresponding entry). + * + * Note that this differs from may_be_affected_by in that the provide row must be the current + * state of the base row, not just some updates to it. This function also has no false positive: a base + * row either does or doesn't match the view filter. + * + * Also note that this function doesn't check the partition key, as it assumes the upper layers + * have already filtered out the views that are not affected. + * + * @param base the base table schema. + * @param key the partition key that is updated. + * @param update the current state of a particular base row. + * @param now the current time in seconds (to decide what is live and what isn't). + * @return whether the base row matches the view filter. + */ + bool matches_view_filter(const ::schema& base, const partition_key& key, const clustering_row& update, gc_clock::time_point now) const; private: cql3::statements::select_statement& select_statement() const; const query::partition_slice& partition_slice() const;