ISSUES-4006 add alter command parser

This commit is contained in:
zhang2014 2020-07-10 15:29:10 +08:00
parent e3f2919f59
commit 3dda4d7dfb
4 changed files with 402 additions and 62 deletions

View File

@ -0,0 +1,317 @@
#include <Parsers/MySQL/ASTAlterCommand.h>
#include <Parsers/ASTExpressionList.h>
#include <Parsers/ASTIdentifier.h>
#include <Parsers/CommonParsers.h>
#include <Parsers/ExpressionElementParsers.h>
#include <Parsers/ExpressionListParsers.h>
#include <Parsers/MySQL/ASTDeclareTableOptions.h>
namespace DB
{
namespace MySQLParser
{
bool ParserAlterCommand::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ParserKeyword k_add("ADD");
ParserKeyword k_drop("DROP");
ParserKeyword k_alter("ALTER");
ParserKeyword k_rename("RENAME");
if (k_add.ignore(pos, expected))
return parseAddCommand(pos, node, expected);
else if (k_drop.ignore(pos, expected))
return parseDropCommand(pos, node, expected);
else if (k_alter.ignore(pos, expected))
return parseAlterCommand(pos, node, expected);
else if (k_rename.ignore(pos, expected))
return parseRenameCommand(pos, node, expected);
else
return parseOtherCommand(pos, node, expected);
// | MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
// | CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST | AFTER col_name]
}
bool ParserAlterCommand::parseAddCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr declare_index;
ASTPtr additional_columns;
ParserDeclareIndex index_p;
ParserDeclareColumn column_p;
auto alter_command = std::make_shared<ASTAlterCommand>();
if (index_p.parse(pos, declare_index, expected))
{
alter_command->type = ASTAlterCommand::ADD_INDEX;
alter_command->set(alter_command->index_decl, declare_index);
}
else
{
alter_command->type = ASTAlterCommand::ADD_COLUMN;
ParserKeyword("COLUMN").ignore(pos, expected);
if (ParserToken(TokenType::OpeningRoundBracket).ignore(pos, expected))
{
ParserList columns_p(std::make_unique<ParserDeclareColumn>(), std::make_unique<ParserToken>(TokenType::Comma));
if (!columns_p.parse(pos, additional_columns, expected))
return false;
if (!ParserToken(TokenType::ClosingRoundBracket).ignore(pos, expected))
return false;
}
else
{
ASTPtr declare_column;
if (!column_p.parse(pos, declare_column, expected))
return false;
additional_columns = std::make_shared<ASTExpressionList>();
additional_columns->children.emplace_back(declare_column);
if (ParserKeyword("FIRST").ignore(pos, expected))
alter_command->first = true;
else if (ParserKeyword("AFTER").ignore(pos, expected))
{
ASTPtr after_column;
ParserIdentifier identifier_p;
if (!identifier_p.parse(pos, after_column, expected))
return false;
alter_command->column_name = getIdentifierName(after_column);
}
}
alter_command->set(alter_command->additional_columns, additional_columns);
}
node = alter_command;
return true;
}
bool ParserAlterCommand::parseDropCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr name;
ParserIdentifier identifier_p;
auto alter_command = std::make_shared<ASTAlterCommand>();
if (ParserKeyword("PRIMARY KEY").ignore(pos, expected))
{
alter_command->index_type = "PRIMARY_KEY";
alter_command->type = ASTAlterCommand::DROP_INDEX;
}
else if (ParserKeyword("FOREIGN KEY").ignore(pos, expected))
{
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->index_type = "FOREIGN";
alter_command->type = ASTAlterCommand::DROP_INDEX;
alter_command->index_name = getIdentifierName(name);
}
else if (ParserKeyword("INDEX").ignore(pos, expected) || ParserKeyword("KEY").ignore(pos, expected))
{
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->index_type = "KEY";
alter_command->type = ASTAlterCommand::DROP_INDEX;
alter_command->index_name = getIdentifierName(name);
}
else if (ParserKeyword("CONSTRAINT").ignore(pos, expected) || ParserKeyword("CHECK").ignore(pos, expected))
{
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->type = ASTAlterCommand::DROP_CHECK;
alter_command->constraint_name = getIdentifierName(name);
}
else
{
ParserKeyword("COLUMN").ignore(pos, expected);
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->type = ASTAlterCommand::DROP_COLUMN;
alter_command->column_name = getIdentifierName(name);
}
node = alter_command;
return true;
}
bool ParserAlterCommand::parseAlterCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr name;
ParserIdentifier identifier_p;
auto alter_command = std::make_shared<ASTAlterCommand>();
if (ParserKeyword("INDEX").ignore(pos, expected))
{
/// ALTER INDEX index_name {VISIBLE | INVISIBLE}
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->index_visible = ParserKeyword("VISIBLE").ignore(pos, expected);
if (!alter_command->index_visible && !ParserKeyword("INVISIBLE").ignore(pos, expected))
return false;
alter_command->type = ASTAlterCommand::MODIFY_INDEX_VISIBLE;
alter_command->index_name = getIdentifierName(name);
}
else if (ParserKeyword("CHECK").ignore(pos, expected) || ParserKeyword("CONSTRAINT").ignore(pos, expected))
{
/// ALTER {CHECK | CONSTRAINT} symbol [NOT] ENFORCED
if (!identifier_p.parse(pos, name, expected))
return false;
alter_command->not_check_enforced = ParserKeyword("NOT").ignore(pos, expected);
if (!ParserKeyword("ENFORCED").ignore(pos, expected))
return false;
alter_command->type = ASTAlterCommand::MODIFY_CHECK;
alter_command->constraint_name = getIdentifierName(name);
}
else
{
/// ALTER [COLUMN] col_name {SET DEFAULT {literal | (expr)} | DROP DEFAULT}
ParserKeyword("COLUMN").ignore(pos, expected);
if (!identifier_p.parse(pos, name, expected))
return false;
if (ParserKeyword("DROP DEFAULT").ignore(pos, expected))
alter_command->type = ASTAlterCommand::DROP_COLUMN_DEFAULT;
else if (ParserKeyword("SET DEFAULT").ignore(pos, expected))
{
ASTPtr default_expression;
ParserExpression expression_p;
if (!expression_p.parse(pos, default_expression, expected))
return false;
alter_command->type = ASTAlterCommand::MODIFY_COLUMN_DEFAULT;
alter_command->set(alter_command->default_expression, default_expression);
}
else
return false;
alter_command->column_name = getIdentifierName(name);
}
node = alter_command;
return true;
}
bool ParserAlterCommand::parseRenameCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr old_name;
ASTPtr new_name;
ParserIdentifier identifier_p;
auto alter_command = std::make_shared<ASTAlterCommand>();
if (ParserKeyword("COLUMN").ignore(pos, expected))
{
if (!identifier_p.parse(pos, old_name, expected))
return false;
if (!ParserKeyword("TO").ignore(pos, expected))
return false;
if (!identifier_p.parse(pos, new_name, expected))
return false;
alter_command->type = ASTAlterCommand::RENAME_COLUMN;
alter_command->old_name = getIdentifierName(old_name);
alter_command->column_name = getIdentifierName(new_name);
}
else if (ParserKeyword("TO").ignore(pos, expected) || ParserKeyword("AS").ignore(pos, expected))
{
if (!identifier_p.parse(pos, new_name, expected))
return false;
alter_command->type = ASTAlterCommand::RENAME_FOREIGN;
alter_command->index_name = getIdentifierName(new_name);
}
else if (ParserKeyword("INDEX").ignore(pos, expected) || ParserKeyword("KEY").ignore(pos, expected))
{
if (!identifier_p.parse(pos, old_name, expected))
return false;
if (!ParserKeyword("TO").ignore(pos, expected))
return false;
if (!identifier_p.parse(pos, new_name, expected))
return false;
alter_command->type = ASTAlterCommand::RENAME_INDEX;
alter_command->old_name = getIdentifierName(old_name);
alter_command->index_name = getIdentifierName(new_name);
}
else
{
return false;
}
node = alter_command;
return true;
}
bool ParserAlterCommand::parseOtherCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
// | CONVERT TO CHARACTER SET charset_name [COLLATE collation_name]
// | [DEFAULT] CHARACTER SET [=] charset_name [COLLATE [=] collation_name]
// | LOCK [=] {DEFAULT | NONE | SHARED | EXCLUSIVE}
// | ORDER BY col_name [, col_name] ...
if (ParserKeyword("FORCE").ignore(pos, expected))
{
/// FORCE
}
else if (ParserKeyword("ALGORITHM").ignore(pos, expected))
{
/// ALGORITHM [=] {DEFAULT | INSTANT | INPLACE | COPY}
}
else if (ParserKeyword("WITH").ignore(pos, expected) || ParserKeyword("WITHOUT").ignore(pos, expected))
{
/// {WITHOUT | WITH} VALIDATION
}
else if (ParserKeyword("IMPORT").ignore(pos, expected) || ParserKeyword("DISCARD").ignore(pos, expected))
{
/// {DISCARD | IMPORT} TABLESPACE
}
else if (ParserKeyword("ENABLE").ignore(pos, expected) || ParserKeyword("DISABLE").ignore(pos, expected))
{
/// {DISABLE | ENABLE} KEYS
}
else
{
ASTPtr table_options;
ParserDeclareTableOptions table_options_p;
if (!table_options_p.parse(pos, table_options, expected))
return false;
/// set.
}
return false;
}
}
}

