Skip to content

Commit 749d351

Browse files
committed
Add syntax ALTER USER {ADD|MODIFY|DROP SETTING}, ALTER USER {ADD|DROP PROFILE}, the same for ALTER ROLE and ALTER PROFILE.
1 parent 4279dd2 commit 749d351

39 files changed

Lines changed: 1310 additions & 179 deletions

docs/en/sql-reference/statements/alter/role.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@ Syntax:
1313
``` sql
1414
ALTER ROLE [IF EXISTS] name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1515
[, name2 [ON CLUSTER cluster_name2] [RENAME TO new_name2] ...]
16-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
16+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
17+
[DROP SETTINGS variable [,...] ]
18+
[ADD PROFILES 'profile_name' [,...] ]
19+
[DROP PROFILES 'profile_name' [,...] ]
20+
[DROP ALL PROFILES]
21+
[DROP ALL SETTINGS]
1722
```

docs/en/sql-reference/statements/alter/settings-profile.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@ Syntax:
1313
``` sql
1414
ALTER SETTINGS PROFILE [IF EXISTS] TO name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1515
[, name2 [ON CLUSTER cluster_name2] [RENAME TO new_name2] ...]
16-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
16+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
17+
[DROP SETTINGS variable [,...] ]
18+
[ADD PROFILES 'profile_name' [,...] ]
19+
[DROP PROFILES 'profile_name' [,...] ]
20+
[DROP ALL PROFILES]
21+
[DROP ALL SETTINGS]
1722
```

docs/en/sql-reference/statements/alter/user.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ ALTER USER [IF EXISTS] name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1717
[VALID UNTIL datetime]
1818
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
1919
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
20-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]
20+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
21+
[DROP SETTINGS variable [,...] ]
22+
[ADD PROFILES 'profile_name' [,...] ]
23+
[DROP PROFILES 'profile_name' [,...] ]
24+
[DROP ALL PROFILES]
25+
[DROP ALL SETTINGS]
2126
```
2227

2328
To use `ALTER USER` you must have the [ALTER USER](../../../sql-reference/statements/grant.md#grant-access-management) privilege.

docs/ru/sql-reference/statements/alter/role.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@ sidebar_label: ROLE
1313
``` sql
1414
ALTER ROLE [IF EXISTS] name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1515
[, name2 [ON CLUSTER cluster_name2] [RENAME TO new_name2] ...]
16-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | PROFILE 'profile_name'] [,...]
16+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
17+
[DROP SETTINGS variable [,...] ]
18+
[ADD PROFILES 'profile_name' [,...] ]
19+
[DROP PROFILES 'profile_name' [,...] ]
20+
[DROP ALL PROFILES]
21+
[DROP ALL SETTINGS]
1722
```

docs/ru/sql-reference/statements/alter/settings-profile.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,10 @@ sidebar_label: SETTINGS PROFILE
1313
``` sql
1414
ALTER SETTINGS PROFILE [IF EXISTS] TO name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1515
[, name2 [ON CLUSTER cluster_name2] [RENAME TO new_name2] ...]
16-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [CONST|READONLY|WRITABLE|CHANGEABLE_IN_READONLY] | INHERIT 'profile_name'] [,...]
16+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
17+
[DROP SETTINGS variable [,...] ]
18+
[ADD PROFILES 'profile_name' [,...] ]
19+
[DROP PROFILES 'profile_name' [,...] ]
20+
[DROP ALL PROFILES]
21+
[DROP ALL SETTINGS]
1722
```

docs/ru/sql-reference/statements/alter/user.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ ALTER USER [IF EXISTS] name1 [ON CLUSTER cluster_name1] [RENAME TO new_name1]
1717
[[ADD | DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
1818
[DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
1919
[GRANTEES {user | role | ANY | NONE} [,...] [EXCEPT {user | role} [,...]]]
20-
[SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY | WRITABLE] | PROFILE 'profile_name'] [,...]
20+
[ADD|MODIFY SETTINGS variable [=value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE|CONST|CHANGEABLE_IN_READONLY] [,...] ]
21+
[DROP SETTINGS variable [,...] ]
22+
[ADD PROFILES 'profile_name' [,...] ]
23+
[DROP PROFILES 'profile_name' [,...] ]
24+
[DROP ALL PROFILES]
25+
[DROP ALL SETTINGS]
2126
```
2227

2328
Для выполнения `ALTER USER` необходима привилегия [ALTER USER](../grant.md#grant-access-management).

src/Access/SettingsConstraints.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ void SettingsConstraints::merge(const SettingsConstraints & other)
133133
}
134134

135135

136+
void SettingsConstraints::check(const Settings & current_settings, const AlterSettingsProfileElements & profile_elements, SettingSource source) const
137+
{
138+
check(current_settings, profile_elements.add_settings, source);
139+
check(current_settings, profile_elements.modify_settings, source);
140+
/// We don't check `drop_settings` here.
141+
}
142+
136143
void SettingsConstraints::check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const
137144
{
138145
for (const auto & element : profile_elements)

src/Access/SettingsConstraints.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,11 @@ class SettingsConstraints
7474
void merge(const SettingsConstraints & other);
7575

7676
/// Checks whether `change` violates these constraints and throws an exception if so.
77-
void check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const;
7877
void check(const Settings & current_settings, const SettingChange & change, SettingSource source) const;
7978
void check(const Settings & current_settings, const SettingsChanges & changes, SettingSource source) const;
8079
void check(const Settings & current_settings, SettingsChanges & changes, SettingSource source) const;
80+
void check(const Settings & current_settings, const SettingsProfileElements & profile_elements, SettingSource source) const;
81+
void check(const Settings & current_settings, const AlterSettingsProfileElements & profile_elements, SettingSource source) const;
8182

8283
/// Checks whether `change` violates these constraints and throws an exception if so. (setting short name is expected inside `changes`)
8384
void check(const MergeTreeSettings & current_settings, const SettingChange & change) const;

src/Access/SettingsProfileElement.cpp

Lines changed: 191 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,23 @@ std::shared_ptr<ASTSettingsProfileElements> SettingsProfileElements::toAST() con
133133
{
134134
auto res = std::make_shared<ASTSettingsProfileElements>();
135135
for (const auto & element : *this)
136-
res->elements.push_back(element.toAST());
136+
{
137+
auto element_ast = element.toAST();
138+
if (!element_ast->empty())
139+
res->elements.push_back(element_ast);
140+
}
137141
return res;
138142
}
139143

140144
std::shared_ptr<ASTSettingsProfileElements> SettingsProfileElements::toASTWithNames(const AccessControl & access_control) const
141145
{
142146
auto res = std::make_shared<ASTSettingsProfileElements>();
143147
for (const auto & element : *this)
144-
res->elements.push_back(element.toASTWithNames(access_control));
148+
{
149+
auto element_ast = element.toASTWithNames(access_control);
150+
if (!element_ast->empty())
151+
res->elements.push_back(element_ast);
152+
}
145153
return res;
146154
}
147155

@@ -252,4 +260,185 @@ bool SettingsProfileElements::isAllowBackupSetting(const String & setting_name)
252260
return Settings::Traits::resolveName(setting_name) == ALLOW_BACKUP_SETTING_NAME;
253261
}
254262

