Make fromReadableSize return UInt64 again

This commit is contained in:
Francisco Javier Jurado Moreno 2024-05-28 09:48:34 +02:00
parent ac8186d02f
commit ef42050ce0
3 changed files with 44 additions and 23 deletions

View File

@ -50,7 +50,7 @@ public:
{"readable_size", static_cast<FunctionArgumentDescriptor::TypeValidator>(&isString), nullptr, "String"},
};
validateFunctionArgumentTypes(*this, arguments, args);
DataTypePtr return_type = std::make_shared<DataTypeFloat64>();
DataTypePtr return_type = std::make_shared<DataTypeUInt64>();
if (error_handling == ErrorHandling::Null) {
return std::make_shared<DataTypeNullable>(return_type);
} else {
@ -74,9 +74,9 @@ public:
);
}
std::unordered_map<std::string_view, Float64> scale_factors = Impl::getScaleFactors();
std::unordered_map<std::string_view, size_t> scale_factors = Impl::getScaleFactors();
auto col_res = ColumnFloat64::create(input_rows_count);
auto col_res = ColumnUInt64::create(input_rows_count);
ColumnUInt8::MutablePtr col_null_map;
if constexpr (error_handling == ErrorHandling::Null)
@ -112,7 +112,7 @@ public:
private:
Float64 parseReadableFormat(const std::unordered_map<std::string_view, Float64> & scale_factors, const std::string_view & str) const
UInt64 parseReadableFormat(const std::unordered_map<std::string_view, size_t> & scale_factors, const std::string_view & str) const
{
ReadBufferFromString buf(str);
// tryReadFloatText does seem to not raise any error when there is leading whitespace so we check it explicitly
@ -137,6 +137,15 @@ private:
str
);
}
else if (base < 0)
{
throw Exception(
ErrorCodes::BAD_ARGUMENTS,
"Invalid expression for function {} - Negative sizes are not allowed (\"{}\")",
getName(),
base
);
}
skipWhitespaceIfAny(buf);
@ -162,7 +171,19 @@ private:
unit
);
}
return base * iter->second;
Float64 num_bytes_with_decimals = base * iter->second;
if (num_bytes_with_decimals > std::numeric_limits<UInt64>::max())
{
throw Exception(
ErrorCodes::BAD_ARGUMENTS,
"Invalid expression for function {} - Result is too big for output type (\"{}\")",
getName(),
num_bytes_with_decimals
);
}
// As the input might be an arbitrary decimal number we might end up with a non-integer amount of bytes when parsing binary (eg MiB) units.
// This doesn't make sense so we round up to indicate the byte size that can fit the passed size.
return static_cast<UInt64>(std::ceil(num_bytes_with_decimals));
}
};
}

View File

@ -9,20 +9,20 @@ namespace
{
// ISO/IEC 80000-13 binary units
const std::unordered_map<std::string_view, Float64> scale_factors =
const std::unordered_map<std::string_view, size_t> scale_factors =
{
{"b", 1.0},
{"kb", 1000.0},
{"mb", 1000.0 * 1000.0},
{"gb", 1000.0 * 1000.0 * 1000.0},
{"tb", 1000.0 * 1000.0 * 1000.0 * 1000.0},
{"pb", 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0},
{"eb", 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0 * 1000.0},
{"b", 1L},
{"kb", 1000L},
{"mb", 1000L * 1000L},
{"gb", 1000L * 1000L * 1000L},
{"tb", 1000L * 1000L * 1000L * 1000L},
{"pb", 1000L * 1000L * 1000L * 1000L * 1000L},
{"eb", 1000L * 1000L * 1000L * 1000L * 1000L * 1000L},
};
struct Impl
{
static const std::unordered_map<std::string_view, Float64> & getScaleFactors()
static const std::unordered_map<std::string_view, size_t> & getScaleFactors()
{
return scale_factors;
}

View File

@ -9,20 +9,20 @@ namespace
{
// ISO/IEC 80000-13 binary units
const std::unordered_map<std::string_view, Float64> scale_factors =
const std::unordered_map<std::string_view, size_t> scale_factors =
{
{"b", 1.0},
{"kib", 1024.0},
{"mib", 1024.0 * 1024.0},
{"gib", 1024.0 * 1024.0 * 1024.0},
{"tib", 1024.0 * 1024.0 * 1024.0 * 1024.0},
{"pib", 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0},
{"eib", 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0},
{"b", 1L},
{"kib", 1024L},
{"mib", 1024L * 1024L},
{"gib", 1024L * 1024L * 1024L},
{"tib", 1024L * 1024L * 1024L * 1024L},
{"pib", 1024L * 1024L * 1024L * 1024L * 1024L},
{"eib", 1024L * 1024L * 1024L * 1024L * 1024L * 1024L},
};
struct Impl
{
static const std::unordered_map<std::string_view, Float64> & getScaleFactors()
static const std::unordered_map<std::string_view, size_t> & getScaleFactors()
{
return scale_factors;
}