2019-11-08 18:47:31 +00:00
|
|
|
#include <Core/SettingsCollection.h>
|
|
|
|
#include <Core/SettingsCollectionImpl.h>
|
2018-06-05 19:46:49 +00:00
|
|
|
|
2019-03-22 12:08:30 +00:00
|
|
|
#include <Core/Field.h>
|
2018-06-05 19:46:49 +00:00
|
|
|
#include <Common/getNumberOfPhysicalCPUCores.h>
|
|
|
|
#include <Common/FieldVisitors.h>
|
2019-11-16 23:12:35 +00:00
|
|
|
#include <common/logger_useful.h>
|
2018-06-05 19:46:49 +00:00
|
|
|
#include <IO/ReadHelpers.h>
|
2019-08-01 17:43:10 +00:00
|
|
|
#include <IO/ReadBufferFromString.h>
|
2018-06-05 19:46:49 +00:00
|
|
|
#include <IO/WriteHelpers.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
|
|
|
namespace ErrorCodes
|
|
|
|
{
|
|
|
|
extern const int UNKNOWN_LOAD_BALANCING;
|
|
|
|
extern const int UNKNOWN_OVERFLOW_MODE;
|
|
|
|
extern const int UNKNOWN_TOTALS_MODE;
|
|
|
|
extern const int UNKNOWN_DISTRIBUTED_PRODUCT_MODE;
|
2020-02-18 17:31:22 +00:00
|
|
|
extern const int UNKNOWN_JOIN;
|
2018-06-05 19:46:49 +00:00
|
|
|
extern const int SIZE_OF_FIXED_STRING_DOESNT_MATCH;
|
2018-06-08 03:15:33 +00:00
|
|
|
extern const int BAD_ARGUMENTS;
|
2019-04-18 23:29:32 +00:00
|
|
|
extern const int UNKNOWN_SETTING;
|
2019-08-01 17:43:10 +00:00
|
|
|
extern const int CANNOT_PARSE_BOOL;
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
|
|
|
|
template <typename Type>
|
|
|
|
String SettingNumber<Type>::toString() const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
|
|
|
return DB::toString(value);
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
|
|
|
Field SettingNumber<Type>::toField() const
|
2019-04-18 23:29:32 +00:00
|
|
|
{
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
|
|
|
void SettingNumber<Type>::set(Type x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
|
|
|
value = x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
|
|
|
void SettingNumber<Type>::set(const Field & x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-18 23:29:32 +00:00
|
|
|
if (x.getType() == Field::Types::String)
|
|
|
|
set(get<const String &>(x));
|
|
|
|
else
|
2019-04-27 13:58:20 +00:00
|
|
|
set(applyVisitor(FieldVisitorConvertToNumber<Type>(), x));
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
|
|
|
void SettingNumber<Type>::set(const String & x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2020-01-24 10:54:24 +00:00
|
|
|
set(parseWithSizeSuffix<Type>(x));
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-08-01 17:03:34 +00:00
|
|
|
template <>
|
|
|
|
void SettingNumber<bool>::set(const String & x)
|
|
|
|
{
|
2019-08-01 17:43:10 +00:00
|
|
|
if (x.size() == 1)
|
|
|
|
{
|
|
|
|
if (x[0] == '0')
|
|
|
|
set(false);
|
|
|
|
else if (x[0] == '1')
|
|
|
|
set(true);
|
2019-08-01 19:30:00 +00:00
|
|
|
else
|
|
|
|
throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL);
|
2019-08-01 17:43:10 +00:00
|
|
|
}
|
2019-08-01 17:03:34 +00:00
|
|
|
else
|
2019-08-01 17:43:10 +00:00
|
|
|
{
|
|
|
|
ReadBufferFromString buf(x);
|
|
|
|
if (checkStringCaseInsensitive("true", buf))
|
|
|
|
set(true);
|
|
|
|
else if (checkStringCaseInsensitive("false", buf))
|
|
|
|
set(false);
|
2019-08-01 19:30:00 +00:00
|
|
|
else
|
|
|
|
throw Exception("Cannot parse bool from string '" + x + "'", ErrorCodes::CANNOT_PARSE_BOOL);
|
2019-08-01 17:43:10 +00:00
|
|
|
}
|
2019-08-01 17:03:34 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingNumber<Type>::serialize(WriteBuffer & buf, SettingsBinaryFormat format) const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
writeStringBinary(toString(), buf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-02 05:55:06 +00:00
|
|
|
if constexpr (is_integral_v<Type> && is_unsigned_v<Type>)
|
2019-04-27 13:58:20 +00:00
|
|
|
writeVarUInt(static_cast<UInt64>(value), buf);
|
2019-11-02 05:55:06 +00:00
|
|
|
else if constexpr (is_integral_v<Type> && is_signed_v<Type>)
|
2019-04-27 13:58:20 +00:00
|
|
|
writeVarInt(static_cast<Int64>(value), buf);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
static_assert(std::is_floating_point_v<Type>);
|
2019-11-16 23:12:35 +00:00
|
|
|
writeStringBinary(toString(), buf);
|
2019-04-27 13:58:20 +00:00
|
|
|
}
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename Type>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingNumber<Type>::deserialize(ReadBuffer & buf, SettingsBinaryFormat format)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
String x;
|
|
|
|
readStringBinary(x, buf);
|
|
|
|
set(x);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-02 05:55:06 +00:00
|
|
|
if constexpr (is_integral_v<Type> && is_unsigned_v<Type>)
|
2019-04-27 13:58:20 +00:00
|
|
|
{
|
|
|
|
UInt64 x;
|
|
|
|
readVarUInt(x, buf);
|
|
|
|
set(static_cast<Type>(x));
|
|
|
|
}
|
2019-11-02 05:55:06 +00:00
|
|
|
else if constexpr (is_integral_v<Type> && is_signed_v<Type>)
|
2019-04-27 13:58:20 +00:00
|
|
|
{
|
|
|
|
Int64 x;
|
|
|
|
readVarInt(x, buf);
|
|
|
|
set(static_cast<Type>(x));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
static_assert(std::is_floating_point_v<Type>);
|
|
|
|
String x;
|
2019-11-16 23:12:35 +00:00
|
|
|
readStringBinary(x, buf);
|
2019-04-27 13:58:20 +00:00
|
|
|
set(x);
|
|
|
|
}
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template struct SettingNumber<UInt64>;
|
|
|
|
template struct SettingNumber<Int64>;
|
|
|
|
template struct SettingNumber<float>;
|
|
|
|
template struct SettingNumber<bool>;
|
2018-06-05 19:46:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
String SettingMaxThreads::toString() const
|
|
|
|
{
|
|
|
|
/// Instead of the `auto` value, we output the actual value to make it easier to see.
|
2019-04-27 13:58:20 +00:00
|
|
|
return is_auto ? ("auto(" + DB::toString(value) + ")") : DB::toString(value);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
Field SettingMaxThreads::toField() const
|
|
|
|
{
|
|
|
|
return is_auto ? 0 : value;
|
|
|
|
}
|
|
|
|
|
2018-06-05 19:46:49 +00:00
|
|
|
void SettingMaxThreads::set(UInt64 x)
|
|
|
|
{
|
|
|
|
value = x ? x : getAutoValue();
|
|
|
|
is_auto = x == 0;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingMaxThreads::set(const Field & x)
|
|
|
|
{
|
|
|
|
if (x.getType() == Field::Types::String)
|
2019-04-18 23:29:32 +00:00
|
|
|
set(get<const String &>(x));
|
2018-06-05 19:46:49 +00:00
|
|
|
else
|
2020-03-13 14:50:26 +00:00
|
|
|
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), x));
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SettingMaxThreads::set(const String & x)
|
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
if (startsWith(x, "auto"))
|
2018-06-05 19:46:49 +00:00
|
|
|
setAuto();
|
|
|
|
else
|
|
|
|
set(parse<UInt64>(x));
|
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingMaxThreads::serialize(WriteBuffer & buf, SettingsBinaryFormat format) const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
writeStringBinary(is_auto ? "auto" : DB::toString(value), buf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
writeVarUInt(is_auto ? 0 : value, buf);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingMaxThreads::deserialize(ReadBuffer & buf, SettingsBinaryFormat format)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
String x;
|
|
|
|
readStringBinary(x, buf);
|
|
|
|
set(x);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
UInt64 x = 0;
|
|
|
|
readVarUInt(x, buf);
|
|
|
|
set(x);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SettingMaxThreads::setAuto()
|
|
|
|
{
|
|
|
|
value = getAutoValue();
|
|
|
|
is_auto = true;
|
|
|
|
}
|
|
|
|
|
2020-03-18 00:57:00 +00:00
|
|
|
UInt64 SettingMaxThreads::getAutoValue()
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
static auto res = getNumberOfPhysicalCPUCores();
|
2018-06-05 19:46:49 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
String SettingTimespan<io_unit>::toString() const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
return DB::toString(value.totalMicroseconds() / microseconds_per_io_unit);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
Field SettingTimespan<io_unit>::toField() const
|
2019-04-18 23:29:32 +00:00
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
return value.totalMicroseconds() / microseconds_per_io_unit;
|
2019-04-18 23:29:32 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
void SettingTimespan<io_unit>::set(const Poco::Timespan & x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
|
|
|
value = x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
void SettingTimespan<io_unit>::set(UInt64 x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
set(Poco::Timespan(x * microseconds_per_io_unit));
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
void SettingTimespan<io_unit>::set(const Field & x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-18 23:29:32 +00:00
|
|
|
if (x.getType() == Field::Types::String)
|
|
|
|
set(get<const String &>(x));
|
|
|
|
else
|
2020-03-13 14:50:26 +00:00
|
|
|
set(applyVisitor(FieldVisitorConvertToNumber<UInt64>(), x));
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
|
|
|
void SettingTimespan<io_unit>::set(const String & x)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
|
|
|
set(parse<UInt64>(x));
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingTimespan<io_unit>::serialize(WriteBuffer & buf, SettingsBinaryFormat format) const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
writeStringBinary(toString(), buf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
writeVarUInt(value.totalMicroseconds() / microseconds_per_io_unit, buf);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <SettingTimespanIO io_unit>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingTimespan<io_unit>::deserialize(ReadBuffer & buf, SettingsBinaryFormat format)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
if (format >= SettingsBinaryFormat::STRINGS)
|
|
|
|
{
|
|
|
|
String x;
|
|
|
|
readStringBinary(x, buf);
|
|
|
|
set(x);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
UInt64 x = 0;
|
|
|
|
readVarUInt(x, buf);
|
|
|
|
set(x);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template struct SettingTimespan<SettingTimespanIO::SECOND>;
|
|
|
|
template struct SettingTimespan<SettingTimespanIO::MILLISECOND>;
|
2018-06-05 19:46:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
String SettingString::toString() const
|
|
|
|
{
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
Field SettingString::toField() const
|
|
|
|
{
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2018-06-05 19:46:49 +00:00
|
|
|
void SettingString::set(const String & x)
|
|
|
|
{
|
|
|
|
value = x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingString::set(const Field & x)
|
|
|
|
{
|
|
|
|
set(safeGet<const String &>(x));
|
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingString::serialize(WriteBuffer & buf, SettingsBinaryFormat) const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
writeStringBinary(value, buf);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingString::deserialize(ReadBuffer & buf, SettingsBinaryFormat)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-18 23:29:32 +00:00
|
|
|
String s;
|
2019-11-16 23:12:35 +00:00
|
|
|
readStringBinary(s, buf);
|
2019-04-18 23:29:32 +00:00
|
|
|
set(s);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
String SettingChar::toString() const
|
|
|
|
{
|
|
|
|
return String(1, value);
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
Field SettingChar::toField() const
|
|
|
|
{
|
|
|
|
return toString();
|
|
|
|
}
|
|
|
|
|
2018-06-05 19:46:49 +00:00
|
|
|
void SettingChar::set(char x)
|
|
|
|
{
|
|
|
|
value = x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingChar::set(const String & x)
|
|
|
|
{
|
2019-03-26 13:05:53 +00:00
|
|
|
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);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SettingChar::set(const Field & x)
|
|
|
|
{
|
|
|
|
const String & s = safeGet<const String &>(x);
|
|
|
|
set(s);
|
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingChar::serialize(WriteBuffer & buf, SettingsBinaryFormat) const
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
writeStringBinary(toString(), buf);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingChar::deserialize(ReadBuffer & buf, SettingsBinaryFormat)
|
2018-06-05 19:46:49 +00:00
|
|
|
{
|
2019-04-18 23:29:32 +00:00
|
|
|
String s;
|
2019-11-16 23:12:35 +00:00
|
|
|
readStringBinary(s, buf);
|
2019-04-18 23:29:32 +00:00
|
|
|
set(s);
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|
|
|
|
|
2018-06-08 03:15:33 +00:00
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename EnumType, typename Tag>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingEnum<EnumType, Tag>::serialize(WriteBuffer & buf, SettingsBinaryFormat) const
|
2018-06-08 03:15:33 +00:00
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
writeStringBinary(toString(), buf);
|
2018-06-08 03:15:33 +00:00
|
|
|
}
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
template <typename EnumType, typename Tag>
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingEnum<EnumType, Tag>::deserialize(ReadBuffer & buf, SettingsBinaryFormat)
|
2018-06-08 03:15:33 +00:00
|
|
|
{
|
2019-04-27 13:58:20 +00:00
|
|
|
String s;
|
2019-11-16 23:12:35 +00:00
|
|
|
readStringBinary(s, buf);
|
2019-04-27 13:58:20 +00:00
|
|
|
set(s);
|
2018-06-08 03:15:33 +00:00
|
|
|
}
|
|
|
|
|
2019-10-04 13:32:21 +00:00
|
|
|
template <typename EnumType, typename Tag>
|
|
|
|
Field SettingEnum<EnumType, Tag>::toField() const
|
|
|
|
{
|
|
|
|
return toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename EnumType, typename Tag>
|
|
|
|
void SettingEnum<EnumType, Tag>::set(const Field & x)
|
|
|
|
{
|
|
|
|
set(safeGet<const String &>(x));
|
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
|
2020-02-02 00:53:11 +00:00
|
|
|
String SettingURI::toString() const
|
|
|
|
{
|
|
|
|
return value.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
Field SettingURI::toField() const
|
|
|
|
{
|
|
|
|
return value.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingURI::set(const Poco::URI & x)
|
|
|
|
{
|
|
|
|
value = x;
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingURI::set(const Field & x)
|
|
|
|
{
|
|
|
|
const String & s = safeGet<const String &>(x);
|
|
|
|
set(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingURI::set(const String & x)
|
|
|
|
{
|
2020-02-02 04:06:20 +00:00
|
|
|
set(Poco::URI(x));
|
2020-02-02 00:53:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SettingURI::serialize(WriteBuffer & buf, SettingsBinaryFormat) const
|
|
|
|
{
|
|
|
|
writeStringBinary(toString(), buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingURI::deserialize(ReadBuffer & buf, SettingsBinaryFormat)
|
|
|
|
{
|
|
|
|
String s;
|
|
|
|
readStringBinary(s, buf);
|
|
|
|
set(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define IMPLEMENT_SETTING_ENUM(ENUM_NAME, LIST_OF_NAMES_MACRO, ERROR_CODE_FOR_UNEXPECTED_NAME) \
|
|
|
|
IMPLEMENT_SETTING_ENUM_WITH_TAG(ENUM_NAME, void, LIST_OF_NAMES_MACRO, ERROR_CODE_FOR_UNEXPECTED_NAME)
|
|
|
|
|
|
|
|
#define IMPLEMENT_SETTING_ENUM_WITH_TAG(ENUM_NAME, TAG, LIST_OF_NAMES_MACRO, ERROR_CODE_FOR_UNEXPECTED_NAME) \
|
|
|
|
template <> \
|
|
|
|
String SettingEnum<ENUM_NAME, TAG>::toString() const \
|
|
|
|
{ \
|
|
|
|
using EnumType = ENUM_NAME; \
|
|
|
|
using UnderlyingType = std::underlying_type<EnumType>::type; \
|
|
|
|
switch (static_cast<UnderlyingType>(value)) \
|
|
|
|
{ \
|
|
|
|
LIST_OF_NAMES_MACRO(IMPLEMENT_SETTING_ENUM_TO_STRING_HELPER_) \
|
|
|
|
} \
|
|
|
|
throw Exception("Unknown " #ENUM_NAME, ERROR_CODE_FOR_UNEXPECTED_NAME); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template <> \
|
|
|
|
void SettingEnum<ENUM_NAME, TAG>::set(const String & s) \
|
|
|
|
{ \
|
|
|
|
using EnumType = ENUM_NAME; \
|
|
|
|
LIST_OF_NAMES_MACRO(IMPLEMENT_SETTING_ENUM_FROM_STRING_HELPER_) \
|
|
|
|
\
|
|
|
|
String all_io_names; \
|
|
|
|
LIST_OF_NAMES_MACRO(IMPLEMENT_SETTING_ENUM_CONCAT_NAMES_HELPER_) \
|
|
|
|
throw Exception("Unknown " #ENUM_NAME " : '" + s + "', must be one of " + all_io_names, \
|
|
|
|
ERROR_CODE_FOR_UNEXPECTED_NAME); \
|
|
|
|
} \
|
|
|
|
\
|
|
|
|
template struct SettingEnum<ENUM_NAME, TAG>;
|
|
|
|
|
|
|
|
#define IMPLEMENT_SETTING_ENUM_TO_STRING_HELPER_(NAME, IO_NAME) \
|
|
|
|
case static_cast<UnderlyingType>(EnumType::NAME): return IO_NAME;
|
|
|
|
|
|
|
|
#define IMPLEMENT_SETTING_ENUM_FROM_STRING_HELPER_(NAME, IO_NAME) \
|
2020-03-18 02:02:24 +00:00
|
|
|
if (s == (IO_NAME)) \
|
2019-04-27 13:58:20 +00:00
|
|
|
{ \
|
|
|
|
set(EnumType::NAME); \
|
|
|
|
return; \
|
|
|
|
}
|
2018-06-08 03:15:33 +00:00
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define IMPLEMENT_SETTING_ENUM_CONCAT_NAMES_HELPER_(NAME, IO_NAME) \
|
|
|
|
if (!all_io_names.empty()) \
|
|
|
|
all_io_names += ", "; \
|
2020-03-18 02:02:24 +00:00
|
|
|
all_io_names += String("'") + (IO_NAME) + "'";
|
2018-06-08 03:15:33 +00:00
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define LOAD_BALANCING_LIST_OF_NAMES(M) \
|
|
|
|
M(RANDOM, "random") \
|
|
|
|
M(NEAREST_HOSTNAME, "nearest_hostname") \
|
|
|
|
M(IN_ORDER, "in_order") \
|
|
|
|
M(FIRST_OR_RANDOM, "first_or_random")
|
|
|
|
IMPLEMENT_SETTING_ENUM(LoadBalancing, LOAD_BALANCING_LIST_OF_NAMES, ErrorCodes::UNKNOWN_LOAD_BALANCING)
|
2018-06-08 03:15:33 +00:00
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define JOIN_STRICTNESS_LIST_OF_NAMES(M) \
|
|
|
|
M(Unspecified, "") \
|
|
|
|
M(ALL, "ALL") \
|
|
|
|
M(ANY, "ANY")
|
2020-03-08 22:08:39 +00:00
|
|
|
IMPLEMENT_SETTING_ENUM(JoinStrictness, JOIN_STRICTNESS_LIST_OF_NAMES, ErrorCodes::UNKNOWN_JOIN) // NOLINT
|
2020-02-18 17:31:22 +00:00
|
|
|
|
|
|
|
#define JOIN_ALGORITHM_NAMES(M) \
|
|
|
|
M(AUTO, "auto") \
|
|
|
|
M(HASH, "hash") \
|
|
|
|
M(PARTIAL_MERGE, "partial_merge") \
|
|
|
|
M(PREFER_PARTIAL_MERGE, "prefer_partial_merge")
|
|
|
|
IMPLEMENT_SETTING_ENUM(JoinAlgorithm, JOIN_ALGORITHM_NAMES, ErrorCodes::UNKNOWN_JOIN)
|
2018-12-18 21:18:54 +00:00
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define TOTALS_MODE_LIST_OF_NAMES(M) \
|
|
|
|
M(BEFORE_HAVING, "before_having") \
|
|
|
|
M(AFTER_HAVING_EXCLUSIVE, "after_having_exclusive") \
|
|
|
|
M(AFTER_HAVING_INCLUSIVE, "after_having_inclusive") \
|
|
|
|
M(AFTER_HAVING_AUTO, "after_having_auto")
|
|
|
|
IMPLEMENT_SETTING_ENUM(TotalsMode, TOTALS_MODE_LIST_OF_NAMES, ErrorCodes::UNKNOWN_TOTALS_MODE)
|
2018-12-18 21:18:54 +00:00
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define OVERFLOW_MODE_LIST_OF_NAMES(M) \
|
|
|
|
M(THROW, "throw") \
|
|
|
|
M(BREAK, "break")
|
|
|
|
IMPLEMENT_SETTING_ENUM(OverflowMode, OVERFLOW_MODE_LIST_OF_NAMES, ErrorCodes::UNKNOWN_OVERFLOW_MODE)
|
2019-04-18 23:29:32 +00:00
|
|
|
|
2018-12-18 21:18:54 +00:00
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define OVERFLOW_MODE_LIST_OF_NAMES_WITH_ANY(M) \
|
|
|
|
M(THROW, "throw") \
|
|
|
|
M(BREAK, "break") \
|
|
|
|
M(ANY, "any")
|
|
|
|
IMPLEMENT_SETTING_ENUM_WITH_TAG(OverflowMode, SettingOverflowModeGroupByTag, OVERFLOW_MODE_LIST_OF_NAMES_WITH_ANY, ErrorCodes::UNKNOWN_OVERFLOW_MODE)
|
2018-12-18 21:18:54 +00:00
|
|
|
|
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
#define DISTRIBUTED_PRODUCT_MODE_LIST_OF_NAMES(M) \
|
|
|
|
M(DENY, "deny") \
|
|
|
|
M(LOCAL, "local") \
|
|
|
|
M(GLOBAL, "global") \
|
|
|
|
M(ALLOW, "allow")
|
|
|
|
IMPLEMENT_SETTING_ENUM(DistributedProductMode, DISTRIBUTED_PRODUCT_MODE_LIST_OF_NAMES, ErrorCodes::UNKNOWN_DISTRIBUTED_PRODUCT_MODE)
|
2018-12-18 21:18:54 +00:00
|
|
|
|
2019-04-27 13:58:20 +00:00
|
|
|
|
|
|
|
#define DATE_TIME_INPUT_FORMAT_LIST_OF_NAMES(M) \
|
|
|
|
M(Basic, "basic") \
|
|
|
|
M(BestEffort, "best_effort")
|
|
|
|
IMPLEMENT_SETTING_ENUM(FormatSettings::DateTimeInputFormat, DATE_TIME_INPUT_FORMAT_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS)
|
|
|
|
|
|
|
|
|
|
|
|
#define LOGS_LEVEL_LIST_OF_NAMES(M) \
|
|
|
|
M(none, "none") \
|
|
|
|
M(error, "error") \
|
|
|
|
M(warning, "warning") \
|
|
|
|
M(information, "information") \
|
|
|
|
M(debug, "debug") \
|
|
|
|
M(trace, "trace")
|
|
|
|
IMPLEMENT_SETTING_ENUM(LogsLevel, LOGS_LEVEL_LIST_OF_NAMES, ErrorCodes::BAD_ARGUMENTS)
|
2018-12-18 21:18:54 +00:00
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
|
|
|
|
namespace details
|
|
|
|
{
|
2019-11-08 18:47:31 +00:00
|
|
|
void SettingsCollectionUtils::serializeName(const StringRef & name, WriteBuffer & buf)
|
|
|
|
{
|
2019-11-16 23:12:35 +00:00
|
|
|
writeStringBinary(name, buf);
|
2019-11-08 18:47:31 +00:00
|
|
|
}
|
|
|
|
|
2019-04-18 23:29:32 +00:00
|
|
|
String SettingsCollectionUtils::deserializeName(ReadBuffer & buf)
|
|
|
|
{
|
|
|
|
String name;
|
2019-11-16 23:12:35 +00:00
|
|
|
readStringBinary(name, buf);
|
2019-04-18 23:29:32 +00:00
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2019-11-08 15:07:37 +00:00
|
|
|
void SettingsCollectionUtils::serializeFlag(bool flag, WriteBuffer & buf)
|
|
|
|
{
|
|
|
|
buf.write(flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SettingsCollectionUtils::deserializeFlag(ReadBuffer & buf)
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
buf.readStrict(c);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2019-11-16 23:12:35 +00:00
|
|
|
void SettingsCollectionUtils::skipValue(ReadBuffer & buf)
|
|
|
|
{
|
|
|
|
/// Ignore a string written by the function writeStringBinary().
|
|
|
|
UInt64 size;
|
|
|
|
readVarUInt(size, buf);
|
|
|
|
buf.ignore(size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SettingsCollectionUtils::warningNameNotFound(const StringRef & name)
|
|
|
|
{
|
|
|
|
static auto * log = &Logger::get("Settings");
|
|
|
|
LOG_WARNING(log, "Unknown setting " << name << ", skipping");
|
|
|
|
}
|
2019-04-18 23:29:32 +00:00
|
|
|
|
|
|
|
void SettingsCollectionUtils::throwNameNotFound(const StringRef & name)
|
|
|
|
{
|
|
|
|
throw Exception("Unknown setting " + name.toString(), ErrorCodes::UNKNOWN_SETTING);
|
|
|
|
}
|
|
|
|
}
|
2018-06-05 19:46:49 +00:00
|
|
|
}
|