View File

@ -0,0 +1,85 @@
#pragma once
#include <Parsers/ASTExpressionList.h>
#include <Parsers/IAST.h>
#include <Parsers/MySQL/ASTDeclareColumn.h>
#include <Parsers/MySQL/ASTDeclareIndex.h>
namespace DB
{
namespace MySQLParser
{
class ASTAlterCommand : public IAST
{
public:
enum Type
{
ADD_INDEX,
ADD_COLUMN,
DROP_INDEX,
DROP_CHECK,
DROP_COLUMN,
DROP_COLUMN_DEFAULT,
RENAME_INDEX,
RENAME_COLUMN,
RENAME_FOREIGN,
MODIFY_CHECK,
MODIFY_COLUMN,
MODIFY_TABLE_OPTIONS,
MODIFY_INDEX_VISIBLE,
MODIFY_COLUMN_DEFAULT,
ORDER_BY,
NO_TYPE
};
Type type = NO_TYPE;
/// For ADD INDEX
ASTDeclareIndex * index_decl;
/// For modify default expression
IAST * default_expression;
/// For ADD COLUMN
ASTExpressionList * additional_columns;
bool first = false;
bool index_visible = false;
bool not_check_enforced = false;
String old_name;
String index_type;
String index_name;
String column_name;
String constraint_name;
};
class ParserAlterCommand : public IParserBase
{
protected:
const char * getName() const override { return "alter command"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
bool parseAddCommand(Pos & pos, ASTPtr & node, Expected & expected);
bool parseDropCommand(Pos & pos, ASTPtr & node, Expected & expected);
bool parseAlterCommand(Pos & pos, ASTPtr & node, Expected & expected);
bool parseRenameCommand(Pos & pos, ASTPtr & node, Expected & expected);
bool parseOtherCommand(Pos & pos, ASTPtr & node, Expected & expected);
};
}
}

View File

@ -52,34 +52,6 @@ void ASTAlterQuery::formatImpl(const IAST::FormatSettings & settings, IAST::Form
// static_cast<IAST *>(command_list)->formatImpl(settings, state, frame_nested);
}
bool ParserAlterCommand::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ParserKeyword k_add("ADD");
ParserKeyword k_drop("DROP");
if (k_add.ignore(pos, expected))
return parseAddCommand(pos, node, expected);
else if (k_drop.ignore(pos, expected))
return parseDropCommand(pos, node, expected);
return false;
}
bool ParserAlterCommand::parseAddCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr declare_index;
ParserDeclareIndex p_index;
/// TODO: add column
if (!p_index.parse(pos, declare_index, expected))
return false;
return true;
}
bool ParserAlterCommand::parseDropCommand(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
return false;
}
bool ParserAlterQuery::parseImpl(IParser::Pos & pos, ASTPtr & node, Expected & expected)
{
ASTPtr table;

View File

@ -11,28 +11,6 @@ namespace DB
namespace MySQLParser
{
class ASTAlterCommand : public IAST
{
public:
enum Type
{
ADD_COLUMN,
ADD_INDEX,
DROP_CONSTRAINT,
DROP_COLUMN,
DROP_INDEX,
DROP_PRIMARY_KEY,
DROP_FOREIGN_KEY,
};
/// For ADD INDEX
ASTDeclareIndex * add_index;
/// For ADD COLUMN
ASTDeclareColumn * add_column;
};
class ASTAlterQuery : public IAST
{
public:
@ -48,18 +26,6 @@ protected:
void formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const override;
};
class ParserAlterCommand : public IParserBase
{
protected:
const char * getName() const override { return "alter command"; }
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
bool parseAddCommand(Pos & pos, ASTPtr & node, Expected & expected);
bool parseDropCommand(Pos & pos, ASTPtr & node, Expected & expected);
};
class ParserAlterQuery : public IParserBase
{
protected: