From af3bf39aad8c5ec58a3d8e2f59f4c10aa804d231 Mon Sep 17 00:00:00 2001 From: robot-clickhouse Date: Thu, 15 Oct 2020 17:42:24 +0300 Subject: [PATCH] Backport #15982 to 20.9: Fix ambiguity in parsing of settings profiles. --- src/Parsers/ParserSettingsProfileElement.cpp | 37 +++++++++++++------ .../01294_create_settings_profile.reference | 7 ++++ .../01294_create_settings_profile.sql | 15 ++++++++ 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/src/Parsers/ParserSettingsProfileElement.cpp b/src/Parsers/ParserSettingsProfileElement.cpp index f1e66a296e70..d7d982efe236 100644 --- a/src/Parsers/ParserSettingsProfileElement.cpp +++ b/src/Parsers/ParserSettingsProfileElement.cpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace DB @@ -14,8 +15,16 @@ namespace { bool parseProfileKeyword(IParserBase::Pos & pos, Expected & expected, bool use_inherit_keyword) { - return ParserKeyword{"PROFILE"}.ignore(pos, expected) || - (use_inherit_keyword && ParserKeyword{"INHERIT"}.ignore(pos, expected)); + if (ParserKeyword{"PROFILE"}.ignore(pos, expected)) + return true; + + if (use_inherit_keyword && ParserKeyword{"INHERIT"}.ignore(pos, expected)) + { + ParserKeyword{"PROFILE"}.ignore(pos, expected); + return true; + } + + return false; } @@ -137,6 +146,15 @@ namespace if (!has_value_or_constraint) return false; + if (boost::iequals(res_setting_name, "PROFILE") && res_value.isNull() && res_min_value.isNull() && res_max_value.isNull() + && res_readonly) + { + /// Ambiguity: "profile readonly" can be treated either as a profile named "readonly" or + /// as a setting named 'profile' with the readonly constraint. + /// So we've decided to treat it as a profile named "readonly". + return false; + } + setting_name = std::move(res_setting_name); value = std::move(res_value); min_value = std::move(res_min_value); @@ -163,15 +181,12 @@ namespace Field max_value; std::optional readonly; - if (parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, readonly)) - { - } - else if (parseProfileKeyword(pos, expected, use_inherit_keyword) || previous_element_was_parent_profile) - { - if (!parseProfileNameOrID(pos, expected, id_mode, parent_profile)) - return false; - } - else + bool ok = parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, readonly); + + if (!ok && (parseProfileKeyword(pos, expected, use_inherit_keyword) || previous_element_was_parent_profile)) + ok = parseProfileNameOrID(pos, expected, id_mode, parent_profile); + + if (!ok) return false; result = std::make_shared(); diff --git a/tests/queries/0_stateless/01294_create_settings_profile.reference b/tests/queries/0_stateless/01294_create_settings_profile.reference index 0780a42ebed7..ab1b3833419f 100644 --- a/tests/queries/0_stateless/01294_create_settings_profile.reference +++ b/tests/queries/0_stateless/01294_create_settings_profile.reference @@ -41,6 +41,13 @@ CREATE SETTINGS PROFILE s1_01294 SETTINGS max_memory_usage = 6000000 CREATE SETTINGS PROFILE s2_01294 SETTINGS max_memory_usage = 6000000 TO r1_01294 CREATE SETTINGS PROFILE s3_01294 SETTINGS max_memory_usage = 6000000 TO r1_01294 CREATE SETTINGS PROFILE s4_01294 TO r1_01294 +-- readonly ambiguity +CREATE SETTINGS PROFILE s1_01294 SETTINGS readonly = 1 +CREATE SETTINGS PROFILE s2_01294 SETTINGS readonly READONLY +CREATE SETTINGS PROFILE s3_01294 SETTINGS INHERIT readonly +CREATE SETTINGS PROFILE s4_01294 SETTINGS INHERIT readonly, INHERIT readonly +CREATE SETTINGS PROFILE s5_01294 SETTINGS INHERIT readonly, readonly = 1 +CREATE SETTINGS PROFILE s6_01294 SETTINGS INHERIT readonly, readonly READONLY -- system.settings_profiles s1_01294 local directory 0 0 [] [] s2_01294 local directory 1 0 ['r1_01294'] [] diff --git a/tests/queries/0_stateless/01294_create_settings_profile.sql b/tests/queries/0_stateless/01294_create_settings_profile.sql index 2d34042f2b44..9dbabd3f0681 100644 --- a/tests/queries/0_stateless/01294_create_settings_profile.sql +++ b/tests/queries/0_stateless/01294_create_settings_profile.sql @@ -87,6 +87,21 @@ ALTER PROFILE s2_01294, s3_01294, s4_01294 TO r1_01294; SHOW CREATE PROFILE s1_01294, s2_01294, s3_01294, s4_01294; DROP PROFILE s1_01294, s2_01294, s3_01294, s4_01294; +SELECT '-- readonly ambiguity'; +CREATE PROFILE s1_01294 SETTINGS readonly=1; +CREATE PROFILE s2_01294 SETTINGS readonly readonly; +CREATE PROFILE s3_01294 SETTINGS profile readonly; +CREATE PROFILE s4_01294 SETTINGS profile readonly, readonly; +CREATE PROFILE s5_01294 SETTINGS profile readonly, readonly=1; +CREATE PROFILE s6_01294 SETTINGS profile readonly, readonly readonly; +SHOW CREATE PROFILE s1_01294; +SHOW CREATE PROFILE s2_01294; +SHOW CREATE PROFILE s3_01294; +SHOW CREATE PROFILE s4_01294; +SHOW CREATE PROFILE s5_01294; +SHOW CREATE PROFILE s6_01294; +DROP PROFILE s1_01294, s2_01294, s3_01294, s4_01294, s5_01294, s6_01294; + SELECT '-- system.settings_profiles'; CREATE PROFILE s1_01294; CREATE PROFILE s2_01294 SETTINGS readonly=0 TO r1_01294;;