diff --git a/src/Access/SettingsConstraints.cpp b/src/Access/SettingsConstraints.cpp index 8ca2262f8cd666fbd46f5437e34d5bd23632662b..2c16f23583faa97e75009c73026471188db145c9 100644 --- a/src/Access/SettingsConstraints.cpp +++ b/src/Access/SettingsConstraints.cpp @@ -38,7 +38,7 @@ void SettingsConstraints::setMinValue(const StringRef & setting_name, const Fiel void SettingsConstraints::setMinValue(size_t setting_index, const Field & min_value) { - getConstraintRef(setting_index).min_value = Settings::valueToCorrespondingType(setting_index, min_value); + getConstraintRef(setting_index).min_value = Settings::castValue(setting_index, min_value); } Field SettingsConstraints::getMinValue(const StringRef & setting_name) const @@ -63,7 +63,7 @@ void SettingsConstraints::setMaxValue(const StringRef & name, const Field & max_ void SettingsConstraints::setMaxValue(size_t setting_index, const Field & max_value) { - getConstraintRef(setting_index).max_value = Settings::valueToCorrespondingType(setting_index, max_value); + getConstraintRef(setting_index).max_value = Settings::castValue(setting_index, max_value); } Field SettingsConstraints::getMaxValue(const StringRef & setting_name) const @@ -179,7 +179,7 @@ void SettingsConstraints::check(const Settings & current_settings, const Setting if (setting_index == Settings::npos) return; - Field new_value = Settings::valueToCorrespondingType(setting_index, change.value); + Field new_value = Settings::castValue(setting_index, change.value); Field current_value = current_settings.get(setting_index); /// Setting isn't checked if value wasn't changed. @@ -233,7 +233,7 @@ void SettingsConstraints::clamp(const Settings & current_settings, SettingChange if (setting_index == Settings::npos) return; - Field new_value = Settings::valueToCorrespondingType(setting_index, change.value); + Field new_value = Settings::castValue(setting_index, change.value); Field current_value = current_settings.get(setting_index); /// Setting isn't checked if value wasn't changed. diff --git a/src/Access/SettingsProfileElement.cpp b/src/Access/SettingsProfileElement.cpp index 4fbe4aec2f8c4749f157480c98bd71e24306ccab..cb9b26cce53c3493d856bebc81582fbf6d77d65e 100644 --- a/src/Access/SettingsProfileElement.cpp +++ b/src/Access/SettingsProfileElement.cpp @@ -43,11 +43,11 @@ void SettingsProfileElement::init(const ASTSettingsProfileElement & ast, const A readonly = ast.readonly; if (!value.isNull()) - value = Settings::valueToCorrespondingType(setting_index, value); + value = Settings::castValue(setting_index, value); if (!min_value.isNull()) - min_value = Settings::valueToCorrespondingType(setting_index, min_value); + min_value = Settings::castValue(setting_index, min_value); if (!max_value.isNull()) - max_value = Settings::valueToCorrespondingType(setting_index, max_value); + max_value = Settings::castValue(setting_index, max_value); } } diff --git a/src/Access/UsersConfigAccessStorage.cpp b/src/Access/UsersConfigAccessStorage.cpp index e3fb9104a6668c51c2e42a2cafdaa37f231ebfe4..a4a0acfc664ea11d331e6b687f678bfe7b16370f 100644 --- a/src/Access/UsersConfigAccessStorage.cpp +++ b/src/Access/UsersConfigAccessStorage.cpp @@ -375,9 +375,9 @@ namespace for (const String & constraint_type : constraint_types) { if (constraint_type == "min") - profile_element.min_value = Settings::valueToCorrespondingType(setting_index, config.getString(path_to_name + "." + constraint_type)); + profile_element.min_value = Settings::stringToValue(setting_index, config.getString(path_to_name + "." + constraint_type)); else if (constraint_type == "max") - profile_element.max_value = Settings::valueToCorrespondingType(setting_index, config.getString(path_to_name + "." + constraint_type)); + profile_element.max_value = Settings::stringToValue(setting_index, config.getString(path_to_name + "." + constraint_type)); else if (constraint_type == "readonly") profile_element.readonly = true; else @@ -419,7 +419,7 @@ namespace SettingsProfileElement profile_element; size_t setting_index = Settings::findIndexStrict(key); profile_element.setting_index = setting_index; - profile_element.value = Settings::valueToCorrespondingType(setting_index, config.getString(profile_config + "." + key)); + profile_element.value = Settings::stringToValue(setting_index, config.getString(profile_config + "." + key)); profile->elements.emplace_back(std::move(profile_element)); } diff --git a/src/Core/Settings.h b/src/Core/Settings.h index 208de421b76a1a2f6e1f5d98f2b48dee6386d7f9..9cc26f9c3248fb379e0667a57231174c77d47085 100644 --- a/src/Core/Settings.h +++ b/src/Core/Settings.h @@ -433,7 +433,7 @@ struct Settings : public SettingsCollection M(Bool, input_format_values_deduce_templates_of_expressions, true, "For Values format: if the field could not be parsed by streaming parser, run SQL parser, deduce template of the SQL expression, try to parse all rows using template and then interpret expression for all rows.", 0) \ M(Bool, input_format_values_accurate_types_of_literals, true, "For Values format: when parsing and interpreting expressions using template, check actual type of literal to avoid possible overflow and precision issues.", 0) \ M(Bool, input_format_avro_allow_missing_fields, false, "For Avro/AvroConfluent format: when field is not found in schema use default value instead of error", 0) \ - M(URI, format_avro_schema_registry_url, {}, "For AvroConfluent format: Confluent Schema Registry URL.", 0) \ + M(URI, format_avro_schema_registry_url, "", "For AvroConfluent format: Confluent Schema Registry URL.", 0) \ \ M(Bool, output_format_json_quote_64bit_integers, true, "Controls quoting of 64-bit integers in JSON output format.", 0) \ \ diff --git a/src/Core/SettingsCollection.h b/src/Core/SettingsCollection.h index 5a6bef3d1d01f39dfdb7f6c06ea8e58fade1ae9f..9b19e7ae04e4a820b512c2652c9e0eecff634417 100644 --- a/src/Core/SettingsCollection.h +++ b/src/Core/SettingsCollection.h @@ -49,28 +49,30 @@ private: struct MemberInfo { using IsChangedFunction = bool (*)(const Derived &); - using GetStringFunction = String (*)(const Derived &); - using GetFieldFunction = Field (*)(const Derived &); - using SetStringFunction = void (*)(Derived &, const String &); - using SetFieldFunction = void (*)(Derived &, const Field &); + using GetValueFunction = Field (*)(const Derived &); + using SetValueFunction = void (*)(Derived &, const Field &); + using GetValueAsStringFunction = String (*)(const Derived &); + using ParseValueFromStringFunction = void (*)(Derived &, const String &); using WriteBinaryFunction = void (*)(const Derived &, WriteBuffer & buf); using ReadBinaryFunction = void (*)(Derived &, ReadBuffer & buf); + using CastValueFunction = Field (*)(const Field &); + using StringToValueFunction = Field (*)(const String &); using ValueToStringFunction = String (*)(const Field &); - using ValueToCorrespondingTypeFunction = Field (*)(const Field &); StringRef name; StringRef description; StringRef type; bool is_important; IsChangedFunction is_changed; - GetStringFunction get_string; - GetFieldFunction get_field; - SetStringFunction set_string; - SetFieldFunction set_field; + GetValueFunction get_value; + SetValueFunction set_value; + GetValueAsStringFunction get_value_as_string; + ParseValueFromStringFunction parse_value_from_string; WriteBinaryFunction write_binary; ReadBinaryFunction read_binary; + CastValueFunction cast_value; + StringToValueFunction string_to_value; ValueToStringFunction value_to_string; - ValueToCorrespondingTypeFunction value_to_corresponding_type; }; class MemberInfos @@ -110,7 +112,7 @@ public: const StringRef & getType() const { return member->type; } bool isChanged() const { return member->is_changed(*collection); } Field getValue() const; - String getValueAsString() const { return member->get_string(*collection); } + String getValueAsString() const { return member->get_value_as_string(*collection); } protected: friend class SettingsCollection::const_iterator; @@ -126,8 +128,8 @@ public: public: reference(Derived & collection_, const MemberInfo & member_) : const_reference(collection_, member_) {} reference(const const_reference & src) : const_reference(src) {} - void setValue(const Field & value) { this->member->set_field(*const_cast(this->collection), value); } - void setValue(const String & value) { this->member->set_string(*const_cast(this->collection), value); } + void setValue(const Field & value) { this->member->set_value(*const_cast(this->collection), value); } + void parseFromString(const String & value) { this->member->parse_value_from_string(*const_cast(this->collection), value); } }; /// Iterator to iterating through all the settings. @@ -178,15 +180,17 @@ public: /// Searches a setting by its name; throws an exception if not found. static size_t findIndexStrict(const StringRef & name) { return members().findIndexStrict(name); } + /// Casts a value to a type according to a specified setting without actual changing this settings. + /// E.g. for SettingInt64 it casts Field to Field::Types::Int64. + static Field castValue(size_t index, const Field & value); + static Field castValue(const StringRef & name, const Field & value); + /// Casts a value to a string according to a specified setting without actual changing this settings. + static Field stringToValue(size_t index, const String & str) { return members()[index].string_to_value(str); } + static Field stringToValue(const StringRef & name, const String & str) { return members().findStrict(name).string_to_value(str); } static String valueToString(size_t index, const Field & value) { return members()[index].value_to_string(value); } static String valueToString(const StringRef & name, const Field & value) { return members().findStrict(name).value_to_string(value); } - /// Casts a value to a type according to a specified setting without actual changing this settings. - /// E.g. for SettingInt64 it casts Field to Field::Types::Int64. - static Field valueToCorrespondingType(size_t index, const Field & value); - static Field valueToCorrespondingType(const StringRef & name, const Field & value); - iterator begin() { return iterator(castToDerived(), members().data()); } const_iterator begin() const { return const_iterator(castToDerived(), members().data()); } iterator end() { const auto & the_members = members(); return iterator(castToDerived(), the_members.data() + the_members.size()); } diff --git a/src/Core/SettingsCollectionImpl.h b/src/Core/SettingsCollectionImpl.h index 913ba9f5b337b139064c5767d53c69bb9bfc8548..fd365b9587e76452999795c7fb5b93303936b7b2 100644 --- a/src/Core/SettingsCollectionImpl.h +++ b/src/Core/SettingsCollectionImpl.h @@ -6,8 +6,10 @@ * instantiation of SettingsCollection<>. */ +#include #include #include +#include namespace DB @@ -86,16 +88,16 @@ SettingsCollection::members() template Field SettingsCollection::const_reference::getValue() const { - return member->get_field(*collection); + return member->get_value(*collection); } template -Field SettingsCollection::valueToCorrespondingType(size_t index, const Field & value) +Field SettingsCollection::castValue(size_t index, const Field & value) { try { - return members()[index].value_to_corresponding_type(value); + return members()[index].cast_value(value); } catch (Exception & e) { @@ -107,9 +109,9 @@ Field SettingsCollection::valueToCorrespondingType(size_t index, const template -Field SettingsCollection::valueToCorrespondingType(const StringRef & name, const Field & value) +Field SettingsCollection::castValue(const StringRef & name, const Field & value) { - return members().findStrict(name).value_to_corresponding_type(value); + return members().findStrict(name).cast_value(value); } @@ -196,7 +198,7 @@ bool SettingsCollection::operator ==(const SettingsCollection { if (left_changed != right_changed) return false; - if (member.get_field(castToDerived()) != member.get_field(rhs.castToDerived())) + if (member.get_value(castToDerived()) != member.get_value(rhs.castToDerived())) return false; } } @@ -213,7 +215,7 @@ SettingsChanges SettingsCollection::changes() const { const auto & member = the_members[i]; if (member.is_changed(castToDerived())) - found_changes.push_back({member.name.toString(), member.get_field(castToDerived())}); + found_changes.push_back({member.name.toString(), member.get_value(castToDerived())}); } return found_changes; } @@ -255,7 +257,7 @@ void SettingsCollection::copyChangesFrom(const Derived & src) { const auto & member = the_members[i]; if (member.is_changed(src)) - member.set_field(castToDerived(), member.get_field(src)); + member.set_value(castToDerived(), member.get_value(src)); } } @@ -280,7 +282,7 @@ void SettingsCollection::serialize(WriteBuffer & buf, SettingsBinaryFor if (format >= SettingsBinaryFormat::STRINGS) { details::SettingsCollectionUtils::serializeFlag(member.is_important, buf); - details::SettingsCollectionUtils::serializeName(member.get_string(castToDerived()), buf); + details::SettingsCollectionUtils::serializeName(member.get_value_as_string(castToDerived()), buf); } else member.write_binary(castToDerived(), buf); @@ -320,7 +322,7 @@ void SettingsCollection::deserialize(ReadBuffer & buf, SettingsBinaryFo if (format >= SettingsBinaryFormat::STRINGS) { String value = details::SettingsCollectionUtils::deserializeName(buf); - member->set_string(castToDerived(), value); + member->parse_value_from_string(castToDerived(), value); } else member->read_binary(castToDerived(), buf); @@ -350,14 +352,15 @@ void SettingsCollection::deserialize(ReadBuffer & buf, SettingsBinaryFo #define IMPLEMENT_SETTINGS_COLLECTION_DEFINE_FUNCTIONS_HELPER_(TYPE, NAME, DEFAULT, DESCRIPTION, FLAGS) \ - static String NAME##_getString(const Derived & collection) { return collection.NAME.toString(); } \ - static Field NAME##_getField(const Derived & collection) { return collection.NAME.toField(); } \ - static void NAME##_setString(Derived & collection, const String & value) { collection.NAME.set(value); } \ - static void NAME##_setField(Derived & collection, const Field & value) { collection.NAME.set(value); } \ + static Field NAME##_getValue(const Derived & collection) { return static_cast(collection.NAME); } \ + static void NAME##_setValue(Derived & collection, const Field & value) { collection.NAME = value; } \ + static String NAME##_toString(const Derived & collection) { return collection.NAME.toString(); } \ + static void NAME##_parseFromString(Derived & collection, const String & value) { collection.NAME.parseFromString(value); } \ static void NAME##_writeBinary(const Derived & collection, WriteBuffer & buf) { collection.NAME.writeBinary(buf); } \ static void NAME##_readBinary(Derived & collection, ReadBuffer & buf) { collection.NAME.readBinary(buf); } \ - static String NAME##_valueToString(const Field & value) { SettingField##TYPE temp{DEFAULT}; temp.set(value); return temp.toString(); } \ - static Field NAME##_valueToCorrespondingType(const Field & value) { SettingField##TYPE temp{DEFAULT}; temp.set(value); return temp.toField(); } \ + static Field NAME##_castValue(const Field & value) { return static_cast(SettingField##TYPE{value}); } \ + static Field NAME##_stringToValue(const String & str) { SettingField##TYPE temp; temp.parseFromString(str); return static_cast(temp); } \ + static String NAME##_valueToString(const Field & value) { return SettingField##TYPE{value}.toString(); } \ #define IMPLEMENT_SETTINGS_COLLECTION_ADD_MEMBER_INFO_HELPER_(TYPE, NAME, DEFAULT, DESCRIPTION, FLAGS) \ @@ -366,8 +369,8 @@ void SettingsCollection::deserialize(ReadBuffer & buf, SettingsBinaryFo StringRef(#TYPE, strlen(#TYPE)), \ FLAGS & IMPORTANT, \ [](const Derived & d) { return d.NAME.changed; }, \ - &Functions::NAME##_getString, &Functions::NAME##_getField, \ - &Functions::NAME##_setString, &Functions::NAME##_setField, \ + &Functions::NAME##_getValue, &Functions::NAME##_setValue, \ + &Functions::NAME##_toString, &Functions::NAME##_parseFromString, \ &Functions::NAME##_writeBinary, &Functions::NAME##_readBinary, \ - &Functions::NAME##_valueToString, &Functions::NAME##_valueToCorrespondingType}); + &Functions::NAME##_castValue, &Functions::NAME##_stringToValue, &Functions::NAME##_valueToString }); } diff --git a/src/Core/SettingsFields.cpp b/src/Core/SettingsFields.cpp index b2053a6a8c15966e101c8dbb798c9eb993efc32d..628e6ef6d4c75e95ca97dd242fea94333ac35d95 100644 --- a/src/Core/SettingsFields.cpp +++ b/src/Core/SettingsFields.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace DB @@ -18,100 +19,96 @@ namespace ErrorCodes } -template -String SettingFieldNumber::toString() const +namespace { - return DB::toString(value); -} + template + T stringToNumber(const String & str) + { + if constexpr (std::is_same_v) + { + if (str == "0") + return false; + if (str == "1") + return true; + if (boost::iequals(str, "false")) + return false; + if (boost::iequals(str, "true")) + return true; + throw Exception("Cannot parse bool from string '" + str + "'", ErrorCodes::CANNOT_PARSE_BOOL); + } + else + return parseWithSizeSuffix(str); + } -template -Field SettingFieldNumber::toField() const -{ - return value; + template + T fieldToNumber(const Field & f) + { + if (f.getType() == Field::Types::String) + return stringToNumber(f.get()); + else + return applyVisitor(FieldVisitorConvertToNumber(), f); + } } -template -void SettingFieldNumber::set(Type x) +template +SettingFieldNumber::SettingFieldNumber(const Field & f) : SettingFieldNumber(fieldToNumber(f)) { - value = x; - changed = true; } -template -void SettingFieldNumber::set(const Field & x) +template +SettingFieldNumber & SettingFieldNumber::operator=(const Field & f) { - if (x.getType() == Field::Types::String) - set(get(x)); - else - set(applyVisitor(FieldVisitorConvertToNumber(), x)); + *this = fieldToNumber(f); + return *this; } -template -void SettingFieldNumber::set(const String & x) +template +String SettingFieldNumber::toString() const { - set(parseWithSizeSuffix(x)); + return ::DB::toString(value); } -template <> -void SettingFieldNumber::set(const String & x) +template +void SettingFieldNumber::parseFromString(const String & str) { - if (x.size() == 1) - { - if (x[0] == '0') - set(false); - else if (x[0] == '1') - set(true); - else - throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); - } - else - { - ReadBufferFromString buf(x); - if (checkStringCaseInsensitive("true", buf)) - set(true); - else if (checkStringCaseInsensitive("false", buf)) - set(false); - else - throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL); - } + *this = stringToNumber(str); } - -template -void SettingFieldNumber::writeBinary(WriteBuffer & out) const +template +void SettingFieldNumber::writeBinary(WriteBuffer & out) const { - if constexpr (is_integral_v && is_unsigned_v) + if constexpr (is_integral_v && is_unsigned_v) writeVarUInt(static_cast(value), out); - else if constexpr (is_integral_v && is_signed_v) + else if constexpr (is_integral_v && is_signed_v) writeVarInt(static_cast(value), out); else { - static_assert(std::is_floating_point_v); - writeStringBinary(toString(), out); + static_assert(std::is_floating_point_v); + writeStringBinary(::DB::toString(value), out); } } -template -void SettingFieldNumber::readBinary(ReadBuffer & in) +template +void SettingFieldNumber::readBinary(ReadBuffer & in) { - if constexpr (is_integral_v && is_unsigned_v) + if constexpr (is_integral_v && is_unsigned_v) { UInt64 x; readVarUInt(x, in); - set(static_cast(x)); + *this = static_cast(x); } - else if constexpr (is_integral_v && is_signed_v) + else if constexpr (is_integral_v && is_signed_v) { Int64 x; readVarInt(x, in); - set(static_cast(x)); + *this = static_cast(value); } else { - static_assert(std::is_floating_point_v); - String x; - readStringBinary(x, in); - set(x); + static_assert(std::is_floating_point_v); + String str; + readStringBinary(str, in); + *this = ::DB::parseFromString(str); } } @@ -121,50 +118,45 @@ template struct SettingFieldNumber; template struct SettingFieldNumber; -String SettingFieldMaxThreads::toString() const +namespace { - /// Instead of the `auto` value, we output the actual value to make it easier to see. - return is_auto ? ("auto(" + DB::toString(value) + ")") : DB::toString(value); -} + UInt64 stringToMaxThreads(const String & str) + { + if (startsWith(str, "auto")) + return 0; + return parseFromString(str); + } -Field SettingFieldMaxThreads::toField() const -{ - return is_auto ? 0 : value; + UInt64 fieldToMaxThreads(const Field & f) + { + if (f.getType() == Field::Types::String) + return stringToMaxThreads(f.get()); + else + return applyVisitor(FieldVisitorConvertToNumber(), f); + } } -void SettingFieldMaxThreads::set(UInt64 x) +SettingFieldMaxThreads::SettingFieldMaxThreads(const Field & f) : SettingFieldMaxThreads(fieldToMaxThreads(f)) { - value = x ? x : getAutoValue(); - is_auto = x == 0; - changed = true; } -void SettingFieldMaxThreads::set(const Field & x) +SettingFieldMaxThreads & SettingFieldMaxThreads::operator=(const Field & f) { - if (x.getType() == Field::Types::String) - set(get(x)); - else - set(applyVisitor(FieldVisitorConvertToNumber(), x)); + *this = fieldToMaxThreads(f); + return *this; } -void SettingFieldMaxThreads::set(const String & x) +String SettingFieldMaxThreads::toString() const { - if (startsWith(x, "auto")) - setAuto(); + if (is_auto) + return "'auto(" + ::DB::toString(value) + ")'"; else - set(parse(x)); + return ::DB::toString(value); } -void SettingFieldMaxThreads::setAuto() +void SettingFieldMaxThreads::parseFromString(const String & str) { - value = getAutoValue(); - is_auto = true; -} - -UInt64 SettingFieldMaxThreads::getAutoValue() -{ - static auto res = getNumberOfPhysicalCPUCores(); - return res; + *this = stringToMaxThreads(str); } void SettingFieldMaxThreads::writeBinary(WriteBuffer & out) const @@ -176,83 +168,57 @@ void SettingFieldMaxThreads::readBinary(ReadBuffer & in) { UInt64 x = 0; readVarUInt(x, in); - set(x); + *this = x; } - -template -String SettingFieldTimespan::toString() const +UInt64 SettingFieldMaxThreads::getAuto() { - return DB::toString(value.totalMicroseconds() / microseconds_per_unit); + return getNumberOfPhysicalCPUCores(); } -template -Field SettingFieldTimespan::toField() const -{ - return value.totalMicroseconds() / microseconds_per_unit; -} - -template -void SettingFieldTimespan::set(const Poco::Timespan & x) -{ - value = x; - changed = true; -} -template -void SettingFieldTimespan::set(UInt64 x) +template +SettingFieldTimespan::SettingFieldTimespan(const Field & f) : SettingFieldTimespan(fieldToNumber(f)) { - set(Poco::Timespan(x * microseconds_per_unit)); } -template -void SettingFieldTimespan::set(const Field & x) +template +SettingFieldTimespan & SettingFieldTimespan::operator=(const Field & f) { - if (x.getType() == Field::Types::String) - set(get(x)); - else - set(applyVisitor(FieldVisitorConvertToNumber(), x)); + *this = fieldToNumber(f); + return *this; } -template -void SettingFieldTimespan::set(const String & x) +template +String SettingFieldTimespan::toString() const { - set(parse(x)); + return ::DB::toString(operator UInt64()); } -template -void SettingFieldTimespan::writeBinary(WriteBuffer & out) const +template +void SettingFieldTimespan::parseFromString(const String & str) { - writeVarUInt(value.totalMicroseconds() / microseconds_per_unit, out); + *this = stringToNumber(str); } -template -void SettingFieldTimespan::readBinary(ReadBuffer & in) +template +void SettingFieldTimespan::writeBinary(WriteBuffer & out) const { - UInt64 x = 0; - readVarUInt(x, in); - set(x); + auto num_units = operator UInt64(); + writeVarUInt(num_units, out); } -template struct SettingFieldTimespan; -template struct SettingFieldTimespan; - - -Field SettingFieldString::toField() const +template +void SettingFieldTimespan::readBinary(ReadBuffer & in) { - return value; + UInt64 num_units = 0; + readVarUInt(num_units, in); + *this = num_units; } -void SettingFieldString::set(const String & x) -{ - value = x; - changed = true; -} +template struct SettingFieldTimespan; +template struct SettingFieldTimespan; -void SettingFieldString::set(const Field & x) -{ - set(safeGet(x)); -} void SettingFieldString::writeBinary(WriteBuffer & out) const { @@ -261,40 +227,42 @@ void SettingFieldString::writeBinary(WriteBuffer & out) const void SettingFieldString::readBinary(ReadBuffer & in) { - String s; - readStringBinary(s, in); - set(s); + String str; + readStringBinary(str, in); + *this = std::move(str); } -String SettingFieldChar::toString() const +namespace { - return String(1, value); -} + char stringToChar(const String & str) + { + if (str.size() > 1) + throw Exception("A setting's value string has to be an exactly one character long", ErrorCodes::SIZE_OF_FIXED_STRING_DOESNT_MATCH); + if (str.empty()) + return '\0'; + return str[0]; + } -Field SettingFieldChar::toField() const -{ - return toString(); + char fieldToChar(const Field & f) + { + return stringToChar(f.safeGet()); + } } -void SettingFieldChar::set(char x) +SettingFieldChar::SettingFieldChar(const Field & f) : SettingFieldChar(fieldToChar(f)) { - value = x; - changed = true; } -void SettingFieldChar::set(const String & x) +SettingFieldChar & SettingFieldChar::operator =(const Field & f) { - if (x.size() > 1) - throw Exception("A setting's value string has to be an exactly one character long", ErrorCodes::SIZE_OF_FIXED_STRING_DOESNT_MATCH); - char c = (x.size() == 1) ? x[0] : '\0'; - set(c); + *this = fieldToChar(f); + return *this; } -void SettingFieldChar::set(const Field & x) +void SettingFieldChar::parseFromString(const String & str) { - const String & s = safeGet(x); - set(s); + *this = stringToChar(str); } void SettingFieldChar::writeBinary(WriteBuffer & out) const @@ -304,49 +272,22 @@ void SettingFieldChar::writeBinary(WriteBuffer & out) const void SettingFieldChar::readBinary(ReadBuffer & in) { - String s; - readStringBinary(s, in); - set(s); -} - - -String SettingFieldURI::toString() const -{ - return value.toString(); -} - -Field SettingFieldURI::toField() const -{ - return value.toString(); -} - -void SettingFieldURI::set(const Poco::URI & x) -{ - value = x; - changed = true; + String str; + readStringBinary(str, in); + *this = stringToChar(str); } -void SettingFieldURI::set(const Field & x) -{ - const String & s = safeGet(x); - set(s); -} -void SettingFieldURI::set(const String & x) +void SettingFieldURI::writeBinary(WriteBuffer & out) const { - set(Poco::URI(x)); + writeStringBinary(value.toString(), out); } -void SettingFieldURI::writeBinary(WriteBuffer & buf) const +void SettingFieldURI::readBinary(ReadBuffer & in) { - writeStringBinary(toString(), buf); -} - -void SettingFieldURI::readBinary(ReadBuffer & buf) -{ - String s; - readStringBinary(s, buf); - set(s); + String str; + readStringBinary(str, in); + *this = Poco::URI{str}; } diff --git a/src/Core/SettingsFields.h b/src/Core/SettingsFields.h index a972180eaee894c6beaf69a3213a6a5d21e27420..f6e03ab9dde539b3a8fcf2ffc06637a0ba993dcf 100644 --- a/src/Core/SettingsFields.h +++ b/src/Core/SettingsFields.h @@ -27,32 +27,26 @@ class WriteBuffer; * and the remote server will use its default value. */ -template +template struct SettingFieldNumber { + using Type = T; + Type value; bool changed = false; - SettingFieldNumber(Type x = 0) : value(x) {} + explicit SettingFieldNumber(Type x = 0) : value(x) {} + explicit SettingFieldNumber(const Field & f); + + SettingFieldNumber & operator=(Type x) { value = x; changed = true; return *this; } + SettingFieldNumber & operator=(const Field & f); operator Type() const { return value; } - SettingFieldNumber & operator=(Type x) { set(x); return *this; } + explicit operator Field() const { return value; } - /// Serialize to a test string. String toString() const; + void parseFromString(const String & str); - /// Converts to a field. - Field toField() const; - - void set(Type x); - - /// Read from SQL literal. - void set(const Field & x); - - /// Read from text string. - void set(const String & x); - - /// Serialize to binary stream. void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); }; @@ -69,72 +63,80 @@ using SettingFieldBool = SettingFieldNumber; */ struct SettingFieldMaxThreads { - UInt64 value; bool is_auto; + UInt64 value; bool changed = false; - SettingFieldMaxThreads(UInt64 x = 0) : value(x ? x : getAutoValue()), is_auto(x == 0) {} + explicit SettingFieldMaxThreads(UInt64 x = 0) : is_auto(!x), value(is_auto ? getAuto() : x) {} + explicit SettingFieldMaxThreads(const Field & f); + + SettingFieldMaxThreads & operator=(UInt64 x) { is_auto = !x; value = is_auto ? getAuto() : x; changed = true; return *this; } + SettingFieldMaxThreads & operator=(const Field & f); operator UInt64() const { return value; } - SettingFieldMaxThreads & operator=(UInt64 x) { set(x); return *this; } + explicit operator Field() const { return value; } + /// Writes "auto()" instead of simple "" if `is_auto==true`. String toString() const; - Field toField() const; - - void set(UInt64 x); - void set(const Field & x); - void set(const String & x); - - void setAuto(); - static UInt64 getAutoValue(); + void parseFromString(const String & str); void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); + +private: + static UInt64 getAuto(); }; -enum class SettingFieldTimespanUnit { MILLISECOND, SECOND }; +enum class SettingFieldTimespanUnit { Millisecond, Second }; -template +template struct SettingFieldTimespan { - static constexpr UInt64 microseconds_per_unit = (unit == SettingFieldTimespanUnit::MILLISECOND) ? 1000 : 1000000; - + using Unit = SettingFieldTimespanUnit; + static constexpr Unit unit = unit_; + static constexpr UInt64 microseconds_per_unit = (unit == SettingFieldTimespanUnit::Millisecond) ? 1000 : 1000000; Poco::Timespan value; bool changed = false; - SettingFieldTimespan(UInt64 x = 0) : value(x * microseconds_per_unit) {} + explicit SettingFieldTimespan(const Poco::Timespan & x = {}) : value(x) {} + + template > + explicit SettingFieldTimespan(const std::chrono::duration & x) + : SettingFieldTimespan(Poco::Timespan{static_cast(std::chrono::duration_cast(x).count())}) {} + + explicit SettingFieldTimespan(UInt64 x) : SettingFieldTimespan(Poco::Timespan{static_cast(x * microseconds_per_unit)}) {} + explicit SettingFieldTimespan(const Field & f); + + SettingFieldTimespan & operator =(const Poco::Timespan & x) { value = x; changed = true; return *this; } + + template > + SettingFieldTimespan & operator =(const std::chrono::duration & x) { *this = Poco::Timespan{static_cast(std::chrono::duration_cast(x).count())}; return *this; } + + SettingFieldTimespan & operator =(UInt64 x) { *this = Poco::Timespan{static_cast(x * microseconds_per_unit)}; return *this; } + SettingFieldTimespan & operator =(const Field & f); operator Poco::Timespan() const { return value; } - SettingFieldTimespan & operator=(const Poco::Timespan & x) { set(x); return *this; } template > operator std::chrono::duration() const { return std::chrono::duration_cast>(std::chrono::microseconds(value.totalMicroseconds())); } - template > - SettingFieldTimespan & operator=(const std::chrono::duration & x) { set(x); return *this; } + explicit operator UInt64() const { return value.totalMicroseconds() / microseconds_per_unit; } + explicit operator Field() const { return operator UInt64(); } - Poco::Timespan::TimeDiff totalSeconds() const { return value.totalSeconds(); } + Poco::Timespan::TimeDiff totalMicroseconds() const { return value.totalMicroseconds(); } Poco::Timespan::TimeDiff totalMilliseconds() const { return value.totalMilliseconds(); } + Poco::Timespan::TimeDiff totalSeconds() const { return value.totalSeconds(); } String toString() const; - Field toField() const; - - void set(const Poco::Timespan & x); - - template > - void set(const std::chrono::duration & duration) { set(static_cast(std::chrono::duration_cast(duration).count())); } - - void set(UInt64 x); - void set(const Field & x); - void set(const String & x); + void parseFromString(const String & str); void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); }; -using SettingFieldSeconds = SettingFieldTimespan; -using SettingFieldMilliseconds = SettingFieldTimespan; +using SettingFieldSeconds = SettingFieldTimespan; +using SettingFieldMilliseconds = SettingFieldTimespan; struct SettingFieldString @@ -142,16 +144,23 @@ struct SettingFieldString String value; bool changed = false; - SettingFieldString(const String & x = String{}) : value(x) {} + explicit SettingFieldString(const std::string_view & str = {}) : value(str) {} + explicit SettingFieldString(const String & str) : SettingFieldString(std::string_view{str}) {} + explicit SettingFieldString(String && str) : value(std::move(str)) {} + explicit SettingFieldString(const char * str) : SettingFieldString(std::string_view{str}) {} + explicit SettingFieldString(const Field & f) : SettingFieldString(f.safeGet()) {} - operator String() const { return value; } - SettingFieldString & operator=(const String & x) { set(x); return *this; } + SettingFieldString & operator =(const std::string_view & str) { value = str; changed = true; return *this; } + SettingFieldString & operator =(const String & str) { *this = std::string_view{str}; return *this; } + SettingFieldString & operator =(String && str) { value = std::move(str); changed = true; return *this; } + SettingFieldString & operator =(const char * str) { *this = std::string_view{str}; return *this; } + SettingFieldString & operator =(const Field & f) { *this = f.safeGet(); return *this; } - const String & toString() const { return value; } - Field toField() const; + operator const String &() const { return value; } + explicit operator Field() const { return value; } - void set(const String & x); - void set(const Field & x); + const String & toString() const { return value; } + void parseFromString(const String & str) { *this = str; } void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); @@ -163,17 +172,18 @@ struct SettingFieldChar public: char value; bool changed = false; - SettingFieldChar(char x = '\0') : value(x) {} - operator char() const { return value; } - SettingFieldChar & operator=(char x) { set(x); return *this; } + explicit SettingFieldChar(char c = '\0') : value(c) {} + explicit SettingFieldChar(const Field & f); - String toString() const; - Field toField() const; + SettingFieldChar & operator =(char c) { value = c; changed = true; return *this; } + SettingFieldChar & operator =(const Field & f); + + operator char() const { return value; } + explicit operator Field() const { return toString(); } - void set(char x); - void set(const String & x); - void set(const Field & x); + String toString() const { return String(&value, 1); } + void parseFromString(const String & str); void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); @@ -185,17 +195,22 @@ struct SettingFieldURI Poco::URI value; bool changed = false; - SettingFieldURI(const Poco::URI & x = Poco::URI{}) : value(x) {} + explicit SettingFieldURI(const Poco::URI & uri = {}) : value(uri) {} + explicit SettingFieldURI(const String & str) : SettingFieldURI(Poco::URI{str}) {} + explicit SettingFieldURI(const char * str) : SettingFieldURI(Poco::URI{str}) {} + explicit SettingFieldURI(const Field & f) : SettingFieldURI(f.safeGet()) {} - operator Poco::URI() const { return value; } - SettingFieldURI & operator=(const Poco::URI & x) { set(x); return *this; } + SettingFieldURI & operator =(const Poco::URI & x) { value = x; changed = true; return *this; } + SettingFieldURI & operator =(const String & str) { *this = Poco::URI{str}; return *this; } + SettingFieldURI & operator =(const char * str) { *this = Poco::URI{str}; return *this; } + SettingFieldURI & operator =(const Field & f) { *this = f.safeGet(); return *this; } - String toString() const; - Field toField() const; + operator const Poco::URI &() const { return value; } + explicit operator String() const { return toString(); } + explicit operator Field() const { return toString(); } - void set(const Poco::URI & x); - void set(const Field & x); - void set(const String & x); + String toString() const { return value.toString(); } + void parseFromString(const String & str) { *this = str; } void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); @@ -213,23 +228,25 @@ struct SettingFieldURI * IMPLEMENT_SETTING_ENUM(SettingFieldGender, ErrorCodes::BAD_ARGUMENTS, * {{"Male", Gender::Male}, {"Female", Gender::Female}}) */ -template +template struct SettingFieldEnum { + using EnumType = EnumT; + EnumType value; bool changed = false; - SettingFieldEnum(EnumType x) : value(x) {} + explicit SettingFieldEnum(EnumType x = EnumType{0}) : value(x) {} + explicit SettingFieldEnum(const Field & f) : SettingFieldEnum(Traits::fromString(f.safeGet())) {} - operator EnumType() const { return value; } - SettingFieldEnum & operator=(EnumType x) { set(x); return *this; } + SettingFieldEnum & operator =(EnumType x) { value = x; changed = true; return *this; } + SettingFieldEnum & operator =(const Field & f) { *this = Traits::fromString(f.safeGet()); return *this; } - const String & toString() const { return NameValueConverter::toString(value); } - Field toField() const { return toString(); } + operator EnumType() const { return value; } + explicit operator Field() const { return toString(); } - void set(EnumType x) { value = x; changed = true; } - void set(const Field & x) { set(safeGet(x)); } - void set(const String & x) { set(NameValueConverter::fromString(x)); } + String toString() const { return Traits::toString(value); } + void parseFromString(const String & str) { *this = Traits::fromString(str); } void writeBinary(WriteBuffer & out) const; void readBinary(ReadBuffer & in); @@ -241,16 +258,16 @@ struct SettingFieldEnumHelpers static String readBinary(ReadBuffer & in); }; -template -inline void SettingFieldEnum::writeBinary(WriteBuffer & out) const +template +void SettingFieldEnum::writeBinary(WriteBuffer & out) const { SettingFieldEnumHelpers::writeBinary(toString(), out); } -template -inline void SettingFieldEnum::readBinary(ReadBuffer & in) +template +void SettingFieldEnum::readBinary(ReadBuffer & in) { - set(SettingFieldEnumHelpers::readBinary(in)); + *this = Traits::fromString(SettingFieldEnumHelpers::readBinary(in)); } #define DECLARE_SETTING_ENUM(ENUM_TYPE) \ @@ -260,17 +277,17 @@ inline void SettingFieldEnum::readBinary(ReadBuffe IMPLEMENT_SETTING_ENUM_WITH_RENAME(ENUM_TYPE, ERROR_CODE_FOR_UNEXPECTED_NAME, __VA_ARGS__) #define DECLARE_SETTING_ENUM_WITH_RENAME(NEW_NAME, ENUM_TYPE) \ - struct SettingField##NEW_NAME##NameValueConverter \ + struct SettingField##NEW_NAME##Traits \ { \ using EnumType = ENUM_TYPE; \ static const String & toString(EnumType value); \ static EnumType fromString(const std::string_view & str); \ }; \ \ - using SettingField##NEW_NAME = SettingFieldEnum; + using SettingField##NEW_NAME = SettingFieldEnum; #define IMPLEMENT_SETTING_ENUM_WITH_RENAME(NEW_NAME, ERROR_CODE_FOR_UNEXPECTED_NAME, ...) \ - const String & SettingField##NEW_NAME##NameValueConverter::toString(typename SettingField##NEW_NAME##NameValueConverter::EnumType value) \ + const String & SettingField##NEW_NAME##Traits::toString(typename SettingField##NEW_NAME::EnumType value) \ { \ static const std::unordered_map map = [] { \ std::unordered_map res; \ @@ -287,7 +304,7 @@ inline void SettingFieldEnum::readBinary(ReadBuffe ERROR_CODE_FOR_UNEXPECTED_NAME); \ } \ \ - typename SettingField##NEW_NAME##NameValueConverter::EnumType SettingField##NEW_NAME##NameValueConverter::fromString(const std::string_view & str) \ + typename SettingField##NEW_NAME::EnumType SettingField##NEW_NAME##Traits::fromString(const std::string_view & str) \ { \ static const std::unordered_map map = [] { \ std::unordered_map res; \ diff --git a/src/IO/ReadHelpers.h b/src/IO/ReadHelpers.h index f299ab2286f8ac392ab1e807215876ebee684687..d11bd1d8706a2375cf782c341e8d834481dbc356 100644 --- a/src/IO/ReadHelpers.h +++ b/src/IO/ReadHelpers.h @@ -638,7 +638,7 @@ template inline T parse(const char * data, size_t size); template -inline T parseFromString(const String & str) +inline T parseFromString(const std::string_view & str) { return parse(str.data(), str.size()); } @@ -1096,7 +1096,7 @@ inline T parseWithSizeSuffix(const char * data, size_t size) } template -inline T parseWithSizeSuffix(const String & s) +inline T parseWithSizeSuffix(const std::string_view & s) { return parseWithSizeSuffix(s.data(), s.size()); } diff --git a/src/Storages/Kafka/StorageKafka.cpp b/src/Storages/Kafka/StorageKafka.cpp index c0f7ef8e44d5f09a0de70e420b5a10de77d3da0a..9d7bc273cd2e078db5617bebd2ab0c49fd9c70c8 100644 --- a/src/Storages/Kafka/StorageKafka.cpp +++ b/src/Storages/Kafka/StorageKafka.cpp @@ -173,7 +173,7 @@ SettingsChanges StorageKafka::createSettingsAdjustments() { if (it.isChanged() && it.getName().toString().rfind("kafka_",0) == std::string::npos) { - result.emplace_back(it.getName().toString(), it.getValueAsString()); + result.emplace_back(it.getName().toString(), it.getValue()); } } return result; @@ -632,8 +632,8 @@ void registerStorageKafka(StorageFactory & factory) engine_args[(ARG_NUM)-1], \ args.local_context); \ } \ - kafka_settings->PAR_NAME.set( \ - engine_args[(ARG_NUM)-1]->as().value);\ + kafka_settings->PAR_NAME = \ + engine_args[(ARG_NUM)-1]->as().value; \ } \ } diff --git a/src/Storages/StorageJoin.cpp b/src/Storages/StorageJoin.cpp index af1a8bf10d73fbf855d64ef282ae7ca274ac278f..74097278026bc4ef9e40a7aa87e35a52fe054263 100644 --- a/src/Storages/StorageJoin.cpp +++ b/src/Storages/StorageJoin.cpp @@ -124,17 +124,17 @@ void registerStorageJoin(StorageFactory & factory) for (const auto & setting : args.storage_def->settings->changes) { if (setting.name == "join_use_nulls") - join_use_nulls.set(setting.value); + join_use_nulls = setting.value; else if (setting.name == "max_rows_in_join") - max_rows_in_join.set(setting.value); + max_rows_in_join = setting.value; else if (setting.name == "max_bytes_in_join") - max_bytes_in_join.set(setting.value); + max_bytes_in_join = setting.value; else if (setting.name == "join_overflow_mode") - join_overflow_mode.set(setting.value); + join_overflow_mode = setting.value; else if (setting.name == "join_any_take_last_row") - join_any_take_last_row.set(setting.value); + join_any_take_last_row = setting.value; else if (setting.name == "any_join_distinct_right_table_keys") - old_any_join.set(setting.value); + old_any_join = setting.value; else throw Exception( "Unknown setting " + setting.name + " for storage " + args.engine_name,