view_info: Explicitly initialize base-dependent fields

Instead of lazily-initializing the regular base column in the view's
PK field, explicitly initialize it. This will be used by future
patches that don't have access to the schema when wanting to obtain
that column.

Signed-off-by: Duarte Nunes <duarte@scylladb.com>
This commit is contained in:
Duarte Nunes
2018-04-16 00:10:55 +01:00
parent b77b71436d
commit 31370fd7b1
3 changed files with 19 additions and 16 deletions

View File

@@ -4275,6 +4275,7 @@ static std::vector<view_ptr>::iterator find_view(std::vector<view_ptr>& views, c
}
void column_family::add_or_update_view(view_ptr v) {
v->view_info()->initialize_base_dependent_fields(*schema());
auto existing = find_view(_views, v);
if (existing != _views.end()) {
*existing = std::move(v);

View File

@@ -114,18 +114,19 @@ const column_definition* view_info::view_column(const schema& base, column_id ba
return _schema.get_column_definition(base.regular_column_at(base_id).name());
}
stdx::optional<column_id> view_info::base_non_pk_column_in_view_pk(const schema& base) const {
if (!_base_non_pk_column_in_view_pk) {
_base_non_pk_column_in_view_pk.emplace(stdx::nullopt);
for (auto&& view_col : boost::range::join(_schema.partition_key_columns(), _schema.clustering_key_columns())) {
auto* base_col = base.get_column_definition(view_col.name());
if (!base_col->is_primary_key()) {
_base_non_pk_column_in_view_pk.emplace(base_col->id);
break;
}
stdx::optional<column_id> view_info::base_non_pk_column_in_view_pk() const {
return _base_non_pk_column_in_view_pk;
}
void view_info::initialize_base_dependent_fields(const schema& base) {
for (auto&& view_col : boost::range::join(_schema.partition_key_columns(), _schema.clustering_key_columns())) {
auto* base_col = base.get_column_definition(view_col.name());
if (!base_col->is_primary_key()) {
_base_non_pk_column_in_view_pk.emplace(base_col->id);
break;
}
}
return *_base_non_pk_column_in_view_pk;
}
namespace db {
@@ -178,7 +179,7 @@ static bool update_requires_read_before_write(const schema& base,
// However, if the view has restrictions on regular columns, then a write that doesn't match those filters
// needs to add a tombstone (assuming a previous update matched those filter and created a view entry); for
// now we just do a read-before-write in that case.
if (!vf.base_non_pk_column_in_view_pk(base)
if (!vf.base_non_pk_column_in_view_pk()
&& vf.select_statement().get_restrictions()->get_non_pk_restriction().empty()) {
continue;
}
@@ -291,7 +292,7 @@ row_marker view_updates::compute_row_marker(const clustering_row& base_row) cons
*/
auto marker = base_row.marker();
auto col_id = _view_info.base_non_pk_column_in_view_pk(*_base);
auto col_id = _view_info.base_non_pk_column_in_view_pk();
if (col_id) {
// Note: multi-cell columns can't be part of the primary key.
auto cell = base_row.cells().cell_at(*col_id).as_atomic_cell();
@@ -463,7 +464,7 @@ void view_updates::generate_update(
return;
}
auto col_id = _view_info.base_non_pk_column_in_view_pk(*_base);
auto col_id = _view_info.base_non_pk_column_in_view_pk();
if (!col_id) {
// The view key is necessarily the same pre and post update.
if (existing && !existing->empty()) {

View File

@@ -33,8 +33,8 @@ class view_info final {
mutable shared_ptr<cql3::statements::select_statement> _select_statement;
mutable stdx::optional<query::partition_slice> _partition_slice;
mutable stdx::optional<dht::partition_range_vector> _partition_ranges;
// Lazily initializes the column id of a regular base table included in the view's PK, if any.
mutable stdx::optional<stdx::optional<column_id>> _base_non_pk_column_in_view_pk;
// Id of a regular base table column included in the view's PK, if any.
mutable stdx::optional<column_id> _base_non_pk_column_in_view_pk;
public:
view_info(const schema& schema, const raw_view_info& raw_view_info);
@@ -62,7 +62,8 @@ public:
const query::partition_slice& partition_slice() const;
const dht::partition_range_vector& partition_ranges() const;
const column_definition* view_column(const schema& base, column_id base_id) const;
stdx::optional<column_id> base_non_pk_column_in_view_pk(const schema& base) const;
stdx::optional<column_id> base_non_pk_column_in_view_pk() const;
void initialize_base_dependent_fields(const schema& base);
friend bool operator==(const view_info& x, const view_info& y) {
return x._raw == y._raw;