Rework the StringField* classes and make conversion String => StringField* explicit.

This commit is contained in:
Vitaly Baranov 2020-07-27 17:26:18 +03:00
parent 18e3f1f60d
commit 300727afa3
11 changed files with 328 additions and 363 deletions

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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));
}

View File

@ -433,7 +433,7 @@ struct Settings : public SettingsCollection<Settings>
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) \
\

View File

@ -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<Derived>::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<Derived *>(this->collection), value); }
void setValue(const String & value) { this->member->set_string(*const_cast<Derived *>(this->collection), value); }
void setValue(const Field & value) { this->member->set_value(*const_cast<Derived *>(this->collection), value); }
void parseFromString(const String & value) { this->member->parse_value_from_string(*const_cast<Derived *>(this->collection), value); }
};
/// Iterator to iterating through all the settings.
@ -178,14 +180,16 @@ 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 string according to a specified setting without actual changing this settings.
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);
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); }
iterator begin() { return iterator(castToDerived(), members().data()); }
const_iterator begin() const { return const_iterator(castToDerived(), members().data()); }

View File

@ -6,8 +6,10 @@
* instantiation of SettingsCollection<>.
*/
#include <Core/SettingsCollection.h>
#include <Common/SettingsChanges.h>
#include <Common/FieldVisitors.h>
#include <common/StringRef.h>
namespace DB
@ -86,16 +88,16 @@ SettingsCollection<Derived>::members()
template <class Derived>
Field SettingsCollection<Derived>::const_reference::getValue() const
{
return member->get_field(*collection);
return member->get_value(*collection);
}
template <class Derived>
Field SettingsCollection<Derived>::valueToCorrespondingType(size_t index, const Field & value)
Field SettingsCollection<Derived>::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<Derived>::valueToCorrespondingType(size_t index, const
template <class Derived>
Field SettingsCollection<Derived>::valueToCorrespondingType(const StringRef & name, const Field & value)
Field SettingsCollection<Derived>::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<Derived>::operator ==(const SettingsCollection<Derived>
{
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<Derived>::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<Derived>::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<Derived>::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<Derived>::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<Derived>::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<Field>(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<Field>(SettingField##TYPE{value}); } \
static Field NAME##_stringToValue(const String & str) { SettingField##TYPE temp; temp.parseFromString(str); return static_cast<Field>(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<Derived>::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 });
}

View File

@ -7,6 +7,7 @@
#include <IO/ReadHelpers.h>
#include <IO/ReadBufferFromString.h>
#include <IO/WriteHelpers.h>
#include <boost/algorithm/string/predicate.hpp>
namespace DB
@ -18,100 +19,96 @@ namespace ErrorCodes
}
template <typename Type>
String SettingFieldNumber<Type>::toString() const
namespace
{
return DB::toString(value);
}
template <typename Type>
Field SettingFieldNumber<Type>::toField() const
{
return value;
}
template <typename Type>
void SettingFieldNumber<Type>::set(Type x)
{
value = x;
changed = true;
}
template <typename Type>
void SettingFieldNumber<Type>::set(const Field & x)
{
if (x.getType() == Field::Types::String)
set(get<const String &>(x));
else
set(applyVisitor(FieldVisitorConvertToNumber<Type>(), x));
}
template <typename Type>
void SettingFieldNumber<Type>::set(const String & x)
{
set(parseWithSizeSuffix<Type>(x));
}
template <>
void SettingFieldNumber<bool>::set(const String & x)
{
if (x.size() == 1)
template <typename T>
T stringToNumber(const String & str)
{
if (x[0] == '0')
set(false);
else if (x[0] == '1')
set(true);
if constexpr (std::is_same_v<T, bool>)
{
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
throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL);
return parseWithSizeSuffix<T>(str);
}
else
template <typename T>
T fieldToNumber(const Field & f)
{
ReadBufferFromString buf(x);
if (checkStringCaseInsensitive("true", buf))
set(true);
else if (checkStringCaseInsensitive("false", buf))
set(false);
if (f.getType() == Field::Types::String)
return stringToNumber<T>(f.get<const String &>());
else
throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL);
return applyVisitor(FieldVisitorConvertToNumber<T>(), f);
}
}
template <typename Type>
void SettingFieldNumber<Type>::writeBinary(WriteBuffer & out) const
template <typename T>
SettingFieldNumber<T>::SettingFieldNumber(const Field & f) : SettingFieldNumber(fieldToNumber<T>(f))
{
if constexpr (is_integral_v<Type> && is_unsigned_v<Type>)
}
template <typename T>
SettingFieldNumber<T> & SettingFieldNumber<T>::operator=(const Field & f)
{
*this = fieldToNumber<T>(f);
return *this;
}
template <typename T>
String SettingFieldNumber<T>::toString() const
{
return ::DB::toString(value);
}
template <typename T>
void SettingFieldNumber<T>::parseFromString(const String & str)
{
*this = stringToNumber<T>(str);
}
template <typename T>
void SettingFieldNumber<T>::writeBinary(WriteBuffer & out) const
{
if constexpr (is_integral_v<T> && is_unsigned_v<T>)
writeVarUInt(static_cast<UInt64>(value), out);
else if constexpr (is_integral_v<Type> && is_signed_v<Type>)
else if constexpr (is_integral_v<T> && is_signed_v<T>)
writeVarInt(static_cast<Int64>(value), out);
else
{
static_assert(std::is_floating_point_v<Type>);
writeStringBinary(toString(), out);
static_assert(std::is_floating_point_v<T>);
writeStringBinary(::DB::toString(value), out);
}
}
template <typename Type>
void SettingFieldNumber<Type>::readBinary(ReadBuffer & in)
template <typename T>
void SettingFieldNumber<T>::readBinary(ReadBuffer & in)
{
if constexpr (is_integral_v<Type> && is_unsigned_v<Type>)
if constexpr (is_integral_v<T> && is_unsigned_v<T>)
{
UInt64 x;
readVarUInt(x, in);
set(static_cast<Type>(x));
*this = static_cast<T>(x);
}
else if constexpr (is_integral_v<Type> && is_signed_v<Type>)
else if constexpr (is_integral_v<T> && is_signed_v<T>)
{
Int64 x;
readVarInt(x, in);
set(static_cast<Type>(x));
*this = static_cast<T>(value);
}
else
{
static_assert(std::is_floating_point_v<Type>);
String x;
readStringBinary(x, in);
set(x);
static_assert(std::is_floating_point_v<T>);
String str;
readStringBinary(str, in);
*this = ::DB::parseFromString<T>(str);
}
}
@ -121,50 +118,45 @@ template struct SettingFieldNumber<float>;
template struct SettingFieldNumber<bool>;
namespace
{
UInt64 stringToMaxThreads(const String & str)
{
if (startsWith(str, "auto"))
return 0;
return parseFromString<UInt64>(str);
}
UInt64 fieldToMaxThreads(const Field & f)
{
if (f.getType() == Field::Types::String)
return stringToMaxThreads(f.get<const String &>());
else
return applyVisitor(FieldVisitorConvertToNumber<UInt64>(), f);
}
}
SettingFieldMaxThreads::SettingFieldMaxThreads(const Field & f) : SettingFieldMaxThreads(fieldToMaxThreads(f))
{
}
SettingFieldMaxThreads & SettingFieldMaxThreads::operator=(const Field & f)
{
*this = fieldToMaxThreads(f);
return *this;
}
String SettingFieldMaxThreads::toString() const
{
/// 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);
}
Field SettingFieldMaxThreads::toField() const
{
return is_auto ? 0 : value;
}
void SettingFieldMaxThreads::set(UInt64 x)
{
value = x ? x : getAutoValue();
is_auto = x == 0;
changed = true;
}
void SettingFieldMaxThreads::set(const Field & x)
{
if (x.getType() == Field::Types::String)
set(get<const String &>(x));
if (is_auto)
return "'auto(" + ::DB::toString(value) + ")'";
else
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), x));
return ::DB::toString(value);
}
void SettingFieldMaxThreads::set(const String & x)
void SettingFieldMaxThreads::parseFromString(const String & str)
{
if (startsWith(x, "auto"))
setAuto();
else
set(parse<UInt64>(x));
}
void SettingFieldMaxThreads::setAuto()
{
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 <SettingFieldTimespanUnit unit>
String SettingFieldTimespan<unit>::toString() const
UInt64 SettingFieldMaxThreads::getAuto()
{
return DB::toString(value.totalMicroseconds() / microseconds_per_unit);
return getNumberOfPhysicalCPUCores();
}
template <SettingFieldTimespanUnit unit>
Field SettingFieldTimespan<unit>::toField() const
template <SettingFieldTimespanUnit unit_>
SettingFieldTimespan<unit_>::SettingFieldTimespan(const Field & f) : SettingFieldTimespan(fieldToNumber<UInt64>(f))
{
return value.totalMicroseconds() / microseconds_per_unit;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const Poco::Timespan & x)
template <SettingFieldTimespanUnit unit_>
SettingFieldTimespan<unit_> & SettingFieldTimespan<unit_>::operator=(const Field & f)
{
value = x;
changed = true;
*this = fieldToNumber<UInt64>(f);
return *this;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(UInt64 x)
template <SettingFieldTimespanUnit unit_>
String SettingFieldTimespan<unit_>::toString() const
{
set(Poco::Timespan(x * microseconds_per_unit));
return ::DB::toString(operator UInt64());
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const Field & x)
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::parseFromString(const String & str)
{
if (x.getType() == Field::Types::String)
set(get<const String &>(x));
else
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), x));
*this = stringToNumber<UInt64>(str);
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const String & x)
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::writeBinary(WriteBuffer & out) const
{
set(parse<UInt64>(x));
auto num_units = operator UInt64();
writeVarUInt(num_units, out);
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::writeBinary(WriteBuffer & out) const
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::readBinary(ReadBuffer & in)
{
writeVarUInt(value.totalMicroseconds() / microseconds_per_unit, out);
UInt64 num_units = 0;
readVarUInt(num_units, in);
*this = num_units;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::readBinary(ReadBuffer & in)
{
UInt64 x = 0;
readVarUInt(x, in);
set(x);
}
template struct SettingFieldTimespan<SettingFieldTimespanUnit::Second>;
template struct SettingFieldTimespan<SettingFieldTimespanUnit::Millisecond>;
template struct SettingFieldTimespan<SettingFieldTimespanUnit::SECOND>;
template struct SettingFieldTimespan<SettingFieldTimespanUnit::MILLISECOND>;
Field SettingFieldString::toField() const
{
return value;
}
void SettingFieldString::set(const String & x)
{
value = x;
changed = true;
}
void SettingFieldString::set(const Field & x)
{
set(safeGet<const String &>(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];
}
char fieldToChar(const Field & f)
{
return stringToChar(f.safeGet<const String &>());
}
}
Field SettingFieldChar::toField() const
SettingFieldChar::SettingFieldChar(const Field & f) : SettingFieldChar(fieldToChar(f))
{
return toString();
}
void SettingFieldChar::set(char x)
SettingFieldChar & SettingFieldChar::operator =(const Field & f)
{
value = x;
changed = true;
*this = fieldToChar(f);
return *this;
}
void SettingFieldChar::set(const String & x)
void SettingFieldChar::parseFromString(const String & str)
{
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);
}
void SettingFieldChar::set(const Field & x)
{
const String & s = safeGet<const String &>(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 str;
readStringBinary(str, in);
*this = stringToChar(str);
}
String SettingFieldURI::toString() const
void SettingFieldURI::writeBinary(WriteBuffer & out) const
{
return value.toString();
writeStringBinary(value.toString(), out);
}
Field SettingFieldURI::toField() const
void SettingFieldURI::readBinary(ReadBuffer & in)
{
return value.toString();
}
void SettingFieldURI::set(const Poco::URI & x)
{
value = x;
changed = true;
}
void SettingFieldURI::set(const Field & x)
{
const String & s = safeGet<const String &>(x);
set(s);
}
void SettingFieldURI::set(const String & x)
{
set(Poco::URI(x));
}
void SettingFieldURI::writeBinary(WriteBuffer & buf) const
{
writeStringBinary(toString(), buf);
}
void SettingFieldURI::readBinary(ReadBuffer & buf)
{
String s;
readStringBinary(s, buf);
set(s);
String str;
readStringBinary(str, in);
*this = Poco::URI{str};
}

View File

@ -27,32 +27,26 @@ class WriteBuffer;
* and the remote server will use its default value.
*/
template <typename Type>
template <typename T>
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<bool>;
*/
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(<number>)" instead of simple "<number>" 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 <SettingFieldTimespanUnit unit>
template <SettingFieldTimespanUnit unit_>
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 <class Rep, class Period = std::ratio<1>>
explicit SettingFieldTimespan(const std::chrono::duration<Rep, Period> & x)
: SettingFieldTimespan(Poco::Timespan{static_cast<Poco::Timespan::TimeDiff>(std::chrono::duration_cast<std::chrono::microseconds>(x).count())}) {}
explicit SettingFieldTimespan(UInt64 x) : SettingFieldTimespan(Poco::Timespan{static_cast<Poco::Timespan::TimeDiff>(x * microseconds_per_unit)}) {}
explicit SettingFieldTimespan(const Field & f);
SettingFieldTimespan & operator =(const Poco::Timespan & x) { value = x; changed = true; return *this; }
template <class Rep, class Period = std::ratio<1>>
SettingFieldTimespan & operator =(const std::chrono::duration<Rep, Period> & x) { *this = Poco::Timespan{static_cast<Poco::Timespan::TimeDiff>(std::chrono::duration_cast<std::chrono::microseconds>(x).count())}; return *this; }
SettingFieldTimespan & operator =(UInt64 x) { *this = Poco::Timespan{static_cast<Poco::Timespan::TimeDiff>(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 <class Rep, class Period = std::ratio<1>>
operator std::chrono::duration<Rep, Period>() const { return std::chrono::duration_cast<std::chrono::duration<Rep, Period>>(std::chrono::microseconds(value.totalMicroseconds())); }
template <class Rep, class Period = std::ratio<1>>
SettingFieldTimespan & operator=(const std::chrono::duration<Rep, Period> & 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 <class Rep, class Period = std::ratio<1>>
void set(const std::chrono::duration<Rep, Period> & duration) { set(static_cast<UInt64>(std::chrono::duration_cast<std::chrono::microseconds>(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<SettingFieldTimespanUnit::SECOND>;
using SettingFieldMilliseconds = SettingFieldTimespan<SettingFieldTimespanUnit::MILLISECOND>;
using SettingFieldSeconds = SettingFieldTimespan<SettingFieldTimespanUnit::Second>;
using SettingFieldMilliseconds = SettingFieldTimespan<SettingFieldTimespanUnit::Millisecond>;
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<const String &>()) {}
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<const String &>(); return *this; }
operator const String &() const { return value; }
explicit operator Field() const { return value; }
const String & toString() const { return value; }
Field toField() const;
void set(const String & x);
void set(const Field & x);
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) {}
explicit SettingFieldChar(char c = '\0') : value(c) {}
explicit SettingFieldChar(const Field & f);
SettingFieldChar & operator =(char c) { value = c; changed = true; return *this; }
SettingFieldChar & operator =(const Field & f);
operator char() const { return value; }
SettingFieldChar & operator=(char x) { set(x); return *this; }
explicit operator Field() const { return toString(); }
String toString() const;
Field toField() const;
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<String>()) {}
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<const String &>(); 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 <typename EnumType, typename NameValueConverter>
template <typename EnumT, typename Traits>
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<const String &>())) {}
SettingFieldEnum & operator =(EnumType x) { value = x; changed = true; return *this; }
SettingFieldEnum & operator =(const Field & f) { *this = Traits::fromString(f.safeGet<const String &>()); return *this; }
operator EnumType() const { return value; }
SettingFieldEnum & operator=(EnumType x) { set(x); return *this; }
explicit operator Field() const { return toString(); }
const String & toString() const { return NameValueConverter::toString(value); }
Field toField() const { return toString(); }
void set(EnumType x) { value = x; changed = true; }
void set(const Field & x) { set(safeGet<const String &>(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 <typename EnumType, typename NameValueConverter>
inline void SettingFieldEnum<EnumType, NameValueConverter>::writeBinary(WriteBuffer & out) const
template <typename EnumT, typename Traits>
void SettingFieldEnum<EnumT, Traits>::writeBinary(WriteBuffer & out) const
{
SettingFieldEnumHelpers::writeBinary(toString(), out);
}
template <typename EnumType, typename NameValueConverter>
inline void SettingFieldEnum<EnumType, NameValueConverter>::readBinary(ReadBuffer & in)
template <typename EnumT, typename Traits>
void SettingFieldEnum<EnumT, Traits>::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<EnumType, NameValueConverter>::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<ENUM_TYPE, SettingField##NEW_NAME##NameValueConverter>;
using SettingField##NEW_NAME = SettingFieldEnum<ENUM_TYPE, SettingField##NEW_NAME##Traits>;
#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<EnumType, String> map = [] { \
std::unordered_map<EnumType, String> res; \
@ -287,7 +304,7 @@ inline void SettingFieldEnum<EnumType, NameValueConverter>::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<std::string_view, EnumType> map = [] { \
std::unordered_map<std::string_view, EnumType> res; \

View File

@ -638,7 +638,7 @@ template <typename T>
inline T parse(const char * data, size_t size);
template <typename T>
inline T parseFromString(const String & str)
inline T parseFromString(const std::string_view & str)
{
return parse<T>(str.data(), str.size());
}
@ -1096,7 +1096,7 @@ inline T parseWithSizeSuffix(const char * data, size_t size)
}
template <typename T>
inline T parseWithSizeSuffix(const String & s)
inline T parseWithSizeSuffix(const std::string_view & s)
{
return parseWithSizeSuffix<T>(s.data(), s.size());
}

View File

@ -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<ASTLiteral &>().value);\
kafka_settings->PAR_NAME = \
engine_args[(ARG_NUM)-1]->as<ASTLiteral &>().value; \
} \
}

View File

@ -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,