From f7b7724eaf09ac9c5212cea9594ee13825673532 Mon Sep 17 00:00:00 2001 From: Piotr Dulikowski Date: Thu, 28 Jul 2022 18:49:09 +0200 Subject: [PATCH] db/view: base_dependent_view_info: split non-pk columns into regular and static Currently, `base_dependent_view_info::_base_non_pk_columns_in_view_pk` field keeps a list of non-primary-key columns from the base table which are a part of the view's primary key. Because the current code does not allow indexes on static columns yet, the columns kept in the aforementioned field are always assumed to be regular columns of the base table and are kept as `column_id`s which do not contain information about the column kind. This commit splits the `_base_non_pk_columns_in_view_pk` field into two, one for regular columns and the other for static columns, so that it is possible to keep both kinds of columns in `base_dependent_view_info` and the structure can be used for secondary indexes on static columns. --- db/view/view.cc | 41 ++++++++++++++++++++++++++++------------- db/view/view.hh | 10 +++++++--- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/db/view/view.cc b/db/view/view.cc index b54ff2e9f1..06cecc4cd1 100644 --- a/db/view/view.cc +++ b/db/view/view.cc @@ -135,10 +135,13 @@ void view_info::set_base_info(db::view::base_info_ptr base_info) { } // A constructor for a base info that can facilitate reads and writes from the materialized view. -db::view::base_dependent_view_info::base_dependent_view_info(schema_ptr base_schema, std::vector&& base_non_pk_columns_in_view_pk) +db::view::base_dependent_view_info::base_dependent_view_info(schema_ptr base_schema, + std::vector&& base_regular_columns_in_view_pk, + std::vector&& base_static_columns_in_view_pk) : _base_schema{std::move(base_schema)} - , _base_non_pk_columns_in_view_pk{std::move(base_non_pk_columns_in_view_pk)} - , has_base_non_pk_columns_in_view_pk{!_base_non_pk_columns_in_view_pk.empty()} + , _base_regular_columns_in_view_pk{std::move(base_regular_columns_in_view_pk)} + , _base_static_columns_in_view_pk{std::move(base_static_columns_in_view_pk)} + , has_base_non_pk_columns_in_view_pk{!_base_regular_columns_in_view_pk.empty() || !_base_static_columns_in_view_pk.empty()} , use_only_for_reads{false} { } @@ -151,13 +154,22 @@ db::view::base_dependent_view_info::base_dependent_view_info(bool has_base_non_p , use_only_for_reads{true} { } -const std::vector& db::view::base_dependent_view_info::base_non_pk_columns_in_view_pk() const { +const std::vector& db::view::base_dependent_view_info::base_regular_columns_in_view_pk() const { if (use_only_for_reads) { on_internal_error(vlogger, - format("base_non_pk_columns_in_view_pk(): operation unsupported when initialized only for view reads. " + format("base_regular_columns_in_view_pk(): operation unsupported when initialized only for view reads. " "Missing column in the base table: {}", to_sstring_view(_column_missing_in_base.value_or(bytes())))); } - return _base_non_pk_columns_in_view_pk; + return _base_regular_columns_in_view_pk; +} + +const std::vector& db::view::base_dependent_view_info::base_static_columns_in_view_pk() const { + if (use_only_for_reads) { + on_internal_error(vlogger, + format("base_static_columns_in_view_pk(): operation unsupported when initialized only for view reads. " + "Missing column in the base table: {}", to_sstring_view(_column_missing_in_base.value_or(bytes())))); + } + return _base_static_columns_in_view_pk; } const schema_ptr& db::view::base_dependent_view_info::base_schema() const { @@ -170,7 +182,8 @@ const schema_ptr& db::view::base_dependent_view_info::base_schema() const { } db::view::base_info_ptr view_info::make_base_dependent_view_info(const schema& base) const { - std::vector base_non_pk_columns_in_view_pk; + std::vector base_regular_columns_in_view_pk; + std::vector base_static_columns_in_view_pk; for (auto&& view_col : boost::range::join(_schema.partition_key_columns(), _schema.clustering_key_columns())) { if (view_col.is_computed()) { @@ -182,8 +195,10 @@ db::view::base_info_ptr view_info::make_base_dependent_view_info(const schema& b } const bytes& view_col_name = view_col.name(); auto* base_col = base.get_column_definition(view_col_name); - if (base_col && !base_col->is_primary_key()) { - base_non_pk_columns_in_view_pk.push_back(base_col->id); + if (base_col && base_col->is_regular()) { + base_regular_columns_in_view_pk.push_back(base_col->id); + } else if (base_col && base_col->is_static()) { + base_static_columns_in_view_pk.push_back(base_col->id); } else if (!base_col) { vlogger.error("Column {} in view {}.{} was not found in the base table {}.{}", to_sstring_view(view_col_name), _schema.ks_name(), _schema.cf_name(), base.ks_name(), base.cf_name()); @@ -202,7 +217,7 @@ db::view::base_info_ptr view_info::make_base_dependent_view_info(const schema& b } } - return make_lw_shared(base.shared_from_this(), std::move(base_non_pk_columns_in_view_pk)); + return make_lw_shared(base.shared_from_this(), std::move(base_regular_columns_in_view_pk), std::move(base_static_columns_in_view_pk)); } bool view_info::has_base_non_pk_columns_in_view_pk() const { @@ -482,7 +497,7 @@ row_marker view_updates::compute_row_marker(const clustering_row& base_row) cons // they share liveness information. It's true especially in the only case currently allowed by CQL, // which assumes there's up to one non-pk column in the view key. It's also true in alternator, // which does not carry TTL information. - const auto& col_ids = _base_info->base_non_pk_columns_in_view_pk(); + const auto& col_ids = _base_info->base_regular_columns_in_view_pk(); if (!col_ids.empty()) { auto& def = _base->regular_column_at(col_ids[0]); // Note: multi-cell columns can't be part of the primary key. @@ -864,7 +879,7 @@ void view_updates::delete_old_entry(const partition_key& base_key, const cluster void view_updates::do_delete_old_entry(const partition_key& base_key, const clustering_row& existing, const clustering_row& update, gc_clock::time_point now) { auto view_rows = get_view_rows(base_key, existing, std::nullopt); for (const auto& [r, action] : view_rows) { - const auto& col_ids = _base_info->base_non_pk_columns_in_view_pk(); + const auto& col_ids = _base_info->base_regular_columns_in_view_pk(); if (_view_info.has_computed_column_depending_on_base_non_primary_key()) { if (auto ts_tag = std::get_if(&action)) { r->apply(ts_tag->into_shadowable_tombstone(now)); @@ -1040,7 +1055,7 @@ void view_updates::generate_update( return; } - const auto& col_ids = _base_info->base_non_pk_columns_in_view_pk(); + const auto& col_ids = _base_info->base_regular_columns_in_view_pk(); if (_view_info.has_computed_column_depending_on_base_non_primary_key()) { return update_entry_for_computed_column(base_key, update, existing, now); } diff --git a/db/view/view.hh b/db/view/view.hh index 09b08fd95a..831edbce0b 100644 --- a/db/view/view.hh +++ b/db/view/view.hh @@ -41,13 +41,15 @@ private: schema_ptr _base_schema; // Id of a regular base table column included in the view's PK, if any. // Scylla views only allow one such column, alternator can have up to two. - std::vector _base_non_pk_columns_in_view_pk; + std::vector _base_regular_columns_in_view_pk; + std::vector _base_static_columns_in_view_pk; // For tracing purposes, if the view is out of sync with its base table // and there exists a column which is not in base, its name is stored // and added to debug messages. std::optional _column_missing_in_base = {}; public: - const std::vector& base_non_pk_columns_in_view_pk() const; + const std::vector& base_regular_columns_in_view_pk() const; + const std::vector& base_static_columns_in_view_pk() const; const schema_ptr& base_schema() const; // Indicates if the view hase pk columns which are not part of the base @@ -62,7 +64,9 @@ public: const bool use_only_for_reads; // A constructor for a base info that can facilitate reads and writes from the materialized view. - base_dependent_view_info(schema_ptr base_schema, std::vector&& base_non_pk_columns_in_view_pk); + base_dependent_view_info(schema_ptr base_schema, + std::vector&& base_regular_columns_in_view_pk, + std::vector&& base_static_columns_in_view_pk); // A constructor for a base info that can facilitate only reads from the materialized view. base_dependent_view_info(bool has_base_non_pk_columns_in_view_pk, std::optional&& column_missing_in_base); };