diff --git a/src/Parsers/Access/ASTCreateUserQuery.cpp b/src/Parsers/Access/ASTCreateUserQuery.cpp index 4eebc471d5e..8f44cb3c409 100644 --- a/src/Parsers/Access/ASTCreateUserQuery.cpp +++ b/src/Parsers/Access/ASTCreateUserQuery.cpp @@ -21,8 +21,6 @@ namespace void formatAuthenticationData(const std::vector> & authentication_methods, const IAST::FormatSettings & settings) { - settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " IDENTIFIED" << (settings.hilite ? IAST::hilite_none : ""); - // safe because this method is only called if authentication_methods.size > 1 // if the first type is present, include the `WITH` keyword if (authentication_methods[0]->type) @@ -200,7 +198,8 @@ ASTPtr ASTCreateUserQuery::clone() const if (settings) res->settings = std::static_pointer_cast(settings->clone()); - if (authentication_methods.empty()) + // If identification (auth method) is missing from query, we should serialize it in the form of `NO_PASSWORD` unless it is alter query + if (!alter && authentication_methods.empty()) { auto ast = std::make_shared(); ast->type = AuthenticationType::NO_PASSWORD; @@ -255,7 +254,15 @@ void ASTCreateUserQuery::formatImpl(const FormatSettings & format, FormatState & formatRenameTo(*new_name, format); if (!authentication_methods.empty()) + { + if (add_identified_with) + { + format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " ADD" << (format.hilite ? IAST::hilite_none : ""); + } + + format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " IDENTIFIED" << (format.hilite ? IAST::hilite_none : ""); formatAuthenticationData(authentication_methods, format); + } if (valid_until) formatValidUntil(*valid_until, format); @@ -278,6 +285,9 @@ void ASTCreateUserQuery::formatImpl(const FormatSettings & format, FormatState & if (grantees) formatGrantees(*grantees, format); + + if (reset_authentication_methods_to_new) + format.ostr << (format.hilite ? hilite_keyword : "") << " RESET AUTHENTICATION METHODS TO NEW" << (format.hilite ? hilite_none : ""); } } diff --git a/src/Parsers/Access/ASTCreateUserQuery.h b/src/Parsers/Access/ASTCreateUserQuery.h index 66a31366993..e1bae98f2f3 100644 --- a/src/Parsers/Access/ASTCreateUserQuery.h +++ b/src/Parsers/Access/ASTCreateUserQuery.h @@ -43,6 +43,7 @@ public: bool if_not_exists = false; bool or_replace = false; bool reset_authentication_methods_to_new = false; + bool add_identified_with = false; bool replace_authentication_methods = false; std::shared_ptr names; diff --git a/src/Parsers/Access/ParserCreateUserQuery.cpp b/src/Parsers/Access/ParserCreateUserQuery.cpp index 466fd544c63..0ef658d2377 100644 --- a/src/Parsers/Access/ParserCreateUserQuery.cpp +++ b/src/Parsers/Access/ParserCreateUserQuery.cpp @@ -536,10 +536,10 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec ASTPtr valid_until; String cluster; String storage_name; - std::optional reset_authentication_methods_to_new; + bool reset_authentication_methods_to_new = false; bool parsed_identified_with = false; - bool parsed_add_new_method = false; + bool parsed_add_identified_with = false; while (true) { @@ -549,20 +549,20 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec if (!parsed_identified_with) { - parsed_add_new_method = parseAddIdentifiedWith(pos, expected, auth_data); + parsed_add_identified_with = parseAddIdentifiedWith(pos, expected, auth_data); - if (parsed_add_new_method && !alter) + if (parsed_add_identified_with && !alter) { throw Exception(ErrorCodes::BAD_ARGUMENTS, "Create user query is not allowed to have ADD IDENTIFIED, remove the ADD keyword."); } } } - if (!reset_authentication_methods_to_new.has_value()) + if (!reset_authentication_methods_to_new) { reset_authentication_methods_to_new = parseResetAuthenticationMethods(pos, expected); - if (reset_authentication_methods_to_new.value() && !alter) + if (reset_authentication_methods_to_new && !alter) { throw Exception(ErrorCodes::BAD_ARGUMENTS, "RESET AUTHENTICATION METHODS TO NEW can only be used on ALTER statement"); } @@ -645,7 +645,7 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec throw Exception(ErrorCodes::BAD_ARGUMENTS, "NO_PASSWORD Authentication method cannot co-exist with other authentication methods"); } - if (has_no_password_authentication_method && parsed_add_new_method) + if (has_no_password_authentication_method && parsed_add_identified_with) { throw Exception(ErrorCodes::BAD_ARGUMENTS, "The authentication method 'no_password' cannot be used with the ADD keyword. " "Use 'ALTER USER xyz IDENTIFIED WITH no_password' to replace existing authentication methods"); @@ -685,7 +685,8 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec query->default_database = std::move(default_database); query->valid_until = std::move(valid_until); query->storage_name = std::move(storage_name); - query->reset_authentication_methods_to_new = reset_authentication_methods_to_new.value_or(false); + query->reset_authentication_methods_to_new = reset_authentication_methods_to_new; + query->add_identified_with = parsed_add_identified_with; query->replace_authentication_methods = parsed_identified_with || has_no_password_authentication_method; for (const auto & authentication_method : query->authentication_methods)