263+
264+
AlterSettingsProfileElements::AlterSettingsProfileElements(const SettingsProfileElements & ast)
265+
{
266+
drop_all_settings = true;
267+
drop_all_profiles = true;
268+
add_settings = ast;
269+
}
270+
271+
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTSettingsProfileElements & ast)
272+
: AlterSettingsProfileElements(SettingsProfileElements{ast})
273+
{
274+
}
275+
276+
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control)
277+
: AlterSettingsProfileElements(SettingsProfileElements{ast, access_control})
278+
{
279+
}
280+
281+
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast)
282+
{
283+
drop_all_settings = ast.drop_all_settings;
284+
drop_all_profiles = ast.drop_all_profiles;
285+
286+
if (ast.add_settings)
287+
add_settings = SettingsProfileElements{*ast.add_settings};
288+
289+
if (ast.modify_settings)
290+
modify_settings = SettingsProfileElements{*ast.modify_settings};
291+
292+
if (ast.drop_settings)
293+
drop_settings = SettingsProfileElements{*ast.drop_settings};
294+
}
295+
296+
AlterSettingsProfileElements::AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast, const AccessControl & access_control)
297+
{
298+
drop_all_settings = ast.drop_all_settings;
299+
drop_all_profiles = ast.drop_all_profiles;
300+
301+
if (ast.add_settings)
302+
add_settings = SettingsProfileElements{*ast.add_settings, access_control};
303+
304+
if (ast.modify_settings)
305+
modify_settings = SettingsProfileElements{*ast.modify_settings, access_control};
306+
307+
if (ast.drop_settings)
308+
drop_settings = SettingsProfileElements{*ast.drop_settings, access_control};
309+
}
310+
311+
void SettingsProfileElements::applyChanges(const AlterSettingsProfileElements & changes)
312+
{
313+
/// 1. First drop profiles and settings which should be dropped.
314+
if (changes.drop_all_profiles)
315+
{
316+
for (auto & element : *this)
317+
element.parent_profile.reset(); /// This makes the element empty if it's a "profile" element.
318+
}
319+
320+
if (changes.drop_all_settings)
321+
{
322+
for (auto & element : *this)
323+
{
324+
/// This makes the element empty if it's a "setting" element.
325+
/// Empty elements will be removed later at the end of this function.
326+
element.setting_name.clear();
327+
element.value.reset();
328+
element.min_value.reset();
329+
element.max_value.reset();
330+
element.writability.reset();
331+
}
332+
}
333+
334+
auto apply_drop_profile = [&](const UUID & profile_id)
335+
{
336+
for (auto & element : *this)
337+
{
338+
if (element.parent_profile == profile_id)
339+
element.parent_profile.reset(); /// This makes the element empty if it corresponds to that profile.
340+
}
341+
};
342+
343+
auto apply_drop_setting = [&](const String & setting_name, size_t end_index = -1)
344+
{
345+
if (end_index == static_cast<size_t>(-1))
346+
end_index = this->size();
347+
for (size_t i = 0; i != end_index; ++i)
348+
{
349+
auto & element = (*this)[i];
350+
if (element.setting_name == setting_name)
351+
{
352+
/// This makes the element empty if it corresponds to that setting.
353+
/// Empty elements will be removed later at the end of this function.
354+
element.setting_name.clear();
355+
element.value.reset();
356+
element.min_value.reset();
357+
element.max_value.reset();
358+
element.writability.reset();
359+
}
360+
}
361+
};
362+
363+
for (const auto & drop : changes.drop_settings)
364+
{
365+
if (drop.parent_profile)
366+
apply_drop_profile(*drop.parent_profile);
367+
if (!drop.setting_name.empty())
368+
apply_drop_setting(drop.setting_name);
369+
}
370+
371+
/// 2. Then add profiles which should be added.
372+
auto apply_add_profile = [&](const UUID & profile_id, bool check_if_exists = true)
373+
{
374+
if (check_if_exists)
375+
apply_drop_profile(profile_id);
376+
SettingsProfileElement new_element;
377+
new_element.parent_profile = profile_id;
378+
push_back(new_element);
379+
};
380+
381+
for (const auto & add : changes.add_settings)
382+
{
383+
if (add.parent_profile)
384+
apply_add_profile(*add.parent_profile);
385+
}
386+
387+
/// 3. Then add settings which should be added.
388+
auto apply_add_setting = [&](const SettingsProfileElement & add, bool check_if_exists = true)
389+
{
390+
if (check_if_exists)
391+
apply_drop_setting(add.setting_name);
392+
SettingsProfileElement new_element;
393+
new_element.setting_name = add.setting_name;
394+
new_element.value = add.value;
395+
new_element.min_value = add.min_value;
396+
new_element.max_value = add.max_value;
397+
new_element.writability = add.writability;
398+
push_back(new_element);
399+
};
400+
401+
for (const auto & add : changes.add_settings)
402+
{
403+
if (!add.setting_name.empty())
404+
apply_add_setting(add);
405+
}
406+
407+
/// 4. After that modify settings which should be modified.
408+
auto apply_modify_setting = [&](const SettingsProfileElement & modify, bool check_if_exists = true)
409+
{
410+
if (check_if_exists && !this->empty())
411+
{
412+
for (int i = static_cast<int>(this->size()) - 1; i >= 0; --i)
413+
{
414+
auto & element = (*this)[i];
415+
if (element.setting_name == modify.setting_name)
416+
{
417+
if (modify.value)
418+
element.value = modify.value;
419+
if (modify.min_value)
420+
element.min_value = modify.min_value;
421+
if (modify.max_value)
422+
element.max_value = modify.max_value;
423+
if (modify.writability)
424+
element.writability = modify.writability;
425+
apply_drop_setting(modify.setting_name, i);
426+
return;
427+
}
428+
}
429+
}
430+
apply_add_setting(modify, /* check_if_exists= */ false);
431+
};
432+
433+
for (const auto & modify : changes.modify_settings)
434+
{
435+
chassert(!modify.parent_profile); /// There is no such thing as "MODIFY PROFILE".
436+
if (!modify.setting_name.empty())
437+
apply_modify_setting(modify);
438+
}
439+
440+
/// 5. Finally remove empty elements from the result list of elements.
441+
std::erase_if(*this, [](const SettingsProfileElement & element) { return element.empty(); });
442+
}
443+
255444
}

