mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Merge 396544a70d
into 44b4bd38b9
This commit is contained in:
commit
93f9fcc5ed
@ -13,5 +13,10 @@ Syntax:
|
|||||||
``` sql
|
``` sql
|
||||||
ALTER ROLE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
ALTER ROLE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
||||||
[ON CLUSTER cluster_name]
|
[ON CLUSTER cluster_name]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
@ -13,6 +13,11 @@ Syntax:
|
|||||||
``` sql
|
``` sql
|
||||||
ALTER SETTINGS PROFILE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
ALTER SETTINGS PROFILE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
||||||
[ON CLUSTER cluster_name]
|
[ON CLUSTER cluster_name]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
|
||||||
[TO {{role1 | user1 [, role2 | user2 ...]} | NONE | ALL | ALL EXCEPT {role1 | user1 [, role2 | user2 ...]}}]
|
[TO {{role1 | user1 [, role2 | user2 ...]} | NONE | ALL | ALL EXCEPT {role1 | user1 [, role2 | user2 ...]}}]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
@ -18,7 +18,12 @@ ALTER USER [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
|||||||
[VALID UNTIL datetime]
|
[VALID UNTIL datetime]
|
||||||
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
||||||
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
|
||||||
To use `ALTER USER` you must have the [ALTER USER](../../../sql-reference/statements/grant.md#access-management) privilege.
|
To use `ALTER USER` you must have the [ALTER USER](../../../sql-reference/statements/grant.md#access-management) privilege.
|
||||||
|
@ -13,5 +13,10 @@ sidebar_label: ROLE
|
|||||||
``` sql
|
``` sql
|
||||||
ALTER ROLE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
ALTER ROLE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
||||||
[ON CLUSTER cluster_name]
|
[ON CLUSTER cluster_name]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
@ -13,6 +13,11 @@ sidebar_label: SETTINGS PROFILE
|
|||||||
``` sql
|
``` sql
|
||||||
ALTER SETTINGS PROFILE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
ALTER SETTINGS PROFILE [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
||||||
[ON CLUSTER cluster_name]
|
[ON CLUSTER cluster_name]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
|
||||||
[TO {{role1 | user1 [, role2 | user2 ...]} | NONE | ALL | ALL EXCEPT {role1 | user1 [, role2 | user2 ...]}}]
|
[TO {{role1 | user1 [, role2 | user2 ...]} | NONE | ALL | ALL EXCEPT {role1 | user1 [, role2 | user2 ...]}}]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
@ -19,7 +19,12 @@ ALTER USER [IF EXISTS] name1 [RENAME TO new_name |, name2 [,...]]
|
|||||||
[VALID UNTIL datetime]
|
[VALID UNTIL datetime]
|
||||||
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
||||||
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
||||||
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]
|
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
[DROP SETTINGS variable [,...] ]
|
||||||
|
[ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
[DROP ALL PROFILES]
|
||||||
|
[DROP ALL SETTINGS]
|
||||||
```
|
```
|
||||||
|
|
||||||
Для выполнения `ALTER USER` необходима привилегия [ALTER USER](../grant.md#grant-access-management).
|
Для выполнения `ALTER USER` необходима привилегия [ALTER USER](../grant.md#grant-access-management).
|
||||||
|
@ -45,7 +45,7 @@ namespace
|
|||||||
|
|
||||||
roles_info.names_of_roles[role_id] = role->getName();
|
roles_info.names_of_roles[role_id] = role->getName();
|
||||||
roles_info.access.makeUnion(role->access);
|
roles_info.access.makeUnion(role->access);
|
||||||
roles_info.settings_from_enabled_roles.merge(role->settings);
|
roles_info.settings_from_enabled_roles.merge(role->settings, /* normalize= */ false);
|
||||||
|
|
||||||
for (const auto & granted_role : role->granted_roles.getGranted())
|
for (const auto & granted_role : role->granted_roles.getGranted())
|
||||||
collectRoles(roles_info, skip_ids, get_role_function, granted_role, false, false);
|
collectRoles(roles_info, skip_ids, get_role_function, granted_role, false, false);
|
||||||
|
@ -137,6 +137,13 @@ void SettingsConstraints::merge(const SettingsConstraints & other)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SettingsConstraints::check(const Settings & current_settings, const AlterSettingsProfileElements & profile_elements, SettingSource source) const
|
||||||
|
{
|
||||||
|
check(current_settings, profile_elements.add_settings, source);
|
||||||
|
check(current_settings, profile_elements.modify_settings, source);
|
||||||
|
/// We don't check `drop_settings` here.
|
||||||
|
}
|
||||||
|
|
||||||
void SettingsConstraints::check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const
|
void SettingsConstraints::check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const
|
||||||
{
|
{
|
||||||
for (const auto & element : profile_elements)
|
for (const auto & element : profile_elements)
|
||||||
|
@ -74,10 +74,11 @@ public:
|
|||||||
void merge(const SettingsConstraints & other);
|
void merge(const SettingsConstraints & other);
|
||||||
|
|
||||||
/// Checks whether `change` violates these constraints and throws an exception if so.
|
/// Checks whether `change` violates these constraints and throws an exception if so.
|
||||||
void check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const;
|
|
||||||
void check(const Settings & current_settings, const SettingChange & change, SettingSource source) const;
|
void check(const Settings & current_settings, const SettingChange & change, SettingSource source) const;
|
||||||
void check(const Settings & current_settings, const SettingsChanges & changes, SettingSource source) const;
|
void check(const Settings & current_settings, const SettingsChanges & changes, SettingSource source) const;
|
||||||
void check(const Settings & current_settings, SettingsChanges & changes, SettingSource source) const;
|
void check(const Settings & current_settings, SettingsChanges & changes, SettingSource source) const;
|
||||||
|
void check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const;
|
||||||
|
void check(const Settings & current_settings, const AlterSettingsProfileElements & profile_elements, SettingSource source) const;
|
||||||
|
|
||||||
/// Checks whether `change` violates these constraints and throws an exception if so. (setting short name is expected inside `changes`)
|
/// Checks whether `change` violates these constraints and throws an exception if so. (setting short name is expected inside `changes`)
|
||||||
void check(const MergeTreeSettings & current_settings, const SettingChange & change) const;
|
void check(const MergeTreeSettings & current_settings, const SettingChange & change) const;
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include <IO/WriteHelpers.h>
|
#include <IO/WriteHelpers.h>
|
||||||
#include <Parsers/Access/ASTSettingsProfileElement.h>
|
#include <Parsers/Access/ASTSettingsProfileElement.h>
|
||||||
#include <base/removeDuplicates.h>
|
#include <base/removeDuplicates.h>
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
#include <boost/container/flat_set.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -19,6 +21,7 @@ namespace ErrorCodes
|
|||||||
extern const int NOT_IMPLEMENTED;
|
extern const int NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsProfileElement::SettingsProfileElement(const ASTSettingsProfileElement & ast)
|
SettingsProfileElement::SettingsProfileElement(const ASTSettingsProfileElement & ast)
|
||||||
{
|
{
|
||||||
init(ast, nullptr);
|
init(ast, nullptr);
|
||||||
@ -116,16 +119,20 @@ std::shared_ptr<ASTSettingsProfileElement> SettingsProfileElement::toASTWithName
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SettingsProfileElements::SettingsProfileElements(const ASTSettingsProfileElements & ast)
|
SettingsProfileElements::SettingsProfileElements(const ASTSettingsProfileElements & ast, bool normalize_)
|
||||||
{
|
{
|
||||||
for (const auto & ast_element : ast.elements)
|
for (const auto & ast_element : ast.elements)
|
||||||
emplace_back(*ast_element);
|
emplace_back(*ast_element);
|
||||||
|
if (normalize_)
|
||||||
|
normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsProfileElements::SettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control)
|
SettingsProfileElements::SettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control, bool normalize_)
|
||||||
{
|
{
|
||||||
for (const auto & ast_element : ast.elements)
|
for (const auto & ast_element : ast.elements)
|
||||||
emplace_back(*ast_element, access_control);
|
emplace_back(*ast_element, access_control);
|
||||||
|
if (normalize_)
|
||||||
|
normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -133,7 +140,11 @@ std::shared_ptr<ASTSettingsProfileElements> SettingsProfileElements::toAST() con
|
|||||||
{
|
{
|
||||||
auto res = std::make_shared<ASTSettingsProfileElements>();
|
auto res = std::make_shared<ASTSettingsProfileElements>();
|
||||||
for (const auto & element : *this)
|
for (const auto & element : *this)
|
||||||
res->elements.push_back(element.toAST());
|
{
|
||||||
|
auto element_ast = element.toAST();
|
||||||
|
if (!element_ast->empty())
|
||||||
|
res->elements.push_back(element_ast);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +152,11 @@ std::shared_ptr<ASTSettingsProfileElements> SettingsProfileElements::toASTWithNa
|
|||||||
{
|
{
|
||||||
auto res = std::make_shared<ASTSettingsProfileElements>();
|
auto res = std::make_shared<ASTSettingsProfileElements>();
|
||||||
for (const auto & element : *this)
|
for (const auto & element : *this)
|
||||||
res->elements.push_back(element.toASTWithNames(access_control));
|
{
|
||||||
|
auto element_ast = element.toASTWithNames(access_control);
|
||||||
|
if (!element_ast->empty())
|
||||||
|
res->elements.push_back(element_ast);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,9 +235,11 @@ void SettingsProfileElements::removeSettingsKeepProfiles()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SettingsProfileElements::merge(const SettingsProfileElements & other)
|
void SettingsProfileElements::merge(const SettingsProfileElements & other, bool normalize_)
|
||||||
{
|
{
|
||||||
insert(end(), other.begin(), other.end());
|
insert(end(), other.begin(), other.end());
|
||||||
|
if (normalize_)
|
||||||
|
normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -280,6 +297,81 @@ std::vector<UUID> SettingsProfileElements::toProfileIDs() const
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SettingsProfileElements::normalize()
|
||||||
|
{
|
||||||
|
/// Ensure that each element represents either a setting or a profile.
|
||||||
|
{
|
||||||
|
SettingsProfileElements new_elements;
|
||||||
|
for (auto & element : *this)
|
||||||
|
{
|
||||||
|
if (element.parent_profile && !element.setting_name.empty())
|
||||||
|
{
|
||||||
|
SettingsProfileElement new_element;
|
||||||
|
new_element.parent_profile = element.parent_profile;
|
||||||
|
element.parent_profile.reset();
|
||||||
|
new_elements.push_back(std::move(new_element));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
insert(end(), new_elements.begin(), new_elements.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Partitioning: first profiles, then settings.
|
||||||
|
/// We use std::stable_partition() here because we want to preserve the relative order of profiles and the relative order of settings.
|
||||||
|
/// (We need that order to be preserved to remove duplicates correctly - see below.)
|
||||||
|
auto profiles_begin = begin();
|
||||||
|
auto profiles_end = std::stable_partition(begin(), end(), [](const SettingsProfileElement & element) { return static_cast<bool>(element.parent_profile); });
|
||||||
|
auto settings_begin = profiles_end;
|
||||||
|
auto settings_end = end();
|
||||||
|
|
||||||
|
/// Remove duplicates among profiles.
|
||||||
|
/// We keep the last position of any used profile.
|
||||||
|
/// It's important to keep exactly the last position (and not just any position) because profiles can override settings from each other.
|
||||||
|
/// For example, [pr_A, pr_B, pr_A, pr_C] is always the same as [pr_B, pr_A, pr_C], but can be not the same as [pr_A, pr_B, pr_C]
|
||||||
|
/// if pr_A and pr_B give different values to same settings.
|
||||||
|
{
|
||||||
|
boost::container::flat_set<UUID> profile_ids;
|
||||||
|
profile_ids.reserve(profiles_end - profiles_begin);
|
||||||
|
auto it = profiles_end;
|
||||||
|
while (it != profiles_begin)
|
||||||
|
{
|
||||||
|
--it;
|
||||||
|
auto & element = *it;
|
||||||
|
if (element.parent_profile && !profile_ids.emplace(*element.parent_profile).second)
|
||||||
|
element.parent_profile.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove duplicates among settings.
|
||||||
|
/// We keep the first position of any used setting, and merge settings with the same name to that first element.
|
||||||
|
{
|
||||||
|
boost::container::flat_map<std::string_view, SettingsProfileElements::iterator> setting_name_to_first_encounter;
|
||||||
|
setting_name_to_first_encounter.reserve(settings_end - settings_begin);
|
||||||
|
for (auto it = settings_begin; it != settings_end; ++it)
|
||||||
|
{
|
||||||
|
auto & element = *it;
|
||||||
|
auto first = setting_name_to_first_encounter.emplace(element.setting_name, it).first->second;
|
||||||
|
if (it != first)
|
||||||
|
{
|
||||||
|
auto & first_element = *first;
|
||||||
|
if (element.value)
|
||||||
|
first_element.value = element.value;
|
||||||
|
if (element.min_value)
|
||||||
|
first_element.min_value = element.min_value;
|
||||||
|
if (element.max_value)
|
||||||
|
first_element.max_value = element.max_value;
|
||||||
|
if (element.writability)
|
||||||
|
first_element.writability = element.writability;
|
||||||
|
element.setting_name.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove empty elements.
|
||||||
|
std::erase_if(*this, [](const SettingsProfileElement & element) { return element.empty(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SettingsProfileElements::isBackupAllowed() const
|
bool SettingsProfileElements::isBackupAllowed() const
|
||||||
{
|
{
|
||||||
for (const auto & setting : *this)
|
for (const auto & setting : *this)
|
||||||
@ -296,4 +388,139 @@ bool SettingsProfileElements::isAllowBackupSetting(const String & setting_name)
|
|||||||
return Settings::resolveName(setting_name) == ALLOW_BACKUP_SETTING_NAME;
|
return Settings::resolveName(setting_name) == ALLOW_BACKUP_SETTING_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
AlterSettingsProfileElements::AlterSettingsProfileElements(const SettingsProfileElements & ast)
|
||||||
|
{
|
||||||
|
drop_all_settings = true;
|
||||||
|
drop_all_profiles = true;
|
||||||
|
add_settings = ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTSettingsProfileElements & ast)
|
||||||
|
: AlterSettingsProfileElements(SettingsProfileElements{ast})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control)
|
||||||
|
: AlterSettingsProfileElements(SettingsProfileElements{ast, access_control})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast)
|
||||||
|
{
|
||||||
|
drop_all_settings = ast.drop_all_settings;
|
||||||
|
drop_all_profiles = ast.drop_all_profiles;
|
||||||
|
|
||||||
|
if (ast.add_settings)
|
||||||
|
add_settings = SettingsProfileElements{*ast.add_settings, /* normalize= */ false}; /// For "ALTER" the normalization is unnecessary.
|
||||||
|
|
||||||
|
if (ast.modify_settings)
|
||||||
|
modify_settings = SettingsProfileElements{*ast.modify_settings, /* normalize= */ false};
|
||||||
|
|
||||||
|
if (ast.drop_settings)
|
||||||
|
drop_settings = SettingsProfileElements{*ast.drop_settings, /* normalize= */ false};
|
||||||
|
}
|
||||||
|
|
||||||
|
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast, const AccessControl & access_control)
|
||||||
|
{
|
||||||
|
drop_all_settings = ast.drop_all_settings;
|
||||||
|
drop_all_profiles = ast.drop_all_profiles;
|
||||||
|
|
||||||
|
if (ast.add_settings)
|
||||||
|
add_settings = SettingsProfileElements{*ast.add_settings, access_control, /* normalize= */ false}; /// For "ALTER" the normalization is unnecessary.
|
||||||
|
|
||||||
|
if (ast.modify_settings)
|
||||||
|
modify_settings = SettingsProfileElements{*ast.modify_settings, access_control, /* normalize= */ false};
|
||||||
|
|
||||||
|
if (ast.drop_settings)
|
||||||
|
drop_settings = SettingsProfileElements{*ast.drop_settings, access_control, /* normalize= */ false};
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsProfileElements::applyChanges(const AlterSettingsProfileElements & changes)
|
||||||
|
{
|
||||||
|
/// Apply "DROP" changes.
|
||||||
|
if (changes.drop_all_profiles)
|
||||||
|
{
|
||||||
|
for (auto & element : *this)
|
||||||
|
element.parent_profile.reset(); /// We only make this element empty, the element will be removed in normalizeProfileElements().
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.drop_all_settings)
|
||||||
|
{
|
||||||
|
for (auto & element : *this)
|
||||||
|
element.setting_name.clear(); /// We only make this element empty, the element will be removed in normalizeProfileElements().
|
||||||
|
}
|
||||||
|
|
||||||
|
auto apply_drop_setting = [&](const String & setting_name)
|
||||||
|
{
|
||||||
|
for (auto & element : *this)
|
||||||
|
{
|
||||||
|
if (element.setting_name == setting_name)
|
||||||
|
element.setting_name.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto apply_drop_profile = [&](const UUID & profile_id)
|
||||||
|
{
|
||||||
|
for (auto & element : *this)
|
||||||
|
{
|
||||||
|
if (element.parent_profile == profile_id)
|
||||||
|
element.parent_profile.reset();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto & drop : changes.drop_settings)
|
||||||
|
{
|
||||||
|
if (drop.parent_profile)
|
||||||
|
apply_drop_profile(*drop.parent_profile);
|
||||||
|
if (!drop.setting_name.empty())
|
||||||
|
apply_drop_setting(drop.setting_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto apply_modify_setting = [&](const SettingsProfileElement & modify)
|
||||||
|
{
|
||||||
|
SettingsProfileElement new_element;
|
||||||
|
new_element.setting_name = modify.setting_name;
|
||||||
|
new_element.value = modify.value;
|
||||||
|
new_element.min_value = modify.min_value;
|
||||||
|
new_element.max_value = modify.max_value;
|
||||||
|
new_element.writability = modify.writability;
|
||||||
|
push_back(new_element); /// normalizeProfileElements() will merge this new element with the previous elements.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Apply "ADD" changes.
|
||||||
|
auto apply_add_setting = [&](const SettingsProfileElement & add)
|
||||||
|
{
|
||||||
|
/// "ADD SETTING" must replace the value and the constraints of a setting, so first we need drop the previous elements for that setting.
|
||||||
|
apply_drop_setting(add.setting_name);
|
||||||
|
apply_modify_setting(add);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto apply_add_profile = [&](const UUID & profile_id)
|
||||||
|
{
|
||||||
|
SettingsProfileElement new_element;
|
||||||
|
new_element.parent_profile = profile_id;
|
||||||
|
push_back(new_element); /// We don't care about possible duplicates here, normalizeProfileElements() will remove duplicates.
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto & add : changes.add_settings)
|
||||||
|
{
|
||||||
|
if (add.parent_profile)
|
||||||
|
apply_add_profile(*add.parent_profile);
|
||||||
|
if (!add.setting_name.empty())
|
||||||
|
apply_add_setting(add);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply "MODIFY" changes.
|
||||||
|
for (const auto & modify : changes.modify_settings)
|
||||||
|
{
|
||||||
|
chassert(!modify.parent_profile); /// There is no such thing as "MODIFY PROFILE".
|
||||||
|
if (!modify.setting_name.empty())
|
||||||
|
apply_modify_setting(modify);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove empty elements and duplicates, and sort the result.
|
||||||
|
normalize();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,10 @@ namespace DB
|
|||||||
struct Settings;
|
struct Settings;
|
||||||
class SettingsChanges;
|
class SettingsChanges;
|
||||||
class SettingsConstraints;
|
class SettingsConstraints;
|
||||||
|
struct AlterSettingsProfileElements;
|
||||||
class ASTSettingsProfileElement;
|
class ASTSettingsProfileElement;
|
||||||
class ASTSettingsProfileElements;
|
class ASTSettingsProfileElements;
|
||||||
|
class ASTAlterSettingsProfileElements;
|
||||||
class AccessControl;
|
class AccessControl;
|
||||||
|
|
||||||
|
|
||||||
@ -44,6 +46,8 @@ struct SettingsProfileElement
|
|||||||
std::shared_ptr<ASTSettingsProfileElement> toAST() const;
|
std::shared_ptr<ASTSettingsProfileElement> toAST() const;
|
||||||
std::shared_ptr<ASTSettingsProfileElement> toASTWithNames(const AccessControl & access_control) const;
|
std::shared_ptr<ASTSettingsProfileElement> toASTWithNames(const AccessControl & access_control) const;
|
||||||
|
|
||||||
|
bool empty() const { return !parent_profile && (setting_name.empty() || (!value && !min_value && !max_value && !writability)); }
|
||||||
|
|
||||||
bool isConstraint() const;
|
bool isConstraint() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -57,8 +61,9 @@ public:
|
|||||||
SettingsProfileElements() = default;
|
SettingsProfileElements() = default;
|
||||||
|
|
||||||
/// The constructor from AST requires the AccessControl if `ast.id_mode == false`.
|
/// The constructor from AST requires the AccessControl if `ast.id_mode == false`.
|
||||||
SettingsProfileElements(const ASTSettingsProfileElements & ast); /// NOLINT
|
SettingsProfileElements(const ASTSettingsProfileElements & ast, bool normalize_ = true); /// NOLINT
|
||||||
SettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control);
|
SettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control, bool normalize_ = true);
|
||||||
|
|
||||||
std::shared_ptr<ASTSettingsProfileElements> toAST() const;
|
std::shared_ptr<ASTSettingsProfileElements> toAST() const;
|
||||||
std::shared_ptr<ASTSettingsProfileElements> toASTWithNames(const AccessControl & access_control) const;
|
std::shared_ptr<ASTSettingsProfileElements> toASTWithNames(const AccessControl & access_control) const;
|
||||||
|
|
||||||
@ -70,16 +75,41 @@ public:
|
|||||||
|
|
||||||
void removeSettingsKeepProfiles();
|
void removeSettingsKeepProfiles();
|
||||||
|
|
||||||
void merge(const SettingsProfileElements & other);
|
|
||||||
|
|
||||||
Settings toSettings() const;
|
Settings toSettings() const;
|
||||||
SettingsChanges toSettingsChanges() const;
|
SettingsChanges toSettingsChanges() const;
|
||||||
SettingsConstraints toSettingsConstraints(const AccessControl & access_control) const;
|
SettingsConstraints toSettingsConstraints(const AccessControl & access_control) const;
|
||||||
std::vector<UUID> toProfileIDs() const;
|
std::vector<UUID> toProfileIDs() const;
|
||||||
|
|
||||||
bool isBackupAllowed() const;
|
/// Normalizes this list of profile elements: removes duplicates and empty elements, and also sorts the elements
|
||||||
|
/// in the following order: first profiles, then settings.
|
||||||
|
/// The function is called automatically after parsing profile elements from an AST and
|
||||||
|
/// at the end of an "ALTER PROFILE (USER/ROLE) command".
|
||||||
|
void normalize();
|
||||||
|
|
||||||
|
/// Appends all the elements of another list of profile elements to this list.
|
||||||
|
void merge(const SettingsProfileElements & other, bool normalize_ = true);
|
||||||
|
|
||||||
|
/// Applies changes from an "ALTER PROFILE (USER/ROLE)" command. Always normalizes the result.
|
||||||
|
void applyChanges(const AlterSettingsProfileElements & changes);
|
||||||
|
|
||||||
|
bool isBackupAllowed() const;
|
||||||
static bool isAllowBackupSetting(const String & setting_name);
|
static bool isAllowBackupSetting(const String & setting_name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AlterSettingsProfileElements
|
||||||
|
{
|
||||||
|
bool drop_all_settings = false;
|
||||||
|
bool drop_all_profiles = false;
|
||||||
|
SettingsProfileElements add_settings;
|
||||||
|
SettingsProfileElements modify_settings;
|
||||||
|
SettingsProfileElements drop_settings;
|
||||||
|
|
||||||
|
AlterSettingsProfileElements() = default;
|
||||||
|
explicit AlterSettingsProfileElements(const SettingsProfileElements & ast);
|
||||||
|
explicit AlterSettingsProfileElements(const ASTSettingsProfileElements & ast);
|
||||||
|
explicit AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast);
|
||||||
|
AlterSettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control);
|
||||||
|
AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast, const AccessControl & access_control);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -135,8 +135,8 @@ void SettingsProfilesCache::mergeSettingsAndConstraintsFor(EnabledSettings & ena
|
|||||||
merged_settings.emplace_back(new_element);
|
merged_settings.emplace_back(new_element);
|
||||||
}
|
}
|
||||||
|
|
||||||
merged_settings.merge(enabled.params.settings_from_enabled_roles);
|
merged_settings.merge(enabled.params.settings_from_enabled_roles, /* normalize= */ false);
|
||||||
merged_settings.merge(enabled.params.settings_from_user);
|
merged_settings.merge(enabled.params.settings_from_user, /* normalize= */ false);
|
||||||
|
|
||||||
auto info = std::make_shared<SettingsProfilesInfo>(access_control);
|
auto info = std::make_shared<SettingsProfilesInfo>(access_control);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ namespace
|
|||||||
Role & role,
|
Role & role,
|
||||||
const ASTCreateRoleQuery & query,
|
const ASTCreateRoleQuery & query,
|
||||||
const String & override_name,
|
const String & override_name,
|
||||||
const std::optional<SettingsProfileElements> & override_settings)
|
const std::optional<AlterSettingsProfileElements> & override_settings)
|
||||||
{
|
{
|
||||||
if (!override_name.empty())
|
if (!override_name.empty())
|
||||||
role.setName(override_name);
|
role.setName(override_name);
|
||||||
@ -33,9 +33,11 @@ namespace
|
|||||||
role.setName(query.names.front());
|
role.setName(query.names.front());
|
||||||
|
|
||||||
if (override_settings)
|
if (override_settings)
|
||||||
role.settings = *override_settings;
|
role.settings.applyChanges(*override_settings);
|
||||||
|
else if (query.alter_settings)
|
||||||
|
role.settings.applyChanges(AlterSettingsProfileElements{*query.alter_settings});
|
||||||
else if (query.settings)
|
else if (query.settings)
|
||||||
role.settings = *query.settings;
|
role.settings.applyChanges(AlterSettingsProfileElements{*query.settings});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,14 +53,14 @@ BlockIO InterpreterCreateRoleQuery::execute()
|
|||||||
else
|
else
|
||||||
getContext()->checkAccess(AccessType::CREATE_ROLE);
|
getContext()->checkAccess(AccessType::CREATE_ROLE);
|
||||||
|
|
||||||
std::optional<SettingsProfileElements> settings_from_query;
|
std::optional<AlterSettingsProfileElements> settings_from_query;
|
||||||
if (query.settings)
|
if (query.alter_settings)
|
||||||
{
|
settings_from_query = AlterSettingsProfileElements{*query.alter_settings, access_control};
|
||||||
settings_from_query = SettingsProfileElements{*query.settings, access_control};
|
else if (query.settings)
|
||||||
|
settings_from_query = AlterSettingsProfileElements{SettingsProfileElements(*query.settings, access_control)};
|
||||||
|
|
||||||
if (!query.attach)
|
if (settings_from_query && !query.attach)
|
||||||
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::ROLE);
|
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::ROLE);
|
||||||
}
|
|
||||||
|
|
||||||
if (!query.cluster.empty())
|
if (!query.cluster.empty())
|
||||||
return executeDDLQueryOnCluster(updated_query_ptr, getContext());
|
return executeDDLQueryOnCluster(updated_query_ptr, getContext());
|
||||||
|
@ -25,7 +25,7 @@ namespace
|
|||||||
SettingsProfile & profile,
|
SettingsProfile & profile,
|
||||||
const ASTCreateSettingsProfileQuery & query,
|
const ASTCreateSettingsProfileQuery & query,
|
||||||
const String & override_name,
|
const String & override_name,
|
||||||
const std::optional<SettingsProfileElements> & override_settings,
|
const std::optional<AlterSettingsProfileElements> & override_settings,
|
||||||
const std::optional<RolesOrUsersSet> & override_to_roles)
|
const std::optional<RolesOrUsersSet> & override_to_roles)
|
||||||
{
|
{
|
||||||
if (!override_name.empty())
|
if (!override_name.empty())
|
||||||
@ -36,9 +36,11 @@ namespace
|
|||||||
profile.setName(query.names.front());
|
profile.setName(query.names.front());
|
||||||
|
|
||||||
if (override_settings)
|
if (override_settings)
|
||||||
profile.elements = *override_settings;
|
profile.elements.applyChanges(*override_settings);
|
||||||
|
else if (query.alter_settings)
|
||||||
|
profile.elements.applyChanges(AlterSettingsProfileElements{*query.alter_settings});
|
||||||
else if (query.settings)
|
else if (query.settings)
|
||||||
profile.elements = *query.settings;
|
profile.elements.applyChanges(AlterSettingsProfileElements{*query.settings});
|
||||||
|
|
||||||
if (override_to_roles)
|
if (override_to_roles)
|
||||||
profile.to_roles = *override_to_roles;
|
profile.to_roles = *override_to_roles;
|
||||||
@ -59,14 +61,14 @@ BlockIO InterpreterCreateSettingsProfileQuery::execute()
|
|||||||
else
|
else
|
||||||
getContext()->checkAccess(AccessType::CREATE_SETTINGS_PROFILE);
|
getContext()->checkAccess(AccessType::CREATE_SETTINGS_PROFILE);
|
||||||
|
|
||||||
std::optional<SettingsProfileElements> settings_from_query;
|
std::optional<AlterSettingsProfileElements> settings_from_query;
|
||||||
if (query.settings)
|
if (query.alter_settings)
|
||||||
{
|
settings_from_query = AlterSettingsProfileElements{*query.alter_settings, access_control};
|
||||||
settings_from_query = SettingsProfileElements{*query.settings, access_control};
|
else if (query.settings)
|
||||||
|
settings_from_query = AlterSettingsProfileElements{SettingsProfileElements(*query.settings, access_control)};
|
||||||
|
|
||||||
if (!query.attach)
|
if (settings_from_query && !query.attach)
|
||||||
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::PROFILE);
|
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::PROFILE);
|
||||||
}
|
|
||||||
|
|
||||||
if (!query.cluster.empty())
|
if (!query.cluster.empty())
|
||||||
{
|
{
|
||||||
|
@ -43,7 +43,7 @@ namespace
|
|||||||
const std::vector<AuthenticationData> authentication_methods,
|
const std::vector<AuthenticationData> authentication_methods,
|
||||||
const std::shared_ptr<ASTUserNameWithHost> & override_name,
|
const std::shared_ptr<ASTUserNameWithHost> & override_name,
|
||||||
const std::optional<RolesOrUsersSet> & override_default_roles,
|
const std::optional<RolesOrUsersSet> & override_default_roles,
|
||||||
const std::optional<SettingsProfileElements> & override_settings,
|
const std::optional<AlterSettingsProfileElements> & override_settings,
|
||||||
const std::optional<RolesOrUsersSet> & override_grantees,
|
const std::optional<RolesOrUsersSet> & override_grantees,
|
||||||
const std::optional<time_t> & global_valid_until,
|
const std::optional<time_t> & global_valid_until,
|
||||||
bool reset_authentication_methods,
|
bool reset_authentication_methods,
|
||||||
@ -172,9 +172,11 @@ namespace
|
|||||||
user.default_database = query.default_database->database_name;
|
user.default_database = query.default_database->database_name;
|
||||||
|
|
||||||
if (override_settings)
|
if (override_settings)
|
||||||
user.settings = *override_settings;
|
user.settings.applyChanges(*override_settings);
|
||||||
|
else if (query.alter_settings)
|
||||||
|
user.settings.applyChanges(AlterSettingsProfileElements{*query.alter_settings});
|
||||||
else if (query.settings)
|
else if (query.settings)
|
||||||
user.settings = *query.settings;
|
user.settings.applyChanges(AlterSettingsProfileElements{*query.settings});
|
||||||
|
|
||||||
if (override_grantees)
|
if (override_grantees)
|
||||||
user.grantees = *override_grantees;
|
user.grantees = *override_grantees;
|
||||||
@ -219,14 +221,14 @@ BlockIO InterpreterCreateUserQuery::execute()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SettingsProfileElements> settings_from_query;
|
std::optional<AlterSettingsProfileElements> settings_from_query;
|
||||||
if (query.settings)
|
if (query.alter_settings)
|
||||||
{
|
settings_from_query = AlterSettingsProfileElements{*query.alter_settings, access_control};
|
||||||
settings_from_query = SettingsProfileElements{*query.settings, access_control};
|
else if (query.settings)
|
||||||
|
settings_from_query = AlterSettingsProfileElements{*query.settings, access_control};
|
||||||
|
|
||||||
if (!query.attach)
|
if (settings_from_query && !query.attach)
|
||||||
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::USER);
|
getContext()->checkSettingsConstraints(*settings_from_query, SettingSource::USER);
|
||||||
}
|
|
||||||
|
|
||||||
if (!query.cluster.empty())
|
if (!query.cluster.empty())
|
||||||
return executeDDLQueryOnCluster(updated_query_ptr, getContext());
|
return executeDDLQueryOnCluster(updated_query_ptr, getContext());
|
||||||
|
@ -71,10 +71,13 @@ namespace
|
|||||||
|
|
||||||
if (!user.settings.empty())
|
if (!user.settings.empty())
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> query_settings;
|
||||||
if (attach_mode)
|
if (attach_mode)
|
||||||
query->settings = user.settings.toAST();
|
query_settings = user.settings.toAST();
|
||||||
else
|
else
|
||||||
query->settings = user.settings.toASTWithNames(*access_control);
|
query_settings = user.settings.toASTWithNames(*access_control);
|
||||||
|
if (!query_settings->empty())
|
||||||
|
query->settings = query_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.grantees != RolesOrUsersSet::AllTag{})
|
if (user.grantees != RolesOrUsersSet::AllTag{})
|
||||||
@ -105,10 +108,13 @@ namespace
|
|||||||
|
|
||||||
if (!role.settings.empty())
|
if (!role.settings.empty())
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> query_settings;
|
||||||
if (attach_mode)
|
if (attach_mode)
|
||||||
query->settings = role.settings.toAST();
|
query_settings = role.settings.toAST();
|
||||||
else
|
else
|
||||||
query->settings = role.settings.toASTWithNames(*access_control);
|
query_settings = role.settings.toASTWithNames(*access_control);
|
||||||
|
if (!query_settings->empty())
|
||||||
|
query->settings = query_settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
@ -123,12 +129,16 @@ namespace
|
|||||||
|
|
||||||
if (!profile.elements.empty())
|
if (!profile.elements.empty())
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> query_settings;
|
||||||
if (attach_mode)
|
if (attach_mode)
|
||||||
query->settings = profile.elements.toAST();
|
query_settings = profile.elements.toAST();
|
||||||
else
|
else
|
||||||
query->settings = profile.elements.toASTWithNames(*access_control);
|
query_settings = profile.elements.toASTWithNames(*access_control);
|
||||||
if (query->settings)
|
if (!query_settings->empty())
|
||||||
query->settings->setUseInheritKeyword(true);
|
{
|
||||||
|
query_settings->setUseInheritKeyword(true);
|
||||||
|
query->settings = query_settings;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profile.to_roles.empty())
|
if (!profile.to_roles.empty())
|
||||||
|
@ -2521,7 +2521,7 @@ void Context::applySettingsChanges(const SettingsChanges & changes)
|
|||||||
applySettingsChangesWithLock(changes, lock);
|
applySettingsChangesWithLock(changes, lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::checkSettingsConstraintsWithLock(const SettingsProfileElements & profile_elements, SettingSource source)
|
void Context::checkSettingsConstraintsWithLock(const AlterSettingsProfileElements & profile_elements, SettingSource source)
|
||||||
{
|
{
|
||||||
getSettingsConstraintsAndCurrentProfilesWithLock()->constraints.check(*settings, profile_elements, source);
|
getSettingsConstraintsAndCurrentProfilesWithLock()->constraints.check(*settings, profile_elements, source);
|
||||||
if (getApplicationType() == ApplicationType::LOCAL || getApplicationType() == ApplicationType::SERVER)
|
if (getApplicationType() == ApplicationType::LOCAL || getApplicationType() == ApplicationType::SERVER)
|
||||||
@ -2561,7 +2561,7 @@ void Context::checkMergeTreeSettingsConstraintsWithLock(const MergeTreeSettings
|
|||||||
getSettingsConstraintsAndCurrentProfilesWithLock()->constraints.check(merge_tree_settings, changes);
|
getSettingsConstraintsAndCurrentProfilesWithLock()->constraints.check(merge_tree_settings, changes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Context::checkSettingsConstraints(const SettingsProfileElements & profile_elements, SettingSource source)
|
void Context::checkSettingsConstraints(const AlterSettingsProfileElements & profile_elements, SettingSource source)
|
||||||
{
|
{
|
||||||
SharedLockGuard lock(mutex);
|
SharedLockGuard lock(mutex);
|
||||||
checkSettingsConstraintsWithLock(profile_elements, source);
|
checkSettingsConstraintsWithLock(profile_elements, source);
|
||||||
|
@ -145,7 +145,7 @@ struct Settings;
|
|||||||
struct SettingChange;
|
struct SettingChange;
|
||||||
class SettingsChanges;
|
class SettingsChanges;
|
||||||
struct SettingsConstraintsAndProfileIDs;
|
struct SettingsConstraintsAndProfileIDs;
|
||||||
class SettingsProfileElements;
|
struct AlterSettingsProfileElements;
|
||||||
class RemoteHostFilter;
|
class RemoteHostFilter;
|
||||||
class IDisk;
|
class IDisk;
|
||||||
using DiskPtr = std::shared_ptr<IDisk>;
|
using DiskPtr = std::shared_ptr<IDisk>;
|
||||||
@ -865,7 +865,7 @@ public:
|
|||||||
void applySettingsChanges(const SettingsChanges & changes);
|
void applySettingsChanges(const SettingsChanges & changes);
|
||||||
|
|
||||||
/// Checks the constraints.
|
/// Checks the constraints.
|
||||||
void checkSettingsConstraints(const SettingsProfileElements & profile_elements, SettingSource source);
|
void checkSettingsConstraints(const AlterSettingsProfileElements & profile_elements, SettingSource source);
|
||||||
void checkSettingsConstraints(const SettingChange & change, SettingSource source);
|
void checkSettingsConstraints(const SettingChange & change, SettingSource source);
|
||||||
void checkSettingsConstraints(const SettingsChanges & changes, SettingSource source);
|
void checkSettingsConstraints(const SettingsChanges & changes, SettingSource source);
|
||||||
void checkSettingsConstraints(SettingsChanges & changes, SettingSource source);
|
void checkSettingsConstraints(SettingsChanges & changes, SettingSource source);
|
||||||
@ -1413,7 +1413,7 @@ private:
|
|||||||
|
|
||||||
void setCurrentDatabaseWithLock(const String & name, const std::lock_guard<ContextSharedMutex> & lock);
|
void setCurrentDatabaseWithLock(const String & name, const std::lock_guard<ContextSharedMutex> & lock);
|
||||||
|
|
||||||
void checkSettingsConstraintsWithLock(const SettingsProfileElements & profile_elements, SettingSource source);
|
void checkSettingsConstraintsWithLock(const AlterSettingsProfileElements & profile_elements, SettingSource source);
|
||||||
|
|
||||||
void checkSettingsConstraintsWithLock(const SettingChange & change, SettingSource source);
|
void checkSettingsConstraintsWithLock(const SettingChange & change, SettingSource source);
|
||||||
|
|
||||||
@ -1422,6 +1422,9 @@ private:
|
|||||||
void checkSettingsConstraintsWithLock(SettingsChanges & changes, SettingSource source);
|
void checkSettingsConstraintsWithLock(SettingsChanges & changes, SettingSource source);
|
||||||
|
|
||||||
void clampToSettingsConstraintsWithLock(SettingsChanges & changes, SettingSource source);
|
void clampToSettingsConstraintsWithLock(SettingsChanges & changes, SettingSource source);
|
||||||
|
void checkSettingsConstraintsWithLock(const AlterSettingsProfileElements & profile_elements, SettingSource source) const;
|
||||||
|
|
||||||
|
void clampToSettingsConstraintsWithLock(SettingsChanges & changes, SettingSource source) const;
|
||||||
|
|
||||||
void checkMergeTreeSettingsConstraintsWithLock(const MergeTreeSettings & merge_tree_settings, const SettingsChanges & changes) const;
|
void checkMergeTreeSettingsConstraintsWithLock(const MergeTreeSettings & merge_tree_settings, const SettingsChanges & changes) const;
|
||||||
|
|
||||||
|
@ -31,6 +31,12 @@ namespace
|
|||||||
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " SETTINGS " << (format.hilite ? IAST::hilite_none : "");
|
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " SETTINGS " << (format.hilite ? IAST::hilite_none : "");
|
||||||
settings.format(format);
|
settings.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void formatAlterSettings(const ASTAlterSettingsProfileElements & alter_settings, const IAST::FormatSettings & format)
|
||||||
|
{
|
||||||
|
format.ostr << " ";
|
||||||
|
alter_settings.format(format);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -47,6 +53,9 @@ ASTPtr ASTCreateRoleQuery::clone() const
|
|||||||
if (settings)
|
if (settings)
|
||||||
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
||||||
|
|
||||||
|
if (alter_settings)
|
||||||
|
res->alter_settings = std::static_pointer_cast<ASTAlterSettingsProfileElements>(alter_settings->clone());
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +91,9 @@ void ASTCreateRoleQuery::formatImpl(const FormatSettings & format, FormatState &
|
|||||||
if (!new_name.empty())
|
if (!new_name.empty())
|
||||||
formatRenameTo(new_name, format);
|
formatRenameTo(new_name, format);
|
||||||
|
|
||||||
if (settings && (!settings->empty() || alter))
|
if (alter_settings)
|
||||||
|
formatAlterSettings(*alter_settings, format);
|
||||||
|
else if (settings)
|
||||||
formatSettings(*settings, format);
|
formatSettings(*settings, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
class ASTSettingsProfileElements;
|
class ASTSettingsProfileElements;
|
||||||
|
class ASTAlterSettingsProfileElements;
|
||||||
|
|
||||||
|
|
||||||
/** CREATE ROLE [IF NOT EXISTS | OR REPLACE] name
|
/** CREATE ROLE [IF NOT EXISTS | OR REPLACE] name
|
||||||
@ -14,7 +15,12 @@ class ASTSettingsProfileElements;
|
|||||||
*
|
*
|
||||||
* ALTER ROLE [IF EXISTS] name
|
* ALTER ROLE [IF EXISTS] name
|
||||||
* [RENAME TO new_name]
|
* [RENAME TO new_name]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
*/
|
*/
|
||||||
class ASTCreateRoleQuery : public IAST, public ASTQueryWithOnCluster
|
class ASTCreateRoleQuery : public IAST, public ASTQueryWithOnCluster
|
||||||
{
|
{
|
||||||
@ -31,6 +37,7 @@ public:
|
|||||||
String storage_name;
|
String storage_name;
|
||||||
|
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
|
|
||||||
String getID(char) const override;
|
String getID(char) const override;
|
||||||
ASTPtr clone() const override;
|
ASTPtr clone() const override;
|
||||||
|
@ -33,6 +33,12 @@ namespace
|
|||||||
settings.format(format);
|
settings.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void formatAlterSettings(const ASTAlterSettingsProfileElements & alter_settings, const IAST::FormatSettings & format)
|
||||||
|
{
|
||||||
|
format.ostr << " ";
|
||||||
|
alter_settings.format(format);
|
||||||
|
}
|
||||||
|
|
||||||
void formatToRoles(const ASTRolesOrUsersSet & roles, const IAST::FormatSettings & settings)
|
void formatToRoles(const ASTRolesOrUsersSet & roles, const IAST::FormatSettings & settings)
|
||||||
{
|
{
|
||||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " TO " << (settings.hilite ? IAST::hilite_none : "");
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " TO " << (settings.hilite ? IAST::hilite_none : "");
|
||||||
@ -57,6 +63,9 @@ ASTPtr ASTCreateSettingsProfileQuery::clone() const
|
|||||||
if (settings)
|
if (settings)
|
||||||
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
||||||
|
|
||||||
|
if (alter_settings)
|
||||||
|
res->alter_settings = std::static_pointer_cast<ASTAlterSettingsProfileElements>(alter_settings->clone());
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,7 +101,9 @@ void ASTCreateSettingsProfileQuery::formatImpl(const FormatSettings & format, Fo
|
|||||||
if (!new_name.empty())
|
if (!new_name.empty())
|
||||||
formatRenameTo(new_name, format);
|
formatRenameTo(new_name, format);
|
||||||
|
|
||||||
if (settings && (!settings->empty() || alter))
|
if (alter_settings)
|
||||||
|
formatAlterSettings(*alter_settings, format);
|
||||||
|
else if (settings)
|
||||||
formatSettings(*settings, format);
|
formatSettings(*settings, format);
|
||||||
|
|
||||||
if (to_roles && (!to_roles->empty() || alter))
|
if (to_roles && (!to_roles->empty() || alter))
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
class ASTSettingsProfileElements;
|
class ASTSettingsProfileElements;
|
||||||
|
class ASTAlterSettingsProfileElements;
|
||||||
class ASTRolesOrUsersSet;
|
class ASTRolesOrUsersSet;
|
||||||
|
|
||||||
|
|
||||||
@ -16,7 +17,12 @@ class ASTRolesOrUsersSet;
|
|||||||
*
|
*
|
||||||
* ALTER SETTINGS PROFILE [IF EXISTS] name
|
* ALTER SETTINGS PROFILE [IF EXISTS] name
|
||||||
* [RENAME TO new_name]
|
* [RENAME TO new_name]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
* [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
|
* [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
|
||||||
*/
|
*/
|
||||||
class ASTCreateSettingsProfileQuery : public IAST, public ASTQueryWithOnCluster
|
class ASTCreateSettingsProfileQuery : public IAST, public ASTQueryWithOnCluster
|
||||||
@ -34,6 +40,7 @@ public:
|
|||||||
String new_name;
|
String new_name;
|
||||||
|
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
|
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> to_roles;
|
std::shared_ptr<ASTRolesOrUsersSet> to_roles;
|
||||||
|
|
||||||
@ -44,4 +51,5 @@ public:
|
|||||||
ASTPtr getRewrittenASTWithoutOnCluster(const WithoutOnClusterASTRewriteParams &) const override { return removeOnCluster<ASTCreateSettingsProfileQuery>(clone()); }
|
ASTPtr getRewrittenASTWithoutOnCluster(const WithoutOnClusterASTRewriteParams &) const override { return removeOnCluster<ASTCreateSettingsProfileQuery>(clone()); }
|
||||||
QueryKind getQueryKind() const override { return QueryKind::Create; }
|
QueryKind getQueryKind() const override { return QueryKind::Create; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -149,13 +149,17 @@ namespace
|
|||||||
default_roles.format(settings);
|
default_roles.format(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void formatSettings(const ASTSettingsProfileElements & settings, const IAST::FormatSettings & format)
|
void formatSettings(const ASTSettingsProfileElements & settings, const IAST::FormatSettings & format)
|
||||||
{
|
{
|
||||||
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " SETTINGS " << (format.hilite ? IAST::hilite_none : "");
|
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << " SETTINGS " << (format.hilite ? IAST::hilite_none : "");
|
||||||
settings.format(format);
|
settings.format(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void formatAlterSettings(const ASTAlterSettingsProfileElements & alter_settings, const IAST::FormatSettings & format)
|
||||||
|
{
|
||||||
|
format.ostr << " ";
|
||||||
|
alter_settings.format(format);
|
||||||
|
}
|
||||||
|
|
||||||
void formatGrantees(const ASTRolesOrUsersSet & grantees, const IAST::FormatSettings & settings)
|
void formatGrantees(const ASTRolesOrUsersSet & grantees, const IAST::FormatSettings & settings)
|
||||||
{
|
{
|
||||||
@ -198,6 +202,9 @@ ASTPtr ASTCreateUserQuery::clone() const
|
|||||||
if (settings)
|
if (settings)
|
||||||
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
res->settings = std::static_pointer_cast<ASTSettingsProfileElements>(settings->clone());
|
||||||
|
|
||||||
|
if (alter_settings)
|
||||||
|
res->alter_settings = std::static_pointer_cast<ASTAlterSettingsProfileElements>(alter_settings->clone());
|
||||||
|
|
||||||
for (const auto & authentication_method : authentication_methods)
|
for (const auto & authentication_method : authentication_methods)
|
||||||
{
|
{
|
||||||
auto ast_clone = std::static_pointer_cast<ASTAuthenticationData>(authentication_method->clone());
|
auto ast_clone = std::static_pointer_cast<ASTAuthenticationData>(authentication_method->clone());
|
||||||
@ -278,7 +285,9 @@ void ASTCreateUserQuery::formatImpl(const FormatSettings & format, FormatState &
|
|||||||
if (default_roles)
|
if (default_roles)
|
||||||
formatDefaultRoles(*default_roles, format);
|
formatDefaultRoles(*default_roles, format);
|
||||||
|
|
||||||
if (settings && (!settings->empty() || alter))
|
if (alter_settings)
|
||||||
|
formatAlterSettings(*alter_settings, format);
|
||||||
|
else if (settings)
|
||||||
formatSettings(*settings, format);
|
formatSettings(*settings, format);
|
||||||
|
|
||||||
if (grantees)
|
if (grantees)
|
||||||
|
@ -13,6 +13,7 @@ class ASTUserNamesWithHost;
|
|||||||
class ASTRolesOrUsersSet;
|
class ASTRolesOrUsersSet;
|
||||||
class ASTDatabaseOrNone;
|
class ASTDatabaseOrNone;
|
||||||
class ASTSettingsProfileElements;
|
class ASTSettingsProfileElements;
|
||||||
|
class ASTAlterSettingsProfileElements;
|
||||||
class ASTAuthenticationData;
|
class ASTAuthenticationData;
|
||||||
|
|
||||||
|
|
||||||
@ -30,7 +31,12 @@ class ASTAuthenticationData;
|
|||||||
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||||
* [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
* [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
||||||
* [DEFAULT DATABASE database | NONE]
|
* [DEFAULT DATABASE database | NONE]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
* [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
* [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
||||||
*/
|
*/
|
||||||
class ASTCreateUserQuery : public IAST, public ASTQueryWithOnCluster
|
class ASTCreateUserQuery : public IAST, public ASTQueryWithOnCluster
|
||||||
@ -58,6 +64,7 @@ public:
|
|||||||
|
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> default_roles;
|
std::shared_ptr<ASTRolesOrUsersSet> default_roles;
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> grantees;
|
std::shared_ptr<ASTRolesOrUsersSet> grantees;
|
||||||
|
|
||||||
std::shared_ptr<ASTDatabaseOrNone> default_database;
|
std::shared_ptr<ASTDatabaseOrNone> default_database;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <Common/FieldVisitorToString.h>
|
#include <Common/FieldVisitorToString.h>
|
||||||
#include <Common/quoteString.h>
|
#include <Common/quoteString.h>
|
||||||
#include <IO/Operators.h>
|
#include <IO/Operators.h>
|
||||||
|
#include <base/insertAtEnd.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -21,7 +22,53 @@ namespace
|
|||||||
settings.ostr << backQuote(str);
|
settings.ostr << backQuote(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void formatSettingsProfileElementsForAlter(std::string_view kind, const ASTSettingsProfileElements & elements, const IAST::FormatSettings & settings)
|
||||||
|
{
|
||||||
|
bool need_comma = false;
|
||||||
|
|
||||||
|
size_t num_profiles = elements.getNumberOfProfiles();
|
||||||
|
if (num_profiles > 0)
|
||||||
|
{
|
||||||
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << kind << " " << (num_profiles == 1 ? "PROFILE" : "PROFILES")
|
||||||
|
<< (settings.hilite ? IAST::hilite_none : "") << " ";
|
||||||
|
|
||||||
|
for (const auto & element : elements.elements)
|
||||||
|
{
|
||||||
|
if (!element->parent_profile.empty())
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
settings.ostr << ", ";
|
||||||
|
formatProfileNameOrID(element->parent_profile, /* is_id= */ false, settings);
|
||||||
|
need_comma = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_settings = elements.getNumberOfSettings();
|
||||||
|
if (num_settings > 0)
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
settings.ostr << ", ";
|
||||||
|
need_comma = false;
|
||||||
|
|
||||||
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << kind << " " << (num_settings == 1 ? "SETTING" : "SETTINGS")
|
||||||
|
<< (settings.hilite ? IAST::hilite_none : "") << " ";
|
||||||
|
|
||||||
|
for (const auto & element : elements.elements)
|
||||||
|
{
|
||||||
|
if (!element->setting_name.empty())
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
settings.ostr << ", ";
|
||||||
|
element->format(settings);
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ASTSettingsProfileElement::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const
|
void ASTSettingsProfileElement::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const
|
||||||
{
|
{
|
||||||
@ -82,6 +129,27 @@ bool ASTSettingsProfileElements::empty() const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t ASTSettingsProfileElements::getNumberOfSettings() const
|
||||||
|
{
|
||||||
|
return std::count_if(elements.begin(), elements.end(), [](const auto & element){ return !element->setting_name.empty(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ASTSettingsProfileElements::getNumberOfProfiles() const
|
||||||
|
{
|
||||||
|
return std::count_if(elements.begin(), elements.end(), [](const auto & element){ return !element->parent_profile.empty(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ASTPtr ASTSettingsProfileElements::clone() const
|
||||||
|
{
|
||||||
|
auto res = std::make_shared<ASTSettingsProfileElements>(*this);
|
||||||
|
|
||||||
|
for (auto & element : res->elements)
|
||||||
|
element = std::static_pointer_cast<ASTSettingsProfileElement>(element->clone());
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ASTSettingsProfileElements::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const
|
void ASTSettingsProfileElements::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const
|
||||||
{
|
{
|
||||||
@ -109,4 +177,108 @@ void ASTSettingsProfileElements::setUseInheritKeyword(bool use_inherit_keyword_)
|
|||||||
element->use_inherit_keyword = use_inherit_keyword_;
|
element->use_inherit_keyword = use_inherit_keyword_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ASTSettingsProfileElements::add(ASTSettingsProfileElements && other)
|
||||||
|
{
|
||||||
|
insertAtEnd(elements, std::move(other.elements));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String ASTAlterSettingsProfileElements::getID(char) const
|
||||||
|
{
|
||||||
|
return "AlterSettingsProfileElements";
|
||||||
|
}
|
||||||
|
|
||||||
|
ASTPtr ASTAlterSettingsProfileElements::clone() const
|
||||||
|
{
|
||||||
|
auto res = std::make_shared<ASTAlterSettingsProfileElements>(*this);
|
||||||
|
|
||||||
|
if (add_settings)
|
||||||
|
res->add_settings = std::static_pointer_cast<ASTSettingsProfileElements>(add_settings->clone());
|
||||||
|
|
||||||
|
if (modify_settings)
|
||||||
|
res->modify_settings = std::static_pointer_cast<ASTSettingsProfileElements>(modify_settings->clone());
|
||||||
|
|
||||||
|
if (drop_settings)
|
||||||
|
res->drop_settings = std::static_pointer_cast<ASTSettingsProfileElements>(drop_settings->clone());
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTAlterSettingsProfileElements::formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const
|
||||||
|
{
|
||||||
|
bool need_comma = false;
|
||||||
|
|
||||||
|
if (drop_all_settings)
|
||||||
|
{
|
||||||
|
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << "DROP ALL SETTINGS" << (format.hilite ? IAST::hilite_none : "");
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop_all_profiles)
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
format.ostr << ", ";
|
||||||
|
format.ostr << (format.hilite ? IAST::hilite_keyword : "") << "DROP ALL PROFILES" << (format.hilite ? IAST::hilite_none : "");
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop_settings && !drop_settings->empty())
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
format.ostr << ", ";
|
||||||
|
formatSettingsProfileElementsForAlter("DROP", *drop_settings, format);
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_settings && !add_settings->empty())
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
format.ostr << ", ";
|
||||||
|
formatSettingsProfileElementsForAlter("ADD", *add_settings, format);
|
||||||
|
need_comma = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modify_settings && !modify_settings->empty())
|
||||||
|
{
|
||||||
|
if (need_comma)
|
||||||
|
format.ostr << ", ";
|
||||||
|
formatSettingsProfileElementsForAlter("MODIFY", *modify_settings, format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ASTAlterSettingsProfileElements::add(ASTAlterSettingsProfileElements && other)
|
||||||
|
{
|
||||||
|
drop_all_settings |= other.drop_all_settings;
|
||||||
|
drop_all_profiles |= other.drop_all_profiles;
|
||||||
|
|
||||||
|
if (other.add_settings)
|
||||||
|
{
|
||||||
|
if (!add_settings)
|
||||||
|
add_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
add_settings->add(std::move(*other.add_settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.add_settings)
|
||||||
|
{
|
||||||
|
if (!add_settings)
|
||||||
|
add_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
add_settings->add(std::move(*other.add_settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.modify_settings)
|
||||||
|
{
|
||||||
|
if (!modify_settings)
|
||||||
|
modify_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
modify_settings->add(std::move(*other.modify_settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (other.drop_settings)
|
||||||
|
{
|
||||||
|
if (!drop_settings)
|
||||||
|
drop_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
drop_settings->add(std::move(*other.drop_settings));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,10 +39,41 @@ public:
|
|||||||
|
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
|
|
||||||
|
size_t getNumberOfSettings() const;
|
||||||
|
size_t getNumberOfProfiles() const;
|
||||||
|
|
||||||
String getID(char) const override { return "SettingsProfileElements"; }
|
String getID(char) const override { return "SettingsProfileElements"; }
|
||||||
ASTPtr clone() const override { return std::make_shared<ASTSettingsProfileElements>(*this); }
|
ASTPtr clone() const override;
|
||||||
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;
|
void formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const override;
|
||||||
|
|
||||||
void setUseInheritKeyword(bool use_inherit_keyword_);
|
void setUseInheritKeyword(bool use_inherit_keyword_);
|
||||||
|
|
||||||
|
void add(ASTSettingsProfileElements && other);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Represents a clause used to alter settings or profiles assigned to a user or a role or another profile.
|
||||||
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
|
*/
|
||||||
|
class ASTAlterSettingsProfileElements : public IAST
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> add_settings;
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> modify_settings;
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> drop_settings;
|
||||||
|
|
||||||
|
bool drop_all_settings = false;
|
||||||
|
bool drop_all_profiles = false;
|
||||||
|
|
||||||
|
String getID(char) const override;
|
||||||
|
ASTPtr clone() const override;
|
||||||
|
void formatImpl(const FormatSettings & format, FormatState &, FormatStateStacked) const override;
|
||||||
|
|
||||||
|
void add(ASTAlterSettingsProfileElements && other);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,20 +25,31 @@ namespace
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::vector<std::shared_ptr<ASTSettingsProfileElement>> & settings)
|
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::shared_ptr<ASTSettingsProfileElements> & settings)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
if (!ParserKeyword{Keyword::SETTINGS}.ignore(pos, expected))
|
ASTPtr ast;
|
||||||
return false;
|
|
||||||
|
|
||||||
ASTPtr new_settings_ast;
|
|
||||||
ParserSettingsProfileElements elements_p;
|
ParserSettingsProfileElements elements_p;
|
||||||
elements_p.useIDMode(id_mode);
|
elements_p.useIDMode(id_mode);
|
||||||
if (!elements_p.parse(pos, new_settings_ast, expected))
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
settings = std::move(new_settings_ast->as<ASTSettingsProfileElements &>().elements);
|
settings = typeid_cast<std::shared_ptr<ASTSettingsProfileElements>>(ast);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseAlterSettings(IParserBase::Pos & pos, Expected & expected, std::shared_ptr<ASTAlterSettingsProfileElements> & alter_settings)
|
||||||
|
{
|
||||||
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
|
{
|
||||||
|
ASTPtr ast;
|
||||||
|
ParserAlterSettingsProfileElements elements_p;
|
||||||
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
alter_settings = typeid_cast<std::shared_ptr<ASTAlterSettingsProfileElements>>(ast);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -91,6 +102,7 @@ bool ParserCreateRoleQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
|
|
||||||
String new_name;
|
String new_name;
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
String cluster;
|
String cluster;
|
||||||
String storage_name;
|
String storage_name;
|
||||||
|
|
||||||
@ -99,15 +111,28 @@ bool ParserCreateRoleQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
if (alter && new_name.empty() && (names.size() == 1) && parseRenameTo(pos, expected, new_name))
|
if (alter && new_name.empty() && (names.size() == 1) && parseRenameTo(pos, expected, new_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ASTSettingsProfileElement>> new_settings;
|
if (alter)
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> new_alter_settings;
|
||||||
|
if (parseAlterSettings(pos, expected, new_alter_settings))
|
||||||
|
{
|
||||||
|
if (!alter_settings)
|
||||||
|
alter_settings = std::make_shared<ASTAlterSettingsProfileElements>();
|
||||||
|
alter_settings->add(std::move(*new_alter_settings));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> new_settings;
|
||||||
if (parseSettings(pos, expected, attach_mode, new_settings))
|
if (parseSettings(pos, expected, attach_mode, new_settings))
|
||||||
{
|
{
|
||||||
if (!settings)
|
if (!settings)
|
||||||
settings = std::make_shared<ASTSettingsProfileElements>();
|
settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
settings->add(std::move(*new_settings));
|
||||||
insertAtEnd(settings->elements, std::move(new_settings));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cluster.empty() && parseOnCluster(pos, expected, cluster))
|
if (cluster.empty() && parseOnCluster(pos, expected, cluster))
|
||||||
continue;
|
continue;
|
||||||
@ -130,6 +155,7 @@ bool ParserCreateRoleQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
query->names = std::move(names);
|
query->names = std::move(names);
|
||||||
query->new_name = std::move(new_name);
|
query->new_name = std::move(new_name);
|
||||||
query->settings = std::move(settings);
|
query->settings = std::move(settings);
|
||||||
|
query->alter_settings = std::move(alter_settings);
|
||||||
query->storage_name = std::move(storage_name);
|
query->storage_name = std::move(storage_name);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,7 +11,12 @@ namespace DB
|
|||||||
*
|
*
|
||||||
* ALTER ROLE [IF EXISTS] name
|
* ALTER ROLE [IF EXISTS] name
|
||||||
* [RENAME TO new_name]
|
* [RENAME TO new_name]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
*/
|
*/
|
||||||
class ParserCreateRoleQuery : public IParserBase
|
class ParserCreateRoleQuery : public IParserBase
|
||||||
{
|
{
|
||||||
|
@ -27,20 +27,32 @@ namespace
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::vector<std::shared_ptr<ASTSettingsProfileElement>> & settings)
|
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::shared_ptr<ASTSettingsProfileElements> & settings)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
if (!ParserKeyword{Keyword::SETTINGS}.ignore(pos, expected))
|
ASTPtr ast;
|
||||||
return false;
|
|
||||||
|
|
||||||
ASTPtr new_settings_ast;
|
|
||||||
ParserSettingsProfileElements elements_p;
|
ParserSettingsProfileElements elements_p;
|
||||||
elements_p.useInheritKeyword(true).useIDMode(id_mode);
|
elements_p.useInheritKeyword(true).useIDMode(id_mode);
|
||||||
if (!elements_p.parse(pos, new_settings_ast, expected))
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
settings = std::move(new_settings_ast->as<ASTSettingsProfileElements &>().elements);
|
settings = typeid_cast<std::shared_ptr<ASTSettingsProfileElements>>(ast);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseAlterSettings(IParserBase::Pos & pos, Expected & expected, std::shared_ptr<ASTAlterSettingsProfileElements> & alter_settings)
|
||||||
|
{
|
||||||
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
|
{
|
||||||
|
ASTPtr ast;
|
||||||
|
ParserAlterSettingsProfileElements elements_p;
|
||||||
|
elements_p.useInheritKeyword(true);
|
||||||
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
alter_settings = typeid_cast<std::shared_ptr<ASTAlterSettingsProfileElements>>(ast);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -111,6 +123,7 @@ bool ParserCreateSettingsProfileQuery::parseImpl(Pos & pos, ASTPtr & node, Expec
|
|||||||
|
|
||||||
String new_name;
|
String new_name;
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
String cluster;
|
String cluster;
|
||||||
String storage_name;
|
String storage_name;
|
||||||
|
|
||||||
@ -119,15 +132,28 @@ bool ParserCreateSettingsProfileQuery::parseImpl(Pos & pos, ASTPtr & node, Expec
|
|||||||
if (alter && new_name.empty() && (names.size() == 1) && parseRenameTo(pos, expected, new_name))
|
if (alter && new_name.empty() && (names.size() == 1) && parseRenameTo(pos, expected, new_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ASTSettingsProfileElement>> new_settings;
|
if (alter)
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> new_alter_settings;
|
||||||
|
if (parseAlterSettings(pos, expected, new_alter_settings))
|
||||||
|
{
|
||||||
|
if (!alter_settings)
|
||||||
|
alter_settings = std::make_shared<ASTAlterSettingsProfileElements>();
|
||||||
|
alter_settings->add(std::move(*new_alter_settings));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> new_settings;
|
||||||
if (parseSettings(pos, expected, attach_mode, new_settings))
|
if (parseSettings(pos, expected, attach_mode, new_settings))
|
||||||
{
|
{
|
||||||
if (!settings)
|
if (!settings)
|
||||||
settings = std::make_shared<ASTSettingsProfileElements>();
|
settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
settings->add(std::move(*new_settings));
|
||||||
insertAtEnd(settings->elements, std::move(new_settings));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (cluster.empty() && parseOnCluster(pos, expected, cluster))
|
if (cluster.empty() && parseOnCluster(pos, expected, cluster))
|
||||||
continue;
|
continue;
|
||||||
@ -156,6 +182,7 @@ bool ParserCreateSettingsProfileQuery::parseImpl(Pos & pos, ASTPtr & node, Expec
|
|||||||
query->names = std::move(names);
|
query->names = std::move(names);
|
||||||
query->new_name = std::move(new_name);
|
query->new_name = std::move(new_name);
|
||||||
query->settings = std::move(settings);
|
query->settings = std::move(settings);
|
||||||
|
query->alter_settings = std::move(alter_settings);
|
||||||
query->to_roles = std::move(to_roles);
|
query->to_roles = std::move(to_roles);
|
||||||
query->storage_name = std::move(storage_name);
|
query->storage_name = std::move(storage_name);
|
||||||
|
|
||||||
|
@ -11,7 +11,12 @@ namespace DB
|
|||||||
*
|
*
|
||||||
* ALTER SETTINGS PROFILE [IF EXISTS] name
|
* ALTER SETTINGS PROFILE [IF EXISTS] name
|
||||||
* [RENAME TO new_name]
|
* [RENAME TO new_name]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
*/
|
*/
|
||||||
class ParserCreateSettingsProfileQuery : public IParserBase
|
class ParserCreateSettingsProfileQuery : public IParserBase
|
||||||
{
|
{
|
||||||
|
@ -427,20 +427,31 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::vector<std::shared_ptr<ASTSettingsProfileElement>> & settings)
|
bool parseSettings(IParserBase::Pos & pos, Expected & expected, bool id_mode, std::shared_ptr<ASTSettingsProfileElements> & settings)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
if (!ParserKeyword{Keyword::SETTINGS}.ignore(pos, expected))
|
ASTPtr ast;
|
||||||
return false;
|
|
||||||
|
|
||||||
ASTPtr new_settings_ast;
|
|
||||||
ParserSettingsProfileElements elements_p;
|
ParserSettingsProfileElements elements_p;
|
||||||
elements_p.useIDMode(id_mode);
|
elements_p.useIDMode(id_mode);
|
||||||
if (!elements_p.parse(pos, new_settings_ast, expected))
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
settings = std::move(new_settings_ast->as<ASTSettingsProfileElements &>().elements);
|
settings = typeid_cast<std::shared_ptr<ASTSettingsProfileElements>>(ast);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseAlterSettings(IParserBase::Pos & pos, Expected & expected, std::shared_ptr<ASTAlterSettingsProfileElements> & alter_settings)
|
||||||
|
{
|
||||||
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
|
{
|
||||||
|
ASTPtr ast;
|
||||||
|
ParserAlterSettingsProfileElements elements_p;
|
||||||
|
if (!elements_p.parse(pos, ast, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
alter_settings = typeid_cast<std::shared_ptr<ASTAlterSettingsProfileElements>>(ast);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -556,6 +567,7 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
std::vector<std::shared_ptr<ASTAuthenticationData>> auth_data;
|
std::vector<std::shared_ptr<ASTAuthenticationData>> auth_data;
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> default_roles;
|
std::shared_ptr<ASTRolesOrUsersSet> default_roles;
|
||||||
std::shared_ptr<ASTSettingsProfileElements> settings;
|
std::shared_ptr<ASTSettingsProfileElements> settings;
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> alter_settings;
|
||||||
std::shared_ptr<ASTRolesOrUsersSet> grantees;
|
std::shared_ptr<ASTRolesOrUsersSet> grantees;
|
||||||
std::shared_ptr<ASTDatabaseOrNone> default_database;
|
std::shared_ptr<ASTDatabaseOrNone> default_database;
|
||||||
ASTPtr global_valid_until;
|
ASTPtr global_valid_until;
|
||||||
@ -604,15 +616,28 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<ASTSettingsProfileElement>> new_settings;
|
if (alter)
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTAlterSettingsProfileElements> new_alter_settings;
|
||||||
|
if (parseAlterSettings(pos, expected, new_alter_settings))
|
||||||
|
{
|
||||||
|
if (!alter_settings)
|
||||||
|
alter_settings = std::make_shared<ASTAlterSettingsProfileElements>();
|
||||||
|
alter_settings->add(std::move(*new_alter_settings));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::shared_ptr<ASTSettingsProfileElements> new_settings;
|
||||||
if (parseSettings(pos, expected, attach_mode, new_settings))
|
if (parseSettings(pos, expected, attach_mode, new_settings))
|
||||||
{
|
{
|
||||||
if (!settings)
|
if (!settings)
|
||||||
settings = std::make_shared<ASTSettingsProfileElements>();
|
settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
settings->add(std::move(*new_settings));
|
||||||
insertAtEnd(settings->elements, std::move(new_settings));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!default_roles && parseDefaultRoles(pos, expected, attach_mode, default_roles))
|
if (!default_roles && parseDefaultRoles(pos, expected, attach_mode, default_roles))
|
||||||
continue;
|
continue;
|
||||||
@ -691,6 +716,7 @@ bool ParserCreateUserQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
|||||||
query->remove_hosts = std::move(remove_hosts);
|
query->remove_hosts = std::move(remove_hosts);
|
||||||
query->default_roles = std::move(default_roles);
|
query->default_roles = std::move(default_roles);
|
||||||
query->settings = std::move(settings);
|
query->settings = std::move(settings);
|
||||||
|
query->alter_settings = std::move(alter_settings);
|
||||||
query->grantees = std::move(grantees);
|
query->grantees = std::move(grantees);
|
||||||
query->default_database = std::move(default_database);
|
query->default_database = std::move(default_database);
|
||||||
query->global_valid_until = std::move(global_valid_until);
|
query->global_valid_until = std::move(global_valid_until);
|
||||||
|
@ -18,7 +18,12 @@ namespace DB
|
|||||||
* [NOT IDENTIFIED | IDENTIFIED {[WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}}|{WITH ldap SERVER 'server_name'}|{WITH kerberos [REALM 'realm']}]
|
* [NOT IDENTIFIED | IDENTIFIED {[WITH {no_password|plaintext_password|sha256_password|sha256_hash|double_sha1_password|double_sha1_hash}] BY {'password'|'hash'}}|{WITH ldap SERVER 'server_name'}|{WITH kerberos [REALM 'realm']}]
|
||||||
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
* [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
|
||||||
* [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
* [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
|
||||||
* [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
|
* [ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] [,...] ]
|
||||||
|
* [DROP SETTINGS variable [,...] ]
|
||||||
|
* [ADD PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP PROFILES 'profile_name' [,...] ]
|
||||||
|
* [DROP ALL PROFILES]
|
||||||
|
* [DROP ALL SETTINGS]
|
||||||
* [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
* [GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
|
||||||
*/
|
*/
|
||||||
class ParserCreateUserQuery : public IParserBase
|
class ParserCreateUserQuery : public IParserBase
|
||||||
|
@ -7,27 +7,13 @@
|
|||||||
#include <Parsers/ExpressionListParsers.h>
|
#include <Parsers/ExpressionListParsers.h>
|
||||||
#include <Parsers/parseIdentifierOrStringLiteral.h>
|
#include <Parsers/parseIdentifierOrStringLiteral.h>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
|
#include <base/insertAtEnd.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
bool parseProfileKeyword(IParserBase::Pos & pos, Expected & expected, bool use_inherit_keyword)
|
|
||||||
{
|
|
||||||
if (ParserKeyword{Keyword::PROFILE}.ignore(pos, expected))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (use_inherit_keyword && ParserKeyword{Keyword::INHERIT}.ignore(pos, expected))
|
|
||||||
{
|
|
||||||
ParserKeyword{Keyword::PROFILE}.ignore(pos, expected);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool parseProfileNameOrID(IParserBase::Pos & pos, Expected & expected, bool id_mode, String & res)
|
bool parseProfileNameOrID(IParserBase::Pos & pos, Expected & expected, bool id_mode, String & res)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
@ -119,6 +105,17 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool parseSettingName(IParserBase::Pos & pos, Expected & expected, String & res)
|
||||||
|
{
|
||||||
|
ASTPtr name_ast;
|
||||||
|
if (!ParserCompoundIdentifier{}.parse(pos, name_ast, expected))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
res = getIdentifierName(name_ast);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseSettingNameWithValueOrConstraints(
|
bool parseSettingNameWithValueOrConstraints(
|
||||||
IParserBase::Pos & pos,
|
IParserBase::Pos & pos,
|
||||||
Expected & expected,
|
Expected & expected,
|
||||||
@ -130,11 +127,10 @@ namespace
|
|||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
ASTPtr name_ast;
|
String res_setting_name;
|
||||||
if (!ParserCompoundIdentifier{}.parse(pos, name_ast, expected))
|
if (!parseSettingName(pos, expected, res_setting_name))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
String res_setting_name = getIdentifierName(name_ast);
|
|
||||||
std::optional<Field> res_value;
|
std::optional<Field> res_value;
|
||||||
std::optional<Field> res_min_value;
|
std::optional<Field> res_min_value;
|
||||||
std::optional<Field> res_max_value;
|
std::optional<Field> res_max_value;
|
||||||
@ -169,52 +165,112 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseSettingsProfileElement(IParserBase::Pos & pos,
|
bool parseSettingsProfileElements(IParserBase::Pos & pos,
|
||||||
Expected & expected,
|
Expected & expected,
|
||||||
bool id_mode,
|
bool id_mode,
|
||||||
bool use_inherit_keyword,
|
bool use_inherit_keyword,
|
||||||
bool previous_element_was_parent_profile,
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> & res)
|
||||||
std::shared_ptr<ASTSettingsProfileElement> & result)
|
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> elements;
|
||||||
|
bool found_none = false;
|
||||||
|
|
||||||
|
bool expect_profiles = false;
|
||||||
|
bool expect_settings = false;
|
||||||
|
|
||||||
|
auto parse_element = [&]
|
||||||
|
{
|
||||||
|
if (ParserKeyword{Keyword::SETTINGS}.ignore(pos, expected) || ParserKeyword{Keyword::SETTING}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
expect_settings = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expect_settings_next = expect_settings;
|
||||||
|
|
||||||
|
if (ParserKeyword{Keyword::PROFILES}.ignore(pos, expected) || ParserKeyword{Keyword::PROFILE}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
expect_profiles = true;
|
||||||
|
expect_settings = false;
|
||||||
|
}
|
||||||
|
else if (use_inherit_keyword && ParserKeyword{Keyword::INHERIT}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
if (!ParserKeyword{Keyword::PROFILES}.ignore(pos, expected))
|
||||||
|
ParserKeyword{Keyword::PROFILE}.ignore(pos, expected);
|
||||||
|
expect_profiles = true;
|
||||||
|
expect_settings = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!expect_profiles && !expect_settings)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (ParserKeyword{Keyword::NONE}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
found_none = true;
|
||||||
|
expect_settings = expect_settings_next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expect_settings)
|
||||||
{
|
{
|
||||||
String parent_profile;
|
|
||||||
String setting_name;
|
String setting_name;
|
||||||
std::optional<Field> value;
|
std::optional<Field> value;
|
||||||
std::optional<Field> min_value;
|
std::optional<Field> min_value;
|
||||||
std::optional<Field> max_value;
|
std::optional<Field> max_value;
|
||||||
std::optional<SettingConstraintWritability> writability;
|
std::optional<SettingConstraintWritability> writability;
|
||||||
|
if (parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, writability))
|
||||||
|
{
|
||||||
|
auto element = std::make_shared<ASTSettingsProfileElement>();
|
||||||
|
element->setting_name = std::move(setting_name);
|
||||||
|
element->value = std::move(value);
|
||||||
|
element->min_value = std::move(min_value);
|
||||||
|
element->max_value = std::move(max_value);
|
||||||
|
element->writability = std::move(writability);
|
||||||
|
elements.push_back(element);
|
||||||
|
expect_profiles = false;
|
||||||
|
expect_settings = expect_settings_next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool ok = parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, writability);
|
if (expect_profiles)
|
||||||
|
{
|
||||||
|
String profile_name;
|
||||||
|
if (parseProfileNameOrID(pos, expected, id_mode, profile_name))
|
||||||
|
{
|
||||||
|
auto element = std::make_shared<ASTSettingsProfileElement>();
|
||||||
|
element->parent_profile = std::move(profile_name);
|
||||||
|
element->id_mode = id_mode;
|
||||||
|
element->use_inherit_keyword = use_inherit_keyword;
|
||||||
|
elements.push_back(element);
|
||||||
|
expect_settings = expect_settings_next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!ok && (parseProfileKeyword(pos, expected, use_inherit_keyword) || previous_element_was_parent_profile))
|
return false;
|
||||||
ok = parseProfileNameOrID(pos, expected, id_mode, parent_profile);
|
};
|
||||||
|
|
||||||
if (!ok)
|
if (!ParserList::parseUtil(pos, expected, parse_element, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
result = std::make_shared<ASTSettingsProfileElement>();
|
if (elements.empty() && !found_none)
|
||||||
result->parent_profile = std::move(parent_profile);
|
return false;
|
||||||
result->setting_name = std::move(setting_name);
|
|
||||||
result->value = std::move(value);
|
res = std::move(elements);
|
||||||
result->min_value = std::move(min_value);
|
|
||||||
result->max_value = std::move(max_value);
|
|
||||||
result->writability = writability;
|
|
||||||
result->id_mode = id_mode;
|
|
||||||
result->use_inherit_keyword = use_inherit_keyword;
|
|
||||||
return true;
|
return true;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ParserSettingsProfileElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
bool ParserSettingsProfileElement::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
{
|
{
|
||||||
std::shared_ptr<ASTSettingsProfileElement> res;
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> elements;
|
||||||
if (!parseSettingsProfileElement(pos, expected, id_mode, use_inherit_keyword, false, res))
|
if (!parseSettingsProfileElements(pos, expected, id_mode, use_inherit_keyword, elements))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
node = res;
|
if (elements.size() != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
node = elements[0];
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,33 +278,157 @@ bool ParserSettingsProfileElement::parseImpl(Pos & pos, ASTPtr & node, Expected
|
|||||||
bool ParserSettingsProfileElements::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
bool ParserSettingsProfileElements::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
{
|
{
|
||||||
std::vector<std::shared_ptr<ASTSettingsProfileElement>> elements;
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> elements;
|
||||||
|
if (!parseSettingsProfileElements(pos, expected, id_mode, use_inherit_keyword, elements))
|
||||||
if (ParserKeyword{Keyword::NONE}.ignore(pos, expected))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
bool previous_element_was_parent_profile = false;
|
|
||||||
|
|
||||||
auto parse_element = [&]
|
|
||||||
{
|
|
||||||
std::shared_ptr<ASTSettingsProfileElement> element;
|
|
||||||
if (!parseSettingsProfileElement(pos, expected, id_mode, use_inherit_keyword, previous_element_was_parent_profile, element))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
elements.push_back(element);
|
|
||||||
previous_element_was_parent_profile = !element->parent_profile.empty();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!ParserList::parseUtil(pos, expected, parse_element, false))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto result = std::make_shared<ASTSettingsProfileElements>();
|
auto result = std::make_shared<ASTSettingsProfileElements>();
|
||||||
result->elements = std::move(elements);
|
result->elements = std::move(elements);
|
||||||
node = result;
|
node = result;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ParserAlterSettingsProfileElements::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> add_settings;
|
||||||
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> modify_settings;
|
||||||
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> drop_settings;
|
||||||
|
bool drop_all_settings = false;
|
||||||
|
bool drop_all_profiles = false;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<ASTSettingsProfileElement>> old_style_settings;
|
||||||
|
if (parseSettingsProfileElements(pos, expected, /* id_mode= */ false, use_inherit_keyword, old_style_settings))
|
||||||
|
{
|
||||||
|
/// old style: "SETTINGS ..." replaces all the settings ad profiles.
|
||||||
|
add_settings = std::move(old_style_settings);
|
||||||
|
drop_all_settings = true;
|
||||||
|
drop_all_profiles = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/// new style: "MODIFY SETTINGS ..., ADD PROFILES ..., DROP PROFILES ..., DROP SETTINGS ..."
|
||||||
|
std::string_view action;
|
||||||
|
std::string_view target;
|
||||||
|
|
||||||
|
auto parse_element = [&]
|
||||||
|
{
|
||||||
|
if (ParserKeyword{Keyword::ADD}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
action = "ADD";
|
||||||
|
target = "";
|
||||||
|
}
|
||||||
|
else if (ParserKeyword{Keyword::DROP}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
action = "DROP";
|
||||||
|
target = "";
|
||||||
|
}
|
||||||
|
else if (ParserKeyword{Keyword::MODIFY}.ignore(pos, expected))
|
||||||
|
{
|
||||||
|
action = "MODIFY";
|
||||||
|
target = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!action.empty())
|
||||||
|
{
|
||||||
|
if (ParserKeyword{Keyword::ALL_PROFILES}.ignore(pos, expected))
|
||||||
|
target = "ALL PROFILES";
|
||||||
|
else if (ParserKeyword{Keyword::ALL_SETTINGS}.ignore(pos, expected))
|
||||||
|
target = "ALL SETTINGS";
|
||||||
|
else if (ParserKeyword{Keyword::PROFILES}.ignore(pos, expected) || ParserKeyword{Keyword::PROFILE}.ignore(pos, expected))
|
||||||
|
target = "PROFILES";
|
||||||
|
else if (ParserKeyword{Keyword::SETTINGS}.ignore(pos, expected) || ParserKeyword{Keyword::SETTING}.ignore(pos, expected))
|
||||||
|
target = "SETTINGS";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (target == "PROFILES")
|
||||||
|
{
|
||||||
|
auto element = std::make_shared<ASTSettingsProfileElement>();
|
||||||
|
if (!parseProfileNameOrID(pos, expected, /* id_mode= */ false, element->parent_profile))
|
||||||
|
return false;
|
||||||
|
if (action == "ADD")
|
||||||
|
{
|
||||||
|
add_settings.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (action == "DROP")
|
||||||
|
{
|
||||||
|
drop_settings.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == "SETTINGS")
|
||||||
|
{
|
||||||
|
auto element = std::make_shared<ASTSettingsProfileElement>();
|
||||||
|
if (action == "ADD" || action == "MODIFY")
|
||||||
|
{
|
||||||
|
if (!parseSettingNameWithValueOrConstraints(pos, expected, element->setting_name, element->value, element->min_value, element->max_value, element->writability))
|
||||||
|
return false;
|
||||||
|
if (action == "ADD")
|
||||||
|
add_settings.push_back(element);
|
||||||
|
else
|
||||||
|
modify_settings.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (action == "DROP")
|
||||||
|
{
|
||||||
|
ASTPtr name_ast;
|
||||||
|
if (!ParserCompoundIdentifier{}.parse(pos, name_ast, expected))
|
||||||
|
return false;
|
||||||
|
element->setting_name = getIdentifierName(name_ast);
|
||||||
|
drop_settings.push_back(element);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == "DROP" && target == "ALL PROFILES")
|
||||||
|
{
|
||||||
|
drop_all_profiles = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action == "DROP" && target == "ALL SETTINGS")
|
||||||
|
{
|
||||||
|
drop_all_settings = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!ParserList::parseUtil(pos, expected, parse_element, false))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add_settings.empty() && modify_settings.empty() && drop_settings.empty() && !drop_all_settings && !drop_all_profiles)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto result = std::make_shared<ASTAlterSettingsProfileElements>();
|
||||||
|
if (!add_settings.empty())
|
||||||
|
{
|
||||||
|
result->add_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
result->add_settings->elements = std::move(add_settings);
|
||||||
|
}
|
||||||
|
if (!modify_settings.empty())
|
||||||
|
{
|
||||||
|
result->modify_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
result->modify_settings->elements = std::move(modify_settings);
|
||||||
|
}
|
||||||
|
if (!drop_settings.empty())
|
||||||
|
{
|
||||||
|
result->drop_settings = std::make_shared<ASTSettingsProfileElements>();
|
||||||
|
result->drop_settings->elements = std::move(drop_settings);
|
||||||
|
}
|
||||||
|
result->drop_all_settings = drop_all_settings;
|
||||||
|
result->drop_all_profiles = drop_all_profiles;
|
||||||
|
|
||||||
|
node = result;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,4 +39,18 @@ private:
|
|||||||
bool use_inherit_keyword = false;
|
bool use_inherit_keyword = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ParserAlterSettingsProfileElements : public IParserBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ParserAlterSettingsProfileElements & useInheritKeyword(bool use_inherit_keyword_ = true) { use_inherit_keyword = use_inherit_keyword_; return *this; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const char * getName() const override { return "AlterSettingsProfileElements"; }
|
||||||
|
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool use_inherit_keyword = false;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,25 @@ namespace DB
|
|||||||
{
|
{
|
||||||
|
|
||||||
#define APPLY_FOR_PARSER_KEYWORDS(MR_MACROS) \
|
#define APPLY_FOR_PARSER_KEYWORDS(MR_MACROS) \
|
||||||
|
MR_MACROS(ADD, "ADD") \
|
||||||
MR_MACROS(ADD_COLUMN, "ADD COLUMN") \
|
MR_MACROS(ADD_COLUMN, "ADD COLUMN") \
|
||||||
MR_MACROS(ADD_CONSTRAINT, "ADD CONSTRAINT") \
|
MR_MACROS(ADD_CONSTRAINT, "ADD CONSTRAINT") \
|
||||||
MR_MACROS(ADD_INDEX, "ADD INDEX") \
|
MR_MACROS(ADD_INDEX, "ADD INDEX") \
|
||||||
MR_MACROS(ADD_PROJECTION, "ADD PROJECTION") \
|
MR_MACROS(ADD_PROJECTION, "ADD PROJECTION") \
|
||||||
MR_MACROS(ADD_STATISTICS, "ADD STATISTICS") \
|
MR_MACROS(ADD_STATISTICS, "ADD STATISTICS") \
|
||||||
MR_MACROS(ADD, "ADD") \
|
|
||||||
MR_MACROS(ADMIN_OPTION_FOR, "ADMIN OPTION FOR") \
|
MR_MACROS(ADMIN_OPTION_FOR, "ADMIN OPTION FOR") \
|
||||||
MR_MACROS(AFTER, "AFTER") \
|
MR_MACROS(AFTER, "AFTER") \
|
||||||
MR_MACROS(ALGORITHM, "ALGORITHM") \
|
MR_MACROS(ALGORITHM, "ALGORITHM") \
|
||||||
MR_MACROS(ALIAS, "ALIAS") \
|
MR_MACROS(ALIAS, "ALIAS") \
|
||||||
MR_MACROS(ALL, "ALL") \
|
MR_MACROS(ALL, "ALL") \
|
||||||
|
MR_MACROS(ALL_PROFILES, "ALL PROFILES") \
|
||||||
|
MR_MACROS(ALL_SETTINGS, "ALL SETTINGS") \
|
||||||
MR_MACROS(ALTER_COLUMN, "ALTER COLUMN") \
|
MR_MACROS(ALTER_COLUMN, "ALTER COLUMN") \
|
||||||
MR_MACROS(ALTER_DATABASE, "ALTER DATABASE") \
|
MR_MACROS(ALTER_DATABASE, "ALTER DATABASE") \
|
||||||
MR_MACROS(ALTER_LIVE_VIEW, "ALTER LIVE VIEW") \
|
MR_MACROS(ALTER_LIVE_VIEW, "ALTER LIVE VIEW") \
|
||||||
MR_MACROS(ALTER_POLICY, "ALTER POLICY") \
|
MR_MACROS(ALTER_POLICY, "ALTER POLICY") \
|
||||||
MR_MACROS(ALTER_PROFILE, "ALTER PROFILE") \
|
MR_MACROS(ALTER_PROFILE, "ALTER PROFILE") \
|
||||||
|
MR_MACROS(ALTER_PROFILES, "ALTER PROFILES") \
|
||||||
MR_MACROS(ALTER_QUOTA, "ALTER QUOTA") \
|
MR_MACROS(ALTER_QUOTA, "ALTER QUOTA") \
|
||||||
MR_MACROS(ALTER_ROLE, "ALTER ROLE") \
|
MR_MACROS(ALTER_ROLE, "ALTER ROLE") \
|
||||||
MR_MACROS(ALTER_ROW_POLICY, "ALTER ROW POLICY") \
|
MR_MACROS(ALTER_ROW_POLICY, "ALTER ROW POLICY") \
|
||||||
@ -380,6 +383,7 @@ namespace DB
|
|||||||
MR_MACROS(PRIMARY_KEY, "PRIMARY KEY") \
|
MR_MACROS(PRIMARY_KEY, "PRIMARY KEY") \
|
||||||
MR_MACROS(PRIMARY, "PRIMARY") \
|
MR_MACROS(PRIMARY, "PRIMARY") \
|
||||||
MR_MACROS(PROFILE, "PROFILE") \
|
MR_MACROS(PROFILE, "PROFILE") \
|
||||||
|
MR_MACROS(PROFILES, "PROFILES") \
|
||||||
MR_MACROS(PROJECTION, "PROJECTION") \
|
MR_MACROS(PROJECTION, "PROJECTION") \
|
||||||
MR_MACROS(PROTOBUF, "Protobuf") \
|
MR_MACROS(PROTOBUF, "Protobuf") \
|
||||||
MR_MACROS(PULL, "PULL") \
|
MR_MACROS(PULL, "PULL") \
|
||||||
@ -445,6 +449,7 @@ namespace DB
|
|||||||
MR_MACROS(SET_ROLE, "SET ROLE") \
|
MR_MACROS(SET_ROLE, "SET ROLE") \
|
||||||
MR_MACROS(SET_TRANSACTION_SNAPSHOT, "SET TRANSACTION SNAPSHOT") \
|
MR_MACROS(SET_TRANSACTION_SNAPSHOT, "SET TRANSACTION SNAPSHOT") \
|
||||||
MR_MACROS(SET, "SET") \
|
MR_MACROS(SET, "SET") \
|
||||||
|
MR_MACROS(SETTING, "SETTING") \
|
||||||
MR_MACROS(SETTINGS, "SETTINGS") \
|
MR_MACROS(SETTINGS, "SETTINGS") \
|
||||||
MR_MACROS(SHOW_ACCESS, "SHOW ACCESS") \
|
MR_MACROS(SHOW_ACCESS, "SHOW ACCESS") \
|
||||||
MR_MACROS(SHOW_CREATE, "SHOW CREATE") \
|
MR_MACROS(SHOW_CREATE, "SHOW CREATE") \
|
||||||
|
@ -49,7 +49,7 @@ CREATE SETTINGS PROFILE `s4_01294` TO r1_01294
|
|||||||
CREATE SETTINGS PROFILE `s1_01294` SETTINGS readonly = 1
|
CREATE SETTINGS PROFILE `s1_01294` SETTINGS readonly = 1
|
||||||
CREATE SETTINGS PROFILE `s2_01294` SETTINGS readonly CONST
|
CREATE SETTINGS PROFILE `s2_01294` SETTINGS readonly CONST
|
||||||
CREATE SETTINGS PROFILE `s3_01294` SETTINGS INHERIT `readonly`
|
CREATE SETTINGS PROFILE `s3_01294` SETTINGS INHERIT `readonly`
|
||||||
CREATE SETTINGS PROFILE `s4_01294` SETTINGS INHERIT `readonly`, INHERIT `readonly`
|
CREATE SETTINGS PROFILE `s4_01294` SETTINGS INHERIT `readonly`
|
||||||
CREATE SETTINGS PROFILE `s5_01294` SETTINGS INHERIT `readonly`, readonly = 1
|
CREATE SETTINGS PROFILE `s5_01294` SETTINGS INHERIT `readonly`, readonly = 1
|
||||||
CREATE SETTINGS PROFILE `s6_01294` SETTINGS INHERIT `readonly`, readonly CONST
|
CREATE SETTINGS PROFILE `s6_01294` SETTINGS INHERIT `readonly`, readonly CONST
|
||||||
-- system.settings_profiles
|
-- system.settings_profiles
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_b`
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_b`, PROFILE `profile_a`, PROFILE `profile_c`
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_d`
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_e`
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_b`
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_b`, PROFILE `profile_a`, PROFILE `profile_c`
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_d`
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_e`
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_b`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_b`, INHERIT `profile_a`, INHERIT `profile_c`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_d`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_e`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
76
tests/queries/0_stateless/02943_alter_user_modify_profiles.sh
Executable file
76
tests/queries/0_stateless/02943_alter_user_modify_profiles.sh
Executable file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=../shell_config.sh
|
||||||
|
. "$CURDIR"/../shell_config.sh
|
||||||
|
|
||||||
|
test_user="test_user_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_role="test_role_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_profile="test_profile_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
|
||||||
|
profile_a="profile_a_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_b="profile_b_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_c="profile_c_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_d="profile_d_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_e="profile_e_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_c};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_d};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_e};"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_c};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_d};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_e};"
|
||||||
|
|
||||||
|
function show_create()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "SHOW CREATE $type ${name};" | sed -e "s/${name}/test_${type}/g" -e "s/${profile_a}/profile_a/g" -e "s/${profile_b}/profile_b/g" -e "s/${profile_c}/profile_c/g" -e "s/${profile_d}/profile_d/g" -e "s/${profile_e}/profile_e/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type IF EXISTS ${name};"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE $type ${name};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILE ${profile_a};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILE ${profile_b};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILES ${profile_a}, ${profile_c};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILE ${profile_d} DROP PROFILES ${profile_b}, ${profile_c};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL PROFILES, ADD PROFILE ${profile_e};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL PROFILES;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type ${name};"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test user ${test_user}
|
||||||
|
run_test role ${test_role}
|
||||||
|
run_test profile ${test_profile}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_c};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_d};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_e};"
|
@ -0,0 +1,39 @@
|
|||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_a`, custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS PROFILE `profile_b`, PROFILE `profile_a`, custom_x = 321, custom_s = \'str\' CONST
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, PROFILE `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_a`, custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE ROLE test_role SETTINGS PROFILE `profile_b`, PROFILE `profile_a`, custom_x = 321, custom_s = \'str\' CONST
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, INHERIT `profile_b`, custom_x = 123, custom_y = 56.5, custom_w = \'www\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_a`, custom_x = 123, custom_t = 7, custom_s = \'str\'
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS INHERIT `profile_b`, INHERIT `profile_a`, custom_x = 321, custom_s = \'str\' CONST
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
86
tests/queries/0_stateless/02943_alter_user_modify_profiles_and_settings.sh
Executable file
86
tests/queries/0_stateless/02943_alter_user_modify_profiles_and_settings.sh
Executable file
@ -0,0 +1,86 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=../shell_config.sh
|
||||||
|
. "$CURDIR"/../shell_config.sh
|
||||||
|
|
||||||
|
test_user="test_user_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_role="test_role_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_profile="test_profile_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
|
||||||
|
profile_a="profile_a_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_b="profile_b_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
profile_c="profile_c_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE IF EXISTS ${profile_c};"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE PROFILE ${profile_c};"
|
||||||
|
|
||||||
|
function show_create()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "SHOW CREATE $type ${name};" | sed -e "s/${name}/test_${type}/g" -e "s/${profile_a}/profile_a/g" -e "s/${profile_b}/profile_b/g" -e "s/${profile_c}/profile_c/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type IF EXISTS ${name};"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE $type ${name};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTINGS custom_x = 123, custom_y=56.5, custom_w='www', ADD PROFILES ${profile_a}, ${profile_b}"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS, DROP ALL PROFILES"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTINGS custom_x = 123, custom_y=56.5, custom_w='www', PROFILES ${profile_a}, ${profile_b}"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS, ALL PROFILES"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_x = 123, ADD SETTING custom_y=56.5, ADD SETTING custom_w='www', ADD PROFILE ${profile_a}, ADD PROFILE ${profile_b}"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL PROFILES, DROP ALL SETTINGS"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_x = 123 ADD SETTING custom_y=56.5 ADD SETTING custom_w='www' ADD PROFILE ${profile_a} ADD PROFILE ${profile_b}"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS DROP ALL PROFILES"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_x = 123, custom_t = 7, custom_s = 'str'"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILE ${profile_a}"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD PROFILE ${profile_b}, ${profile_a}, DROP SETTING custom_t, MODIFY SETTING custom_s READONLY, custom_x = 321"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS, ALL PROFILES"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type ${name};"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test user ${test_user}
|
||||||
|
run_test role ${test_role}
|
||||||
|
run_test profile ${test_profile}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_a};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_b};"
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP PROFILE ${profile_c};"
|
@ -0,0 +1,42 @@
|
|||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_a = 100
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_a = 100, custom_b = 200
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_a = 100, custom_b = 300, custom_c = 400
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 1000
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 2000
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 500 MAX 2000
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 700 MIN 500 MAX 2000
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 800 MIN 150
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_c = 400, custom_d = 500
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_c = 400, custom_d = 500, custom_x = 1, custom_y = 2
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password SETTINGS custom_z = 3
|
||||||
|
CREATE USER test_user IDENTIFIED WITH no_password
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE ROLE test_role SETTINGS custom_a = 100
|
||||||
|
CREATE ROLE test_role SETTINGS custom_a = 100, custom_b = 200
|
||||||
|
CREATE ROLE test_role SETTINGS custom_a = 100, custom_b = 300, custom_c = 400
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 1000
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 2000
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 500 MAX 2000
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 700 MIN 500 MAX 2000
|
||||||
|
CREATE ROLE test_role SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 800 MIN 150
|
||||||
|
CREATE ROLE test_role SETTINGS custom_c = 400, custom_d = 500
|
||||||
|
CREATE ROLE test_role SETTINGS custom_c = 400, custom_d = 500, custom_x = 1, custom_y = 2
|
||||||
|
CREATE ROLE test_role SETTINGS custom_z = 3
|
||||||
|
CREATE ROLE test_role
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_a = 100
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_a = 100, custom_b = 200
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_a = 100, custom_b = 300, custom_c = 400
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 1000
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 0 MAX 2000
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 600 MIN 500 MAX 2000
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 700 MIN 500 MAX 2000
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_b = 300, custom_c = 400, custom_d = 500, custom_e = 800 MIN 150
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_c = 400, custom_d = 500
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_c = 400, custom_d = 500, custom_x = 1, custom_y = 2
|
||||||
|
CREATE SETTINGS PROFILE `test_profile` SETTINGS custom_z = 3
|
||||||
|
CREATE SETTINGS PROFILE `test_profile`
|
73
tests/queries/0_stateless/02943_alter_user_modify_settings.sh
Executable file
73
tests/queries/0_stateless/02943_alter_user_modify_settings.sh
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||||
|
# shellcheck source=../shell_config.sh
|
||||||
|
. "$CURDIR"/../shell_config.sh
|
||||||
|
|
||||||
|
test_user="test_user_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_role="test_role_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
test_profile="test_profile_02932_${CLICKHOUSE_DATABASE}_$RANDOM"
|
||||||
|
|
||||||
|
function show_create()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "SHOW CREATE $type ${name};" | sed "s/${name}/test_${type}/g"
|
||||||
|
}
|
||||||
|
|
||||||
|
function run_test()
|
||||||
|
{
|
||||||
|
local type="$1"
|
||||||
|
local name="$2"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type IF EXISTS ${name};"
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "CREATE $type ${name};"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_a=100;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_b=200;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTINGS custom_b=300, custom_c=400;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_d=500 DROP SETTING custom_a;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_e=600 MIN 0 MAX 1000;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} MODIFY SETTING custom_e MAX 2000;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} MODIFY SETTING custom_e MIN 500;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} MODIFY SETTING custom_e=700;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} ADD SETTING custom_e=800 MIN 150;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP SETTINGS custom_b, custom_e;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} MODIFY SETTINGS custom_x=1, custom_y=2;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS, ADD SETTING custom_z=3;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "ALTER $type ${name} DROP ALL SETTINGS;"
|
||||||
|
show_create $type ${name}
|
||||||
|
|
||||||
|
$CLICKHOUSE_CLIENT -q "DROP $type ${name};"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_test user ${test_user}
|
||||||
|
run_test role ${test_role}
|
||||||
|
run_test profile ${test_profile}
|
Loading…
Reference in New Issue
Block a user