mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Fix UBsan reports in quantileTiming
UBsan reports [1]: ../src/AggregateFunctions/QuantileTiming.h:442:27: runtime error: 1.84467e+19 is outside the range of representable values of type 'unsigned long' Received signal -3 Received signal Unknown signal (-3) [1]: https://clickhouse-test-reports.s3.yandex.net/19971/e15f5d9cb5b36482d1ae9ca069074fb200f2ab37/fuzzer_ubsan/report.html#fail1 Follow-up for: #19394
This commit is contained in:
parent
da79469092
commit
984445b44b
@ -32,6 +32,8 @@ namespace ErrorCodes
|
||||
* - a histogram (that is, value -> number), consisting of two parts
|
||||
* -- for values from 0 to 1023 - in increments of 1;
|
||||
* -- for values from 1024 to 30,000 - in increments of 16;
|
||||
*
|
||||
* NOTE: 64-bit integer weight can overflow, see also QantileExactWeighted.h::get()
|
||||
*/
|
||||
|
||||
#define TINY_MAX_ELEMS 31
|
||||
@ -396,9 +398,9 @@ namespace detail
|
||||
/// Get the value of the `level` quantile. The level must be between 0 and 1.
|
||||
UInt16 get(double level) const
|
||||
{
|
||||
UInt64 pos = std::ceil(count * level);
|
||||
double pos = std::ceil(count * level);
|
||||
|
||||
UInt64 accumulated = 0;
|
||||
double accumulated = 0;
|
||||
Iterator it(*this);
|
||||
|
||||
while (it.isValid())
|
||||
@ -422,9 +424,9 @@ namespace detail
|
||||
const auto * indices_end = indices + size;
|
||||
const auto * index = indices;
|
||||
|
||||
UInt64 pos = std::ceil(count * levels[*index]);
|
||||
double pos = std::ceil(count * levels[*index]);
|
||||
|
||||
UInt64 accumulated = 0;
|
||||
double accumulated = 0;
|
||||
Iterator it(*this);
|
||||
|
||||
while (it.isValid())
|
||||
|
@ -0,0 +1,2 @@
|
||||
[0]
|
||||
[0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1]
|
31
tests/queries/0_stateless/01690_quantilesTiming_ubsan.sql
Normal file
31
tests/queries/0_stateless/01690_quantilesTiming_ubsan.sql
Normal file
@ -0,0 +1,31 @@
|
||||
-- NOTE: that due to overflows it may give different result before
|
||||
-- quantilesTimingWeighted() had been converted to double:
|
||||
--
|
||||
-- Before:
|
||||
--
|
||||
-- SELECT quantilesTimingWeighted(1)(number, 9223372036854775807)
|
||||
-- FROM numbers(2)
|
||||
--
|
||||
-- ┌─quantilesTimingWeighted(1)(number, 9223372036854775807)─┐
|
||||
-- │ [1] │
|
||||
-- └─────────────────────────────────────────────────────────┘
|
||||
--
|
||||
-- After:
|
||||
--
|
||||
-- SELECT quantilesTimingWeighted(1)(number, 9223372036854775807)
|
||||
-- FROM numbers(2)
|
||||
--
|
||||
-- ┌─quantilesTimingWeighted(1)(number, 9223372036854775807)─┐
|
||||
-- │ [0] │
|
||||
-- └─────────────────────────────────────────────────────────┘
|
||||
|
||||
SELECT quantilesTimingWeighted(0.1)(number, 9223372036854775807) FROM numbers(2);
|
||||
|
||||
-- same UB, but in the inner loop
|
||||
SELECT quantilesTimingWeighted(0, 0.001, 0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.6, 0.7, 0.8, 0.9, 0.95, 0.99, 0.999, 1)(number, 9223372036854775807)
|
||||
FROM
|
||||
(
|
||||
SELECT number
|
||||
FROM system.numbers
|
||||
LIMIT 100
|
||||
);
|
Loading…
Reference in New Issue
Block a user