#include #include #include #include #include #include #include #include namespace DB { namespace { bool parseRenameTo(IParserBase::Pos & pos, Expected & expected, String & new_name) { return IParserBase::wrapParseImpl(pos, [&] { if (!ParserKeyword{"RENAME TO"}.ignore(pos, expected)) return false; return parseRoleName(pos, expected, new_name); }); } bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::shared_ptr & settings) { return IParserBase::wrapParseImpl(pos, [&] { if (!ParserKeyword{"SETTINGS"}.ignore(pos, expected)) return false; ASTPtr new_settings_ast; if (!ParserSettingsProfileElements{}.useIDMode(id_mode).parse(pos, new_settings_ast, expected)) return false; if (!settings) settings = std::make_shared(); const auto & new_settings = new_settings_ast->as(); settings->elements.insert(settings->elements.end(), new_settings.elements.begin(), new_settings.elements.end()); return true; }); } } bool ParserCreateRoleQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { bool alter = false; if (attach_mode) { if (!ParserKeyword{"ATTACH ROLE"}.ignore(pos, expected)) return false; } else { if (ParserKeyword{"ALTER ROLE"}.ignore(pos, expected)) alter = true; else if (!ParserKeyword{"CREATE ROLE"}.ignore(pos, expected)) return false; } bool if_exists = false; bool if_not_exists = false; bool or_replace = false; if (alter) { if (ParserKeyword{"IF EXISTS"}.ignore(pos, expected)) if_exists = true; } else { if (ParserKeyword{"IF NOT EXISTS"}.ignore(pos, expected)) if_not_exists = true; else if (ParserKeyword{"OR REPLACE"}.ignore(pos, expected)) or_replace = true; } String name; if (!parseRoleName(pos, expected, name)) return false; String new_name; std::shared_ptr settings; while (true) { if (alter && parseRenameTo(pos, expected, new_name)) continue; if (parseSettings(pos, expected, attach_mode, settings)) continue; break; } auto query = std::make_shared(); node = query; query->alter = alter; query->attach = attach_mode; query->if_exists = if_exists; query->if_not_exists = if_not_exists; query->or_replace = or_replace; query->name = std::move(name); query->new_name = std::move(new_name); query->settings = std::move(settings); return true; } }