2018-05-15 12:56:14 +00:00
|
|
|
#include <Storages/MutationCommands.h>
|
2018-04-19 10:33:16 +00:00
|
|
|
#include <IO/Operators.h>
|
|
|
|
#include <Parsers/formatAST.h>
|
2018-07-11 12:43:55 +00:00
|
|
|
#include <Parsers/ExpressionListParsers.h>
|
|
|
|
#include <Parsers/ParserAlterQuery.h>
|
2018-04-19 10:33:16 +00:00
|
|
|
#include <Parsers/parseQuery.h>
|
2018-08-07 13:58:11 +00:00
|
|
|
#include <Parsers/ASTAssignment.h>
|
2018-07-11 12:43:55 +00:00
|
|
|
#include <Common/typeid_cast.h>
|
2018-05-15 12:56:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
|
2018-07-11 12:43:55 +00:00
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int UNKNOWN_MUTATION_COMMAND;
|
2018-08-07 13:58:11 +00:00
|
|
|
extern const int MULTIPLE_ASSIGNMENTS_TO_COLUMN;
|
2018-07-11 12:43:55 +00:00
|
|
|
}
|
|
|
|
|
2018-06-13 13:49:27 +00:00
|
|
|
std::optional<MutationCommand> MutationCommand::parse(ASTAlterCommand * command)
|
2018-04-19 10:33:16 +00:00
|
|
|
{
|
2018-06-13 13:49:27 +00:00
|
|
|
if (command->type == ASTAlterCommand::DELETE)
|
2018-04-19 10:33:16 +00:00
|
|
|
{
|
2018-06-13 13:49:27 +00:00
|
|
|
MutationCommand res;
|
|
|
|
res.ast = command->ptr();
|
|
|
|
res.type = DELETE;
|
|
|
|
res.predicate = command->predicate;
|
|
|
|
return res;
|
2018-04-19 10:33:16 +00:00
|
|
|
}
|
2018-08-07 13:58:11 +00:00
|
|
|
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 = typeid_cast<const ASTAssignment &>(*assignment_ast);
|
|
|
|
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 `" + assignment.column_name + "`",
|
|
|
|
ErrorCodes::MULTIPLE_ASSIGNMENTS_TO_COLUMN);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2018-06-13 13:49:27 +00:00
|
|
|
else
|
|
|
|
return {};
|
2018-04-19 10:33:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-13 13:49:27 +00:00
|
|
|
std::shared_ptr<ASTAlterCommandList> MutationCommands::ast() const
|
2018-04-19 10:33:16 +00:00
|
|
|
{
|
2018-06-13 13:49:27 +00:00
|
|
|
auto res = std::make_shared<ASTAlterCommandList>();
|
|
|
|
for (const MutationCommand & command : *this)
|
|
|
|
res->add(command.ast->clone());
|
|
|
|
return res;
|
2018-04-19 10:33:16 +00:00
|
|
|
}
|
|
|
|
|
2018-07-11 12:43:55 +00:00
|
|
|
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 : typeid_cast<const ASTAlterCommandList &>(*commands_ast).commands)
|
|
|
|
{
|
|
|
|
auto command = MutationCommand::parse(command_ast);
|
|
|
|
if (!command)
|
|
|
|
throw Exception("Unknown mutation command type: " + DB::toString<int>(command_ast->type), ErrorCodes::UNKNOWN_MUTATION_COMMAND);
|
|
|
|
push_back(std::move(*command));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-15 12:56:14 +00:00
|
|
|
}
|