ClickHouse/src/Storages/MutationCommands.cpp

158 lines
5.3 KiB
C++
Raw Normal View History

#include <Storages/MutationCommands.h>
2021-01-11 14:43:05 +00:00
#include <IO/WriteHelpers.h>
#include <Parsers/formatAST.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/ParserAlterQuery.h>
#include <Parsers/parseQuery.h>
#include <Parsers/ASTAssignment.h>
#include <Parsers/ASTColumnDeclaration.h>
#include <Parsers/ASTFunction.h>
2019-05-05 17:01:54 +00:00
#include <Parsers/ASTIdentifier.h>
#include <Parsers/ASTLiteral.h>
#include <Common/typeid_cast.h>
#include <Common/quoteString.h>
#include <Core/Defines.h>
2020-01-15 13:00:08 +00:00
#include <DataTypes/DataTypeFactory.h>
2020-03-17 13:49:50 +00:00
#include <Parsers/queryToString.h>
#include <common/logger_useful.h>
namespace DB
{
namespace ErrorCodes
{
extern const int UNKNOWN_MUTATION_COMMAND;
extern const int MULTIPLE_ASSIGNMENTS_TO_COLUMN;
}
2020-03-17 13:49:50 +00:00
std::optional<MutationCommand> MutationCommand::parse(ASTAlterCommand * command, bool parse_alter_commands)
{
if (command->type == ASTAlterCommand::DELETE)
{
MutationCommand res;
res.ast = command->ptr();
res.type = DELETE;
res.predicate = command->predicate;
res.partition = command->partition;
return res;
}
else if (command->type == ASTAlterCommand::UPDATE)
{
MutationCommand res;
res.ast = command->ptr();
res.type = UPDATE;
res.predicate = command->predicate;
res.partition = command->partition;
for (const ASTPtr & assignment_ast : command->update_assignments->children)
{
const auto & assignment = assignment_ast->as<ASTAssignment &>();
2020-11-29 13:43:24 +00:00
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;
}
2019-04-10 17:44:39 +00:00
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<ASTIdentifier &>().name();
2019-04-10 17:44:39 +00:00
return res;
}
2020-03-17 13:49:50 +00:00
else if (parse_alter_commands && command->type == ASTAlterCommand::MODIFY_COLUMN)
2020-01-15 13:00:08 +00:00
{
MutationCommand res;
res.ast = command->ptr();
2020-01-17 13:54:22 +00:00
res.type = MutationCommand::Type::READ_COLUMN;
2020-01-15 13:00:08 +00:00
const auto & ast_col_decl = command->col_decl->as<ASTColumnDeclaration &>();
res.column_name = ast_col_decl.name;
res.data_type = DataTypeFactory::instance().get(ast_col_decl.type);
return res;
}
2020-03-17 13:49:50 +00:00
else if (parse_alter_commands && command->type == ASTAlterCommand::DROP_COLUMN)
2020-01-15 13:00:08 +00:00
{
MutationCommand res;
res.ast = command->ptr();
2020-01-17 13:54:22 +00:00
res.type = MutationCommand::Type::DROP_COLUMN;
2020-01-15 13:00:08 +00:00
res.column_name = getIdentifierName(command->column);
2020-03-17 13:49:50 +00:00
if (command->partition)
res.partition = command->partition;
if (command->clear_column)
res.clear = true;
2020-01-15 13:00:08 +00:00
return res;
}
2020-03-17 13:49:50 +00:00
else if (parse_alter_commands && command->type == ASTAlterCommand::DROP_INDEX)
2020-01-17 13:54:22 +00:00
{
MutationCommand res;
res.ast = command->ptr();
res.type = MutationCommand::Type::DROP_INDEX;
res.column_name = command->index->as<ASTIdentifier &>().name();
2020-03-17 13:49:50 +00:00
if (command->partition)
res.partition = command->partition;
if (command->clear_index)
res.clear = true;
return res;
2020-02-25 08:53:14 +00:00
}
2020-03-25 18:44:08 +00:00
else if (parse_alter_commands && command->type == ASTAlterCommand::RENAME_COLUMN)
{
MutationCommand res;
res.ast = command->ptr();
res.type = MutationCommand::Type::RENAME_COLUMN;
res.column_name = command->column->as<ASTIdentifier &>().name();
res.rename_to = command->rename_to->as<ASTIdentifier &>().name();
2020-03-25 18:44:08 +00:00
return res;
}
2020-01-22 13:24:20 +00:00
else if (command->type == ASTAlterCommand::MATERIALIZE_TTL)
{
MutationCommand res;
res.ast = command->ptr();
res.type = MATERIALIZE_TTL;
2020-03-10 11:17:26 +00:00
res.partition = command->partition;
2020-01-17 13:54:22 +00:00
return res;
}
2020-02-25 09:49:45 +00:00
return {};
}
std::shared_ptr<ASTExpressionList> MutationCommands::ast() const
{
auto res = std::make_shared<ASTExpressionList>();
for (const MutationCommand & command : *this)
res->children.push_back(command.ast->clone());
return res;
}
void MutationCommands::writeText(WriteBuffer & out) const
{
2020-11-09 16:05:40 +00:00
WriteBufferFromOwnString commands_buf;
formatAST(*ast(), commands_buf, /* hilite = */ false, /* one_line = */ true);
2021-01-11 14:43:05 +00:00
writeEscapedString(commands_buf.str(), out);
}
void MutationCommands::readText(ReadBuffer & in)
{
String commands_str;
2021-01-11 14:43:05 +00:00
readEscapedString(commands_str, in);
ParserAlterCommandList p_alter_commands;
auto commands_ast = parseQuery(
p_alter_commands, commands_str.data(), commands_str.data() + commands_str.length(), "mutation commands list", 0, DBMS_DEFAULT_MAX_PARSER_DEPTH);
for (const auto & child : commands_ast->children)
{
auto * command_ast = child->as<ASTAlterCommand>();
2020-01-15 13:00:08 +00:00
auto command = MutationCommand::parse(command_ast, true);
if (!command)
throw Exception("Unknown mutation command type: " + DB::toString<int>(command_ast->type), ErrorCodes::UNKNOWN_MUTATION_COMMAND);
push_back(std::move(*command));
}
}
}