mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-28 10:31:57 +00:00
Fixed extremes calculation in presense of NaNs [#METR-22882].
This commit is contained in:
parent
00176b9c5e
commit
9c39a324f2
@ -120,6 +120,27 @@ template <> inline UInt64 unionCastToUInt64(Float32 x)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// To be sure, that this function is zero-cost for non-floating point types.
|
||||||
|
template <typename T>
|
||||||
|
inline bool isNaN(T x)
|
||||||
|
{
|
||||||
|
return std::is_floating_point<T>::value ? isnan(x) : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<std::is_floating_point<T>::value, T>::type NaNOrZero()
|
||||||
|
{
|
||||||
|
return std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<!std::is_floating_point<T>::value, T>::type NaNOrZero()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Шаблон столбцов, которые используют для хранения простой массив.
|
/** Шаблон столбцов, которые используют для хранения простой массив.
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -435,16 +456,35 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
T cur_min = data[0];
|
bool has_value = false;
|
||||||
T cur_max = data[0];
|
|
||||||
|
|
||||||
for (size_t i = 1; i < size; ++i)
|
/** Skip all NaNs in extremes calculation.
|
||||||
|
* If all values are NaNs, then return NaN.
|
||||||
|
* NOTE: There exist many different NaNs.
|
||||||
|
* Different NaN could be returned: not bit-exact value as one of NaNs from column.
|
||||||
|
*/
|
||||||
|
|
||||||
|
T cur_min = NaNOrZero<T>();
|
||||||
|
T cur_max = NaNOrZero<T>();
|
||||||
|
|
||||||
|
for (const T x : data)
|
||||||
{
|
{
|
||||||
if (data[i] < cur_min)
|
if (isNaN(x))
|
||||||
cur_min = data[i];
|
continue;
|
||||||
|
|
||||||
if (data[i] > cur_max)
|
if (!has_value)
|
||||||
cur_max = data[i];
|
{
|
||||||
|
cur_min = x;
|
||||||
|
cur_max = x;
|
||||||
|
has_value = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x < cur_min)
|
||||||
|
cur_min = x;
|
||||||
|
|
||||||
|
if (x > cur_max)
|
||||||
|
cur_max = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
min = typename NearestFieldType<T>::Type(cur_min);
|
min = typename NearestFieldType<T>::Type(cur_min);
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
3
|
||||||
|
1
|
||||||
|
2
|
||||||
|
|
||||||
|
1
|
||||||
|
3
|
||||||
|
nan
|
||||||
|
1
|
||||||
|
2
|
||||||
|
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
nan
|
||||||
|
2
|
||||||
|
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
1
|
||||||
|
nan
|
||||||
|
|
||||||
|
1
|
||||||
|
3
|
||||||
|
nan
|
||||||
|
nan
|
||||||
|
2
|
||||||
|
|
||||||
|
2
|
||||||
|
2
|
||||||
|
nan
|
||||||
|
1
|
||||||
|
nan
|
||||||
|
|
||||||
|
1
|
||||||
|
1
|
||||||
|
3
|
||||||
|
nan
|
||||||
|
nan
|
||||||
|
|
||||||
|
3
|
||||||
|
3
|
||||||
|
nan
|
||||||
|
nan
|
||||||
|
nan
|
||||||
|
|
||||||
|
nan
|
||||||
|
nan
|
@ -0,0 +1,8 @@
|
|||||||
|
SELECT arrayJoin([3, 1, 2]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([nan, 1, 2]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([3, nan, 2]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([3, 1, nan]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([nan, nan, 2]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([nan, 1, nan]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([3, nan, nan]) SETTINGS extremes = 1;
|
||||||
|
SELECT arrayJoin([nan, nan, nan]) SETTINGS extremes = 1;
|
Loading…
Reference in New Issue
Block a user