From edff0cf4db355b7c8a6b08e308ef59ae14c31a17 Mon Sep 17 00:00:00 2001 From: Gleb Natapov Date: Wed, 17 Nov 2021 17:20:24 +0200 Subject: [PATCH] cql3: move ALTER TYPE statement to prepare_schema_mutations() api --- cql3/statements/alter_type_statement.cc | 62 ++++++++++++++++++++++--- cql3/statements/alter_type_statement.hh | 12 ++++- 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/cql3/statements/alter_type_statement.cc b/cql3/statements/alter_type_statement.cc index 15050ffaa6..61dd711c3e 100644 --- a/cql3/statements/alter_type_statement.cc +++ b/cql3/statements/alter_type_statement.cc @@ -82,7 +82,7 @@ const sstring& alter_type_statement::keyspace() const return _name.get_keyspace(); } -future<> alter_type_statement::do_announce_migration(database& db, service::migration_manager& mm) const +future<> alter_type_statement::do_announce_migration(database& db, service::migration_manager& mm, base_visitor& visitor) const { auto&& ks = db.find_keyspace(keyspace()); auto&& all_types = ks.metadata()->user_types().get_all_types(); @@ -105,7 +105,7 @@ future<> alter_type_statement::do_announce_migration(database& db, service::migr // Now, we need to announce the type update to basically change it for new tables using this type, // but we also need to find all existing user types and CF using it and change them. - co_await mm.announce_type_update(updated); + co_await visitor(updated); for (auto&& schema : ks.metadata()->cf_meta_data() | boost::adaptors::map_values) { auto cfm = schema_builder(schema); @@ -120,19 +120,69 @@ future<> alter_type_statement::do_announce_migration(database& db, service::migr } if (modified) { if (schema->is_view()) { - co_await mm.announce_view_update(view_ptr(cfm.build())); + co_await visitor(view_ptr(cfm.build())); } else { - co_await mm.announce_column_family_update(cfm.build(), false, {}, std::nullopt); + co_await visitor(cfm.build(), false, {}, std::nullopt); } } } } +future, std::vector>> +alter_type_statement::prepare_schema_mutations(query_processor& qp) const { + try { + struct visitor : public base_visitor { + service::migration_manager& mm; + std::vector mutations; + future<> operator()(view_ptr view) override { + auto m = co_await mm.prepare_view_update_announcement(std::move(view)); + std::move(m.begin(), m.end(), std::back_inserter(mutations)); + } + future<> operator()(user_type type) override { + auto m = co_await mm.prepare_update_type_announcement(std::move(type)); + std::move(m.begin(), m.end(), std::back_inserter(mutations)); + } + future<> operator()(schema_ptr cfm, bool from_thrift, std::vector&& view_updates, std::optional ts_opt) override { + auto m = co_await mm.prepare_column_family_update_announcement(std::move(cfm), from_thrift, std::move(view_updates), ts_opt); + std::move(m.begin(), m.end(), std::back_inserter(mutations)); + } + visitor(service::migration_manager& mm_) : mm(mm_) {} + } v(qp.get_migration_manager()); + + co_await do_announce_migration(qp.db(), qp.get_migration_manager(), v); + + using namespace cql_transport; + auto ret = ::make_shared( + event::schema_change::change_type::UPDATED, + event::schema_change::target_type::TYPE, + keyspace(), + _name.get_string_type_name()); + + co_return std::make_pair(std::move(ret), std::move(v.mutations)); + } catch(no_such_keyspace& e) { + co_return coroutine::make_exception(exceptions::invalid_request_exception(format("Cannot alter type in unknown keyspace {}", keyspace()))); + } +} + future> alter_type_statement::announce_migration(query_processor& qp) const { - database& db = qp.db(); try { - co_await do_announce_migration(db, qp.get_migration_manager()); + struct visitor : public base_visitor { + service::migration_manager& mm; + future<> operator()(view_ptr view) override { + return mm.announce_view_update(std::move(view)); + } + future<> operator()(user_type type) override { + return mm.announce_type_update(std::move(type)); + } + future<> operator()(schema_ptr cfm, bool from_thrift, std::vector&& view_updates, std::optional ts_opt) override { + return mm.announce_column_family_update(std::move(cfm), from_thrift, std::move(view_updates), ts_opt); + } + visitor(service::migration_manager& mm_) : mm(mm_) {} + } v(qp.get_migration_manager()); + + co_await do_announce_migration(qp.db(), qp.get_migration_manager(), v); + using namespace cql_transport; co_return ::make_shared( event::schema_change::change_type::UPDATED, diff --git a/cql3/statements/alter_type_statement.hh b/cql3/statements/alter_type_statement.hh index 75272219dc..09738d09ca 100644 --- a/cql3/statements/alter_type_statement.hh +++ b/cql3/statements/alter_type_statement.hh @@ -45,6 +45,7 @@ #include "cql3/cql3_type.hh" #include "cql3/ut_name.hh" #include "database_fwd.hh" +#include "schema.hh" namespace service { class migration_manager; @@ -72,12 +73,21 @@ public: virtual future> announce_migration(query_processor& qp) const override; + future, std::vector>> prepare_schema_mutations(query_processor& qp) const override; + virtual bool has_prepare_schema_mutations() const override { return true; } + class add_or_alter; class renames; protected: virtual user_type make_updated_type(database& db, user_type to_update) const = 0; private: - future<> do_announce_migration(database& db, service::migration_manager& mm) const; + struct base_visitor { + virtual future<> operator()(view_ptr view) = 0; + virtual future<> operator()(user_type type) = 0; + virtual future<> operator()(schema_ptr cfm, bool from_thrift, std::vector&& view_updates, std::optional ts_opt) = 0; + }; + + future<> do_announce_migration(database& db, service::migration_manager& mm, base_visitor& visitor) const; }; class alter_type_statement::add_or_alter : public alter_type_statement {