Merge pull request #8072 from millb/suffix_in_settings_value

Parsing suffix for settings values
This commit is contained in:
alexey-milovidov 2020-01-24 17:15:25 +03:00 committed by GitHub
commit b3d34da57b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 16 deletions

View File

@ -62,7 +62,7 @@ void SettingNumber<Type>::set(const Field & x)
template <typename Type>
void SettingNumber<Type>::set(const String & x)
{
set(completeParse<Type>(x));
set(parseWithSizeSuffix<Type>(x));
}
template <>

View File

@ -972,28 +972,78 @@ inline T parse(const char * data, size_t size)
return res;
}
/// Read something from text format, but expect complete parse of given text
/// For example: 723145 -- ok, 213MB -- not ok
template <typename T>
inline T completeParse(const char * data, size_t size)
inline std::enable_if_t<!is_integral_v<T>, void>
readTextWithSizeSuffix(T & x, ReadBuffer & buf) { readText(x, buf); }
template <typename T>
inline std::enable_if_t<is_integral_v<T>, void>
readTextWithSizeSuffix(T & x, ReadBuffer & buf)
{
readIntText(x, buf);
if (buf.eof())
return;
/// Updates x depending on the suffix
auto finish = [&buf, &x] (UInt64 base, int power_of_two) mutable
{
++buf.position();
if (buf.eof())
{
x *= base; /// For decimal suffixes, such as k, M, G etc.
}
else if (*buf.position() == 'i')
{
x = (x << power_of_two); /// For binary suffixes, such as ki, Mi, Gi, etc.
++buf.position();
}
return;
};
switch (*buf.position())
{
case 'k': [[fallthrough]];
case 'K':
finish(1000, 10);
break;
case 'M':
finish(1000000, 20);
break;
case 'G':
finish(1000000000, 30);
break;
case 'T':
finish(1000000000000ULL, 40);
break;
default:
return;
}
return;
}
/// Read something from text format and trying to parse the suffix.
/// If the suffix is not valid gives an error
/// For example: 723145 -- ok, 213MB -- not ok, but 213Mi -- ok
template <typename T>
inline T parseWithSizeSuffix(const char * data, size_t size)
{
T res;
ReadBufferFromMemory buf(data, size);
readText(res, buf);
readTextWithSizeSuffix(res, buf);
assertEOF(buf);
return res;
}
template <typename T>
inline T completeParse(const String & s)
inline T parseWithSizeSuffix(const String & s)
{
return completeParse<T>(s.data(), s.size());
return parseWithSizeSuffix<T>(s.data(), s.size());
}
template <typename T>
inline T completeParse(const char * data)
inline T parseWithSizeSuffix(const char * data)
{
return completeParse<T>(data, strlen(data));
return parseWithSizeSuffix<T>(data, strlen(data));
}
template <typename T>

View File

@ -1,2 +1,10 @@
10000000001
10000000001
1000000000
3221225472
1567000
125952
1567000
125952
12000000
32505856
1000000000000
1099511627776

View File

@ -1,7 +1,20 @@
SET max_memory_usage = 10000000001;
SET max_memory_usage = '1G';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '1G'; -- { serverError 27 }
SET max_memory_usage = '3Gi';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '1567k';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '123ki';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '1567K';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '123Ki';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '12M';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '31Mi';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '1T';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';
SET max_memory_usage = '1Ti';
SELECT value FROM system.settings WHERE name = 'max_memory_usage';