mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Handle overflow in quantileTDigest
This commit is contained in:
parent
2c0b59576e
commit
58a756da9e
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <Common/Exception.h>
|
||||
#include <Common/RadixSort.h>
|
||||
#include <Common/PODArray.h>
|
||||
#include <Core/AccurateComparison.h>
|
||||
#include <IO/WriteBuffer.h>
|
||||
#include <IO/ReadBuffer.h>
|
||||
#include <IO/VarInt.h>
|
||||
@ -14,8 +16,9 @@ struct Settings;
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int TOO_LARGE_ARRAY_SIZE;
|
||||
extern const int CANNOT_PARSE_INPUT_ASSERTION_FAILED;
|
||||
extern const int DECIMAL_OVERFLOW;
|
||||
extern const int TOO_LARGE_ARRAY_SIZE;
|
||||
}
|
||||
|
||||
|
||||
@ -314,7 +317,7 @@ public:
|
||||
compress();
|
||||
|
||||
if (centroids.size() == 1)
|
||||
return centroids.front().mean;
|
||||
return checkOverflow<ResultType>(centroids.front().mean);
|
||||
|
||||
Float64 x = level * count;
|
||||
Float64 prev_x = 0;
|
||||
@ -333,11 +336,11 @@ public:
|
||||
Float64 right = current_x - 0.5 * (c.count == 1);
|
||||
|
||||
if (x <= left)
|
||||
return prev_mean;
|
||||
return checkOverflow<ResultType>(prev_mean);
|
||||
else if (x >= right)
|
||||
return c.mean;
|
||||
return checkOverflow<ResultType>(c.mean);
|
||||
else
|
||||
return interpolate(x, left, prev_mean, right, c.mean);
|
||||
return checkOverflow<ResultType>(interpolate(x, left, prev_mean, right, c.mean));
|
||||
}
|
||||
|
||||
sum += c.count;
|
||||
@ -346,7 +349,7 @@ public:
|
||||
prev_x = current_x;
|
||||
}
|
||||
|
||||
return centroids.back().mean;
|
||||
return checkOverflow<ResultType>(centroids.back().mean);
|
||||
}
|
||||
|
||||
/** Get multiple quantiles (`size` parts).
|
||||
@ -438,6 +441,16 @@ public:
|
||||
{
|
||||
getManyImpl(levels, indices, size, result);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ResultType>
|
||||
static ResultType checkOverflow(Value val)
|
||||
{
|
||||
ResultType result;
|
||||
if (bool ok = accurate::convertNumeric(val, result); ok)
|
||||
return result;
|
||||
throw DB::Exception("Numeric overflow", ErrorCodes::DECIMAL_OVERFLOW);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
SELECT cityHash64(toString(quantileDeterministicState(number, sipHash64(number)))) FROM numbers(8193);
|
3
tests/queries/0_stateless/01779_quantile_sanitizer.sql
Normal file
3
tests/queries/0_stateless/01779_quantile_sanitizer.sql
Normal file
@ -0,0 +1,3 @@
|
||||
SELECT cityHash64(toString(quantileDeterministicState(number, sipHash64(number)))) FROM numbers(8193);
|
||||
SELECT quantileTDigest(0.8)(toDateTime('2106-02-07 09:28:15')); -- { serverError DECIMAL_OVERFLOW }
|
||||
SELECT quantileTDigestWeighted(-0.)(toDateTime(10000000000.), 1); -- { serverError DECIMAL_OVERFLOW }
|
Loading…
Reference in New Issue
Block a user