#include #include #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 parseIdentifierOrStringLiteral(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).enableInheritKeyword(true).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 parseToRoles(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::shared_ptr & roles) { return IParserBase::wrapParseImpl(pos, [&] { ASTPtr ast; if (roles || !ParserKeyword{"TO"}.ignore(pos, expected) || !ParserExtendedRoleSet{}.useIDMode(id_mode).parse(pos, ast, expected)) return false; roles = std::static_pointer_cast(ast); return true; }); } } bool ParserCreateSettingsProfileQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected) { bool alter = false; if (attach_mode) { if (!ParserKeyword{"ATTACH SETTINGS PROFILE"}.ignore(pos, expected) && !ParserKeyword{"ATTACH PROFILE"}.ignore(pos, expected)) return false; } else { if (ParserKeyword{"ALTER SETTINGS PROFILE"}.ignore(pos, expected) || ParserKeyword{"ALTER PROFILE"}.ignore(pos, expected)) alter = true; else if (!ParserKeyword{"CREATE SETTINGS PROFILE"}.ignore(pos, expected) && !ParserKeyword{"CREATE PROFILE"}.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 (!parseIdentifierOrStringLiteral(pos, expected, name)) return false; String cluster; if (ParserKeyword{"ON"}.ignore(pos, expected)) { if (!ASTQueryWithOnCluster::parse(pos, cluster, expected)) 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; } std::shared_ptr to_roles; parseToRoles(pos, expected, attach_mode, to_roles); 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->cluster = std::move(cluster); query->name = std::move(name); query->new_name = std::move(new_name); query->settings = std::move(settings); query->to_roles = std::move(to_roles); return true; } }