Currently, the base_info may or may not be set in view schemas. Even when it's set, it may be modified. This necessitates extra checks when handling view schemas, as well as potentially causing errors when we forget to set it at some point. Instead, we want to make the base info an immutable member of view schemas (inside view_info). The first step towards that is making sure that all newly created schemas have the base info set. We achieve that by requiring a base schema when constructing a view schema. Unfortunately, this adds complexity each time we're making a view schema - we need to get the base schema as well. In most cases, the base schema is already available. The most problematic scenario is when we create a schema from mutations: - when parsing system tables we can get the schema from the database, as regular tables are parsed before views - when loading a view schema using the schema loader tool, we need to load the base additionally to the view schema, effectively doubling the work - when pulling the schema from another node - in this case we can only get the current version of the base schema from the local database Additionally, we need to consider the base schema version - when we generate view updates the version of the base schema used for reads should match the version of the base schema in view's base info. This is achieved by selecting the correct (old or new) schema in `db::schema_tables::merge_tables_and_views` and using the stored base schema in the schema_registry.
98 lines
4.1 KiB
C++
98 lines
4.1 KiB
C++
/*
|
|
* Copyright 2015-present ScyllaDB
|
|
*
|
|
* Modified by ScyllaDB
|
|
*/
|
|
|
|
/*
|
|
* SPDX-License-Identifier: (LicenseRef-ScyllaDB-Source-Available-1.0 and Apache-2.0)
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "cql3/attributes.hh"
|
|
#include "cql3/statements/schema_altering_statement.hh"
|
|
#include "cql3/statements/cf_prop_defs.hh"
|
|
#include "cql3/cql3_type.hh"
|
|
#include "cql3/column_identifier.hh"
|
|
#include "data_dictionary/data_dictionary.hh"
|
|
#include "timestamp.hh"
|
|
|
|
namespace cql3 {
|
|
|
|
class query_processor;
|
|
|
|
namespace statements {
|
|
|
|
class alter_table_statement : public schema_altering_statement {
|
|
public:
|
|
enum class type {
|
|
add,
|
|
alter,
|
|
drop,
|
|
opts,
|
|
rename,
|
|
};
|
|
using renames_type = std::vector<std::pair<shared_ptr<column_identifier::raw>,
|
|
shared_ptr<column_identifier::raw>>>;
|
|
struct column_change {
|
|
shared_ptr<column_identifier::raw> name;
|
|
shared_ptr<cql3_type::raw> validator = nullptr;
|
|
bool is_static = false;
|
|
};
|
|
|
|
class raw_statement;
|
|
private:
|
|
const uint32_t _bound_terms;
|
|
|
|
const type _type;
|
|
const std::vector<column_change> _column_changes;
|
|
const std::optional<cf_prop_defs> _properties;
|
|
const renames_type _renames;
|
|
const std::unique_ptr<attributes> _attrs;
|
|
public:
|
|
alter_table_statement(uint32_t bound_terms,
|
|
cf_name name,
|
|
type t,
|
|
std::vector<column_change> column_changes,
|
|
std::optional<cf_prop_defs> properties,
|
|
renames_type renames,
|
|
std::unique_ptr<attributes> attrs);
|
|
|
|
virtual uint32_t get_bound_terms() const override;
|
|
virtual future<> check_access(query_processor& qp, const service::client_state& state) const override;
|
|
virtual std::unique_ptr<prepared_statement> prepare(data_dictionary::database db, cql_stats& stats) override;
|
|
virtual future<::shared_ptr<messages::result_message>> execute(query_processor& qp, service::query_state& state, const query_options& options, std::optional<service::group0_guard> guard) const override;
|
|
|
|
future<std::tuple<::shared_ptr<cql_transport::event::schema_change>, std::vector<mutation>, cql3::cql_warnings_vec>> prepare_schema_mutations(query_processor& qp, const query_options& options, api::timestamp_type) const override;
|
|
private:
|
|
void add_column(const query_options& options, const schema& schema, data_dictionary::table cf, schema_builder& cfm, std::vector<view_ptr>& view_updates, const column_identifier& column_name, const cql3_type validator, const column_definition* def, bool is_static) const;
|
|
void alter_column(const query_options& options, const schema& schema, data_dictionary::table cf, schema_builder& cfm, std::vector<view_ptr>& view_updates, const column_identifier& column_name, const cql3_type validator, const column_definition* def, bool is_static) const;
|
|
void drop_column(const query_options& options, const schema& schema, data_dictionary::table cf, schema_builder& cfm, std::vector<view_ptr>& view_updates, const column_identifier& column_name, const cql3_type validator, const column_definition* def, bool is_static) const;
|
|
std::pair<schema_ptr, std::vector<view_ptr>> prepare_schema_update(data_dictionary::database db, const query_options& options) const;
|
|
};
|
|
|
|
class alter_table_statement::raw_statement : public raw::cf_statement {
|
|
const alter_table_statement::type _type;
|
|
const std::vector<column_change> _column_changes;
|
|
const std::optional<cf_prop_defs> _properties;
|
|
const alter_table_statement::renames_type _renames;
|
|
const std::unique_ptr<attributes::raw> _attrs;
|
|
|
|
public:
|
|
raw_statement(cf_name name,
|
|
type t,
|
|
std::vector<column_change> column_changes,
|
|
std::optional<cf_prop_defs> properties,
|
|
renames_type renames,
|
|
std::unique_ptr<attributes::raw> attrs);
|
|
|
|
virtual std::unique_ptr<prepared_statement> prepare(data_dictionary::database db, cql_stats& stats) override;
|
|
|
|
virtual audit::statement_category category() const override { return audit::statement_category::DDL; }
|
|
};
|
|
|
|
}
|
|
|
|
}
|