#include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int UNKNOWN_MUTATION_COMMAND; extern const int MULTIPLE_ASSIGNMENTS_TO_COLUMN; } std::optional MutationCommand::parse(ASTAlterCommand * command) { if (command->type == ASTAlterCommand::DELETE) { MutationCommand res; res.ast = command->ptr(); res.type = DELETE; res.predicate = command->predicate; return res; } else if (command->type == ASTAlterCommand::UPDATE) { MutationCommand res; res.ast = command->ptr(); res.type = UPDATE; res.predicate = command->predicate; for (const ASTPtr & assignment_ast : command->update_assignments->children) { const auto & assignment = assignment_ast->as(); auto insertion = res.column_to_update_expression.emplace(assignment.column_name, assignment.expression); if (!insertion.second) throw Exception("Multiple assignments in the single statement to column " + backQuote(assignment.column_name), ErrorCodes::MULTIPLE_ASSIGNMENTS_TO_COLUMN); } return res; } else if (command->type == ASTAlterCommand::MATERIALIZE_INDEX) { MutationCommand res; res.ast = command->ptr(); res.type = MATERIALIZE_INDEX; res.partition = command->partition; res.predicate = nullptr; res.index_name = command->index->as().name; return res; } else return {}; } std::shared_ptr MutationCommands::ast() const { auto res = std::make_shared(); for (const MutationCommand & command : *this) res->add(command.ast->clone()); return res; } void MutationCommands::writeText(WriteBuffer & out) const { std::stringstream commands_ss; formatAST(*ast(), commands_ss, /* hilite = */ false, /* one_line = */ true); out << escape << commands_ss.str(); } void MutationCommands::readText(ReadBuffer & in) { String commands_str; in >> escape >> commands_str; ParserAlterCommandList p_alter_commands; auto commands_ast = parseQuery( p_alter_commands, commands_str.data(), commands_str.data() + commands_str.length(), "mutation commands list", 0); for (ASTAlterCommand * command_ast : commands_ast->as().commands) { auto command = MutationCommand::parse(command_ast); if (!command) throw Exception("Unknown mutation command type: " + DB::toString(command_ast->type), ErrorCodes::UNKNOWN_MUTATION_COMMAND); push_back(std::move(*command)); } } }