| 74 | } |
| 75 | |
| 76 | BlockIO InterpreterAlterQuery::executeToTable(const ASTAlterQuery & alter) |
| 77 | { |
| 78 | BlockIO res; |
| 79 | |
| 80 | if (!alter.cluster.empty()) |
| 81 | return executeDDLQueryOnCluster(query_ptr, getContext(), getRequiredAccess()); |
| 82 | |
| 83 | getContext()->checkAccess(getRequiredAccess()); |
| 84 | auto table_id = getContext()->resolveStorageID(alter, Context::ResolveOrdinary); |
| 85 | query_ptr->as<ASTAlterQuery &>().database = table_id.database_name; |
| 86 | |
| 87 | DatabasePtr database = DatabaseCatalog::instance().getDatabase(table_id.database_name, getContext()); |
| 88 | if (typeid_cast<DatabaseReplicated *>(database.get()) |
| 89 | && !getContext()->getClientInfo().is_replicated_database_internal) |
| 90 | { |
| 91 | auto guard = DatabaseCatalog::instance().getDDLGuard(table_id.database_name, table_id.table_name); |
| 92 | guard->releaseTableLock(); |
| 93 | return typeid_cast<DatabaseReplicated *>(database.get())->tryEnqueueReplicatedDDL(query_ptr, getContext()); |
| 94 | } |
| 95 | |
| 96 | StoragePtr table = DatabaseCatalog::instance().getTable(table_id, getContext()); |
| 97 | |
| 98 | TableLockHolder alter_lock; |
| 99 | IntentLockPtr cnch_table_lock; |
| 100 | auto metadata_snapshot = table->getInMemoryMetadataPtr(); |
| 101 | |
| 102 | if (database->getEngineName() == "Cnch") |
| 103 | { |
| 104 | auto cnch_txn = getContext()->getCurrentTransaction(); |
| 105 | |
| 106 | if (!cnch_txn) |
| 107 | throw Exception("Cnch transaction is not initialized", ErrorCodes::CNCH_TRANSACTION_NOT_INITIALIZED); |
| 108 | |
| 109 | LOG_INFO(&Poco::Logger::get("InterpreterAlterQuery"), "Waiting for cnch_lock for " + table_id.database_name + "." + table_id.table_name + "."); |
| 110 | cnch_table_lock = cnch_txn->createIntentLock(IntentLock::TB_LOCK_PREFIX, table->getStorageID().database_name, table->getStorageID().table_name); |
| 111 | } |
| 112 | else |
| 113 | { |
| 114 | /// Only accquire lock for non-cnch table |
| 115 | alter_lock = table->lockForAlter(getContext()->getCurrentQueryId(), getContext()->getSettingsRef().lock_acquire_timeout); |
| 116 | } |
| 117 | |
| 118 | /// Add default database to table identifiers that we can encounter in e.g. default expressions, mutation expression, etc. |
| 119 | AddDefaultDatabaseVisitor visitor(getContext(), table_id.getDatabaseName()); |
| 120 | ASTPtr command_list_ptr = alter.command_list->ptr(); |
| 121 | visitor.visit(command_list_ptr); |
| 122 | |
| 123 | AlterCommands alter_commands; |
| 124 | PartitionCommands partition_commands; |
| 125 | MutationCommands mutation_commands; |
| 126 | LiveViewCommands live_view_commands; |
| 127 | for (const auto & child : alter.command_list->children) |
| 128 | { |
| 129 | auto * command_ast = child->as<ASTAlterCommand>(); |
| 130 | if (auto alter_command = AlterCommand::parse(command_ast, getContext())) |
| 131 | alter_commands.emplace_back(std::move(*alter_command)); |
| 132 | else if (auto partition_command = PartitionCommand::parse(command_ast)) |
| 133 | { |
nothing calls this directly
no test coverage detected