mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Merge pull request #49831 from vitlibar/fix-setting-null-in-profile-def
Fix setting NULL in profile definition
This commit is contained in:
commit
801cacc13f
@ -105,21 +105,21 @@ void SettingsConstraints::check(const Settings & current_settings, const Setting
|
|||||||
if (SettingsProfileElements::isAllowBackupSetting(element.setting_name))
|
if (SettingsProfileElements::isAllowBackupSetting(element.setting_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!element.value.isNull())
|
if (element.value)
|
||||||
{
|
{
|
||||||
SettingChange value(element.setting_name, element.value);
|
SettingChange value(element.setting_name, *element.value);
|
||||||
check(current_settings, value);
|
check(current_settings, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!element.min_value.isNull())
|
if (element.min_value)
|
||||||
{
|
{
|
||||||
SettingChange value(element.setting_name, element.min_value);
|
SettingChange value(element.setting_name, *element.min_value);
|
||||||
check(current_settings, value);
|
check(current_settings, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!element.max_value.isNull())
|
if (element.max_value)
|
||||||
{
|
{
|
||||||
SettingChange value(element.setting_name, element.max_value);
|
SettingChange value(element.setting_name, *element.max_value);
|
||||||
check(current_settings, value);
|
check(current_settings, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,18 +63,18 @@ void SettingsProfileElement::init(const ASTSettingsProfileElement & ast, const A
|
|||||||
max_value = ast.max_value;
|
max_value = ast.max_value;
|
||||||
writability = ast.writability;
|
writability = ast.writability;
|
||||||
|
|
||||||
if (!value.isNull())
|
if (value)
|
||||||
value = Settings::castValueUtil(setting_name, value);
|
value = Settings::castValueUtil(setting_name, *value);
|
||||||
if (!min_value.isNull())
|
if (min_value)
|
||||||
min_value = Settings::castValueUtil(setting_name, min_value);
|
min_value = Settings::castValueUtil(setting_name, *min_value);
|
||||||
if (!max_value.isNull())
|
if (max_value)
|
||||||
max_value = Settings::castValueUtil(setting_name, max_value);
|
max_value = Settings::castValueUtil(setting_name, *max_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SettingsProfileElement::isConstraint() const
|
bool SettingsProfileElement::isConstraint() const
|
||||||
{
|
{
|
||||||
return this->writability || !this->min_value.isNull() || !this->max_value.isNull();
|
return this->writability || this->min_value || this->max_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<ASTSettingsProfileElement> SettingsProfileElement::toAST() const
|
std::shared_ptr<ASTSettingsProfileElement> SettingsProfileElement::toAST() const
|
||||||
@ -187,8 +187,8 @@ Settings SettingsProfileElements::toSettings() const
|
|||||||
Settings res;
|
Settings res;
|
||||||
for (const auto & elem : *this)
|
for (const auto & elem : *this)
|
||||||
{
|
{
|
||||||
if (!elem.setting_name.empty() && !isAllowBackupSetting(elem.setting_name) && !elem.value.isNull())
|
if (!elem.setting_name.empty() && !isAllowBackupSetting(elem.setting_name) && elem.value)
|
||||||
res.set(elem.setting_name, elem.value);
|
res.set(elem.setting_name, *elem.value);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -200,8 +200,8 @@ SettingsChanges SettingsProfileElements::toSettingsChanges() const
|
|||||||
{
|
{
|
||||||
if (!elem.setting_name.empty() && !isAllowBackupSetting(elem.setting_name))
|
if (!elem.setting_name.empty() && !isAllowBackupSetting(elem.setting_name))
|
||||||
{
|
{
|
||||||
if (!elem.value.isNull())
|
if (elem.value)
|
||||||
res.push_back({elem.setting_name, elem.value});
|
res.push_back({elem.setting_name, *elem.value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
@ -214,8 +214,8 @@ SettingsConstraints SettingsProfileElements::toSettingsConstraints(const AccessC
|
|||||||
if (!elem.setting_name.empty() && elem.isConstraint() && !isAllowBackupSetting(elem.setting_name))
|
if (!elem.setting_name.empty() && elem.isConstraint() && !isAllowBackupSetting(elem.setting_name))
|
||||||
res.set(
|
res.set(
|
||||||
elem.setting_name,
|
elem.setting_name,
|
||||||
elem.min_value,
|
elem.min_value ? *elem.min_value : Field{},
|
||||||
elem.max_value,
|
elem.max_value ? *elem.max_value : Field{},
|
||||||
elem.writability ? *elem.writability : SettingConstraintWritability::WRITABLE);
|
elem.writability ? *elem.writability : SettingConstraintWritability::WRITABLE);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -240,8 +240,8 @@ bool SettingsProfileElements::isBackupAllowed() const
|
|||||||
{
|
{
|
||||||
for (const auto & setting : *this)
|
for (const auto & setting : *this)
|
||||||
{
|
{
|
||||||
if (isAllowBackupSetting(setting.setting_name))
|
if (isAllowBackupSetting(setting.setting_name) && setting.value)
|
||||||
return static_cast<bool>(SettingFieldBool{setting.value});
|
return static_cast<bool>(SettingFieldBool{*setting.value});
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,9 @@ struct SettingsProfileElement
|
|||||||
std::optional<UUID> parent_profile;
|
std::optional<UUID> parent_profile;
|
||||||
|
|
||||||
String setting_name;
|
String setting_name;
|
||||||
Field value;
|
std::optional<Field> value;
|
||||||
Field min_value;
|
std::optional<Field> min_value;
|
||||||
Field max_value;
|
std::optional<Field> max_value;
|
||||||
std::optional<SettingConstraintWritability> writability;
|
std::optional<SettingConstraintWritability> writability;
|
||||||
|
|
||||||
auto toTuple() const { return std::tie(parent_profile, setting_name, value, min_value, max_value, writability); }
|
auto toTuple() const { return std::tie(parent_profile, setting_name, value, min_value, max_value, writability); }
|
||||||
|
@ -35,21 +35,21 @@ void ASTSettingsProfileElement::formatImpl(const FormatSettings & settings, Form
|
|||||||
|
|
||||||
formatSettingName(setting_name, settings.ostr);
|
formatSettingName(setting_name, settings.ostr);
|
||||||
|
|
||||||
if (!value.isNull())
|
if (value)
|
||||||
{
|
{
|
||||||
settings.ostr << " = " << applyVisitor(FieldVisitorToString{}, value);
|
settings.ostr << " = " << applyVisitor(FieldVisitorToString{}, *value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!min_value.isNull())
|
if (min_value)
|
||||||
{
|
{
|
||||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " MIN " << (settings.hilite ? IAST::hilite_none : "")
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " MIN " << (settings.hilite ? IAST::hilite_none : "")
|
||||||
<< applyVisitor(FieldVisitorToString{}, min_value);
|
<< applyVisitor(FieldVisitorToString{}, *min_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!max_value.isNull())
|
if (max_value)
|
||||||
{
|
{
|
||||||
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " MAX " << (settings.hilite ? IAST::hilite_none : "")
|
settings.ostr << (settings.hilite ? IAST::hilite_keyword : "") << " MAX " << (settings.hilite ? IAST::hilite_none : "")
|
||||||
<< applyVisitor(FieldVisitorToString{}, max_value);
|
<< applyVisitor(FieldVisitorToString{}, *max_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writability)
|
if (writability)
|
||||||
|
@ -14,9 +14,9 @@ class ASTSettingsProfileElement : public IAST
|
|||||||
public:
|
public:
|
||||||
String parent_profile;
|
String parent_profile;
|
||||||
String setting_name;
|
String setting_name;
|
||||||
Field value;
|
std::optional<Field> value;
|
||||||
Field min_value;
|
std::optional<Field> min_value;
|
||||||
Field max_value;
|
std::optional<Field> max_value;
|
||||||
std::optional<SettingConstraintWritability> writability;
|
std::optional<SettingConstraintWritability> writability;
|
||||||
bool id_mode = false; /// If true then `parent_profile` keeps UUID, not a name.
|
bool id_mode = false; /// If true then `parent_profile` keeps UUID, not a name.
|
||||||
bool use_inherit_keyword = false; /// If true then this element is a part of ASTCreateSettingsProfileQuery.
|
bool use_inherit_keyword = false; /// If true then this element is a part of ASTCreateSettingsProfileQuery.
|
||||||
|
@ -52,7 +52,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseValue(IParserBase::Pos & pos, Expected & expected, Field & res)
|
bool parseValue(IParserBase::Pos & pos, Expected & expected, std::optional<Field> & res)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
@ -69,7 +69,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parseMinMaxValue(IParserBase::Pos & pos, Expected & expected, Field & min_value, Field & max_value)
|
bool parseMinMaxValue(IParserBase::Pos & pos, Expected & expected, std::optional<Field> & min_value, std::optional<Field> & max_value)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
{
|
{
|
||||||
@ -124,9 +124,9 @@ namespace
|
|||||||
IParserBase::Pos & pos,
|
IParserBase::Pos & pos,
|
||||||
Expected & expected,
|
Expected & expected,
|
||||||
String & setting_name,
|
String & setting_name,
|
||||||
Field & value,
|
std::optional<Field> & value,
|
||||||
Field & min_value,
|
std::optional<Field> & min_value,
|
||||||
Field & max_value,
|
std::optional<Field> & max_value,
|
||||||
std::optional<SettingConstraintWritability> & writability)
|
std::optional<SettingConstraintWritability> & writability)
|
||||||
{
|
{
|
||||||
return IParserBase::wrapParseImpl(pos, [&]
|
return IParserBase::wrapParseImpl(pos, [&]
|
||||||
@ -136,9 +136,9 @@ namespace
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
String res_setting_name = getIdentifierName(name_ast);
|
String res_setting_name = getIdentifierName(name_ast);
|
||||||
Field res_value;
|
std::optional<Field> res_value;
|
||||||
Field res_min_value;
|
std::optional<Field> res_min_value;
|
||||||
Field res_max_value;
|
std::optional<Field> res_max_value;
|
||||||
std::optional<SettingConstraintWritability> res_writability;
|
std::optional<SettingConstraintWritability> res_writability;
|
||||||
|
|
||||||
bool has_value_or_constraint = false;
|
bool has_value_or_constraint = false;
|
||||||
@ -151,7 +151,7 @@ namespace
|
|||||||
if (!has_value_or_constraint)
|
if (!has_value_or_constraint)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (boost::iequals(res_setting_name, "PROFILE") && res_value.isNull() && res_min_value.isNull() && res_max_value.isNull()
|
if (boost::iequals(res_setting_name, "PROFILE") && !res_value && !res_min_value && !res_max_value
|
||||||
&& res_writability == SettingConstraintWritability::CONST)
|
&& res_writability == SettingConstraintWritability::CONST)
|
||||||
{
|
{
|
||||||
/// Ambiguity: "profile readonly" can be treated either as a profile named "readonly" or
|
/// Ambiguity: "profile readonly" can be treated either as a profile named "readonly" or
|
||||||
@ -181,9 +181,9 @@ namespace
|
|||||||
{
|
{
|
||||||
String parent_profile;
|
String parent_profile;
|
||||||
String setting_name;
|
String setting_name;
|
||||||
Field value;
|
std::optional<Field> value;
|
||||||
Field min_value;
|
std::optional<Field> min_value;
|
||||||
Field max_value;
|
std::optional<Field> max_value;
|
||||||
std::optional<SettingConstraintWritability> writability;
|
std::optional<SettingConstraintWritability> writability;
|
||||||
|
|
||||||
bool ok = parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, writability);
|
bool ok = parseSettingNameWithValueOrConstraints(pos, expected, setting_name, value, min_value, max_value, writability);
|
||||||
|
@ -87,27 +87,27 @@ void StorageSystemSettingsProfileElements::fillData(MutableColumns & res_columns
|
|||||||
size_t current_index = index++;
|
size_t current_index = index++;
|
||||||
|
|
||||||
bool inserted_value = false;
|
bool inserted_value = false;
|
||||||
if (!element.value.isNull() && !element.setting_name.empty())
|
if (element.value && !element.setting_name.empty())
|
||||||
{
|
{
|
||||||
String str = Settings::valueToStringUtil(element.setting_name, element.value);
|
String str = Settings::valueToStringUtil(element.setting_name, *element.value);
|
||||||
column_value.insertData(str.data(), str.length());
|
column_value.insertData(str.data(), str.length());
|
||||||
column_value_null_map.push_back(false);
|
column_value_null_map.push_back(false);
|
||||||
inserted_value = true;
|
inserted_value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inserted_min = false;
|
bool inserted_min = false;
|
||||||
if (!element.min_value.isNull() && !element.setting_name.empty())
|
if (element.min_value && !element.setting_name.empty())
|
||||||
{
|
{
|
||||||
String str = Settings::valueToStringUtil(element.setting_name, element.min_value);
|
String str = Settings::valueToStringUtil(element.setting_name, *element.min_value);
|
||||||
column_min.insertData(str.data(), str.length());
|
column_min.insertData(str.data(), str.length());
|
||||||
column_min_null_map.push_back(false);
|
column_min_null_map.push_back(false);
|
||||||
inserted_min = true;
|
inserted_min = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inserted_max = false;
|
bool inserted_max = false;
|
||||||
if (!element.max_value.isNull() && !element.setting_name.empty())
|
if (element.max_value && !element.setting_name.empty())
|
||||||
{
|
{
|
||||||
String str = Settings::valueToStringUtil(element.setting_name, element.max_value);
|
String str = Settings::valueToStringUtil(element.setting_name, *element.max_value);
|
||||||
column_max.insertData(str.data(), str.length());
|
column_max.insertData(str.data(), str.length());
|
||||||
column_max_null_map.push_back(false);
|
column_max_null_map.push_back(false);
|
||||||
inserted_max = true;
|
inserted_max = true;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
--- assigning ---
|
||||||
5 UInt8
|
5 UInt8
|
||||||
-177 Int16
|
-177 Int16
|
||||||
98.11 Float64
|
98.11 Float64
|
||||||
@ -6,7 +7,7 @@ custom_a UInt64_5
|
|||||||
custom_b Int64_-177
|
custom_b Int64_-177
|
||||||
custom_c Float64_98.11
|
custom_c Float64_98.11
|
||||||
custom_d \'abc def\'
|
custom_d \'abc def\'
|
||||||
|
--- modifying ---
|
||||||
changed String
|
changed String
|
||||||
\N Nullable(Nothing)
|
\N Nullable(Nothing)
|
||||||
50000 UInt16
|
50000 UInt16
|
||||||
@ -15,9 +16,10 @@ custom_a \'changed\'
|
|||||||
custom_b NULL
|
custom_b NULL
|
||||||
custom_c UInt64_50000
|
custom_c UInt64_50000
|
||||||
custom_d Float64_1.11
|
custom_d Float64_1.11
|
||||||
|
--- undefined setting ---
|
||||||
404 UInt16
|
404 UInt16
|
||||||
|
--- wrong prefix ---
|
||||||
|
--- using query context ---
|
||||||
-0.333 Float64
|
-0.333 Float64
|
||||||
custom_e Float64_-0.333
|
custom_e Float64_-0.333
|
||||||
404 UInt16
|
404 UInt16
|
||||||
@ -25,7 +27,13 @@ custom_e UInt64_404
|
|||||||
word String
|
word String
|
||||||
custom_f \'word\'
|
custom_f \'word\'
|
||||||
0
|
0
|
||||||
|
--- compound identifier ---
|
||||||
test String
|
test String
|
||||||
custom_compound.identifier.v1 \'test\'
|
custom_compound.identifier.v1 \'test\'
|
||||||
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100
|
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100
|
||||||
|
--- null type ---
|
||||||
|
\N Nullable(Nothing)
|
||||||
|
custom_null NULL
|
||||||
|
\N Nullable(Nothing)
|
||||||
|
custom_null NULL
|
||||||
|
CREATE SETTINGS PROFILE s2_01418 SETTINGS custom_null = NULL
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
DROP SETTINGS PROFILE IF EXISTS s1_01418, s2_01418;
|
||||||
|
|
||||||
|
SELECT '--- assigning ---';
|
||||||
SET custom_a = 5;
|
SET custom_a = 5;
|
||||||
SET custom_b = -177;
|
SET custom_b = -177;
|
||||||
SET custom_c = 98.11;
|
SET custom_c = 98.11;
|
||||||
@ -8,7 +11,7 @@ SELECT getSetting('custom_c') as v, toTypeName(v);
|
|||||||
SELECT getSetting('custom_d') as v, toTypeName(v);
|
SELECT getSetting('custom_d') as v, toTypeName(v);
|
||||||
SELECT name, value FROM system.settings WHERE name LIKE 'custom_%' ORDER BY name;
|
SELECT name, value FROM system.settings WHERE name LIKE 'custom_%' ORDER BY name;
|
||||||
|
|
||||||
SELECT '';
|
SELECT '--- modifying ---';
|
||||||
SET custom_a = 'changed';
|
SET custom_a = 'changed';
|
||||||
SET custom_b = NULL;
|
SET custom_b = NULL;
|
||||||
SET custom_c = 50000;
|
SET custom_c = 50000;
|
||||||
@ -19,14 +22,15 @@ SELECT getSetting('custom_c') as v, toTypeName(v);
|
|||||||
SELECT getSetting('custom_d') as v, toTypeName(v);
|
SELECT getSetting('custom_d') as v, toTypeName(v);
|
||||||
SELECT name, value FROM system.settings WHERE name LIKE 'custom_%' ORDER BY name;
|
SELECT name, value FROM system.settings WHERE name LIKE 'custom_%' ORDER BY name;
|
||||||
|
|
||||||
SELECT '';
|
SELECT '--- undefined setting ---';
|
||||||
SELECT getSetting('custom_e') as v, toTypeName(v); -- { serverError 115 } -- Setting not found.
|
SELECT getSetting('custom_e') as v, toTypeName(v); -- { serverError 115 } -- Setting not found.
|
||||||
SET custom_e = 404;
|
SET custom_e = 404;
|
||||||
SELECT getSetting('custom_e') as v, toTypeName(v);
|
SELECT getSetting('custom_e') as v, toTypeName(v);
|
||||||
|
|
||||||
|
SELECT '--- wrong prefix ---';
|
||||||
SET invalid_custom = 8; -- { serverError 115 } -- Setting is neither a builtin nor started with one of the registered prefixes for user-defined settings.
|
SET invalid_custom = 8; -- { serverError 115 } -- Setting is neither a builtin nor started with one of the registered prefixes for user-defined settings.
|
||||||
|
|
||||||
SELECT '';
|
SELECT '--- using query context ---';
|
||||||
SELECT getSetting('custom_e') as v, toTypeName(v) SETTINGS custom_e = -0.333;
|
SELECT getSetting('custom_e') as v, toTypeName(v) SETTINGS custom_e = -0.333;
|
||||||
SELECT name, value FROM system.settings WHERE name = 'custom_e' SETTINGS custom_e = -0.333;
|
SELECT name, value FROM system.settings WHERE name = 'custom_e' SETTINGS custom_e = -0.333;
|
||||||
SELECT getSetting('custom_e') as v, toTypeName(v);
|
SELECT getSetting('custom_e') as v, toTypeName(v);
|
||||||
@ -37,7 +41,7 @@ SELECT name, value FROM system.settings WHERE name = 'custom_f' SETTINGS custom_
|
|||||||
SELECT getSetting('custom_f') as v, toTypeName(v); -- { serverError 115 } -- Setting not found.
|
SELECT getSetting('custom_f') as v, toTypeName(v); -- { serverError 115 } -- Setting not found.
|
||||||
SELECT COUNT() FROM system.settings WHERE name = 'custom_f';
|
SELECT COUNT() FROM system.settings WHERE name = 'custom_f';
|
||||||
|
|
||||||
SELECT '';
|
SELECT '--- compound identifier ---';
|
||||||
SET custom_compound.identifier.v1 = 'test';
|
SET custom_compound.identifier.v1 = 'test';
|
||||||
SELECT getSetting('custom_compound.identifier.v1') as v, toTypeName(v);
|
SELECT getSetting('custom_compound.identifier.v1') as v, toTypeName(v);
|
||||||
SELECT name, value FROM system.settings WHERE name = 'custom_compound.identifier.v1';
|
SELECT name, value FROM system.settings WHERE name = 'custom_compound.identifier.v1';
|
||||||
@ -45,3 +49,15 @@ SELECT name, value FROM system.settings WHERE name = 'custom_compound.identifier
|
|||||||
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100;
|
CREATE SETTINGS PROFILE s1_01418 SETTINGS custom_compound.identifier.v2 = 100;
|
||||||
SHOW CREATE SETTINGS PROFILE s1_01418;
|
SHOW CREATE SETTINGS PROFILE s1_01418;
|
||||||
DROP SETTINGS PROFILE s1_01418;
|
DROP SETTINGS PROFILE s1_01418;
|
||||||
|
|
||||||
|
SELECT '--- null type ---';
|
||||||
|
SELECT getSetting('custom_null') as v, toTypeName(v) SETTINGS custom_null = NULL;
|
||||||
|
SELECT name, value FROM system.settings WHERE name = 'custom_null' SETTINGS custom_null = NULL;
|
||||||
|
|
||||||
|
SET custom_null = NULL;
|
||||||
|
SELECT getSetting('custom_null') as v, toTypeName(v);
|
||||||
|
SELECT name, value FROM system.settings WHERE name = 'custom_null';
|
||||||
|
|
||||||
|
CREATE SETTINGS PROFILE s2_01418 SETTINGS custom_null = NULL;
|
||||||
|
SHOW CREATE SETTINGS PROFILE s2_01418;
|
||||||
|
DROP SETTINGS PROFILE s2_01418;
|
||||||
|
Loading…
Reference in New Issue
Block a user