提交 300727af 编写于 作者: V Vitaly Baranov

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

上级 18e3f1f6
......@@ -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.
......
......@@ -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);
}
}
......
......@@ -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));
}
......
......@@ -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) \
\
......
......@@ -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,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()); }
......
......@@ -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 });
}
......@@ -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 T>
T stringToNumber(const String & str)
{
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
return parseWithSizeSuffix<T>(str);
}
template <typename Type>
Field SettingFieldNumber<Type>::toField() const
{
return value;
template <typename T>
T fieldToNumber(const Field & f)
{
if (f.getType() == Field::Types::String)
return stringToNumber<T>(f.get<const String &>());
else
return applyVisitor(FieldVisitorConvertToNumber<T>(), f);
}
}
template <typename Type>
void SettingFieldNumber<Type>::set(Type x)
template <typename T>
SettingFieldNumber<T>::SettingFieldNumber(const Field & f) : SettingFieldNumber(fieldToNumber<T>(f))
{
value = x;
changed = true;
}
template <typename Type>
void SettingFieldNumber<Type>::set(const Field & x)
template <typename T>
SettingFieldNumber<T> & SettingFieldNumber<T>::operator=(const Field & f)
{
if (x.getType() == Field::Types::String)
set(get<const String &>(x));
else
set(applyVisitor(FieldVisitorConvertToNumber<Type>(), x));
*this = fieldToNumber<T>(f);
return *this;
}
template <typename Type>
void SettingFieldNumber<Type>::set(const String & x)
template <typename T>
String SettingFieldNumber<T>::toString() const
{
set(parseWithSizeSuffix<Type>(x));
return ::DB::toString(value);
}
template <>
void SettingFieldNumber<bool>::set(const String & x)
template <typename T>
void SettingFieldNumber<T>::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<T>(str);
}
template <typename Type>
void SettingFieldNumber<Type>::writeBinary(WriteBuffer & out) const
template <typename T>
void SettingFieldNumber<T>::writeBinary(WriteBuffer & out) const
{
if constexpr (is_integral_v<Type> && is_unsigned_v<Type>)
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>;
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<UInt64>(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<const String &>());
else
return applyVisitor(FieldVisitorConvertToNumber<UInt64>(), 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<const String &>(x));
else
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), 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<UInt64>(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 <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
{
return value.totalMicroseconds() / microseconds_per_unit;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const Poco::Timespan & x)
{
value = x;
changed = true;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(UInt64 x)
template <SettingFieldTimespanUnit unit_>
SettingFieldTimespan<unit_>::SettingFieldTimespan(const Field & f) : SettingFieldTimespan(fieldToNumber<UInt64>(f))
{
set(Poco::Timespan(x * microseconds_per_unit));
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const Field & x)
template <SettingFieldTimespanUnit unit_>
SettingFieldTimespan<unit_> & SettingFieldTimespan<unit_>::operator=(const Field & f)
{
if (x.getType() == Field::Types::String)
set(get<const String &>(x));
else
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), x));
*this = fieldToNumber<UInt64>(f);
return *this;
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::set(const String & x)
template <SettingFieldTimespanUnit unit_>
String SettingFieldTimespan<unit_>::toString() const
{
set(parse<UInt64>(x));
return ::DB::toString(operator UInt64());
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::writeBinary(WriteBuffer & out) const
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::parseFromString(const String & str)
{
writeVarUInt(value.totalMicroseconds() / microseconds_per_unit, out);
*this = stringToNumber<UInt64>(str);
}
template <SettingFieldTimespanUnit unit>
void SettingFieldTimespan<unit>::readBinary(ReadBuffer & in)
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::writeBinary(WriteBuffer & out) const
{
UInt64 x = 0;
readVarUInt(x, in);
set(x);
auto num_units = operator UInt64();
writeVarUInt(num_units, out);
}
template struct SettingFieldTimespan<SettingFieldTimespanUnit::SECOND>;
template struct SettingFieldTimespan<SettingFieldTimespanUnit::MILLISECOND>;
Field SettingFieldString::toField() const
template <SettingFieldTimespanUnit unit_>
void SettingFieldTimespan<unit_>::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<SettingFieldTimespanUnit::Second>;
template struct SettingFieldTimespan<SettingFieldTimespanUnit::Millisecond>;
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];
}
Field SettingFieldChar::toField() const
{
return toString();
char fieldToChar(const Field & f)
{
return stringToChar(f.safeGet<const String &>());
}
}
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<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 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<const String &>(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};
}
......
......@@ -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; }
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<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 &>())) {}
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<const String &>()); 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<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; \
......
......@@ -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());
}
......
......@@ -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; \
} \
}
......
......@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册