src/Access/SettingsProfileElement.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@ namespace DB
1313
struct Settings;
1414
class SettingsChanges;
1515
class SettingsConstraints;
16+
struct AlterSettingsProfileElements;
1617
class ASTSettingsProfileElement;
1718
class ASTSettingsProfileElements;
19+
class ASTAlterSettingsProfileElements;
1820
class AccessControl;
1921

2022

@@ -44,6 +46,8 @@ struct SettingsProfileElement
4446
std::shared_ptr<ASTSettingsProfileElement> toAST() const;
4547
std::shared_ptr<ASTSettingsProfileElement> toASTWithNames(const AccessControl & access_control) const;
4648

49+
bool empty() const { return !parent_profile && (setting_name.empty() || (!value && !min_value && !max_value && !writability)); }
50+
4751
bool isConstraint() const;
4852

4953
private:
@@ -67,6 +71,8 @@ class SettingsProfileElements : public std::vector<SettingsProfileElement>
6771

6872
void merge(const SettingsProfileElements & other);
6973

74+
void applyChanges(const AlterSettingsProfileElements & changes);
75+
7076
Settings toSettings() const;
7177
SettingsChanges toSettingsChanges() const;
7278
SettingsConstraints toSettingsConstraints(const AccessControl & access_control) const;
@@ -77,4 +83,20 @@ class SettingsProfileElements : public std::vector<SettingsProfileElement>
7783
static bool isAllowBackupSetting(const String & setting_name);
7884
};
7985

86+
struct AlterSettingsProfileElements
87+
{
88+
bool drop_all_settings = false;
89+
bool drop_all_profiles = false;
90+
SettingsProfileElements add_settings;
91+
SettingsProfileElements modify_settings;
92+
SettingsProfileElements drop_settings;
93+
94+
AlterSettingsProfileElements() = default;
95+
explicit AlterSettingsProfileElements(const SettingsProfileElements & ast);
96+
explicit AlterSettingsProfileElements(const ASTSettingsProfileElements & ast);
97+
explicit AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast);
98+
AlterSettingsProfileElements(const ASTSettingsProfileElements & ast, const AccessControl & access_control);
99+
AlterSettingsProfileElements(const ASTAlterSettingsProfileElements & ast, const AccessControl & access_control);
100+
};
101+
80102
}

0 commit comments

Comments
 (0)