Backport #70979 to 24.3: Fix an error with negative zeros in two-level hash table

This commit is contained in:
robot-clickhouse 2024-10-23 21:09:21 +00:00
parent 3e29f2d91a
commit 3bf9a44267
4 changed files with 28 additions and 21 deletions

View File

@ -367,11 +367,15 @@ namespace PackedZeroTraits
{ {
template <typename Second, template <typename, typename> class PackedPairNoInit> template <typename Second, template <typename, typename> class PackedPairNoInit>
inline bool check(const PackedPairNoInit<StringRef, Second> p) inline bool check(const PackedPairNoInit<StringRef, Second> p)
{ return 0 == p.key.size; } {
return 0 == p.key.size;
}
template <typename Second, template <typename, typename> class PackedPairNoInit> template <typename Second, template <typename, typename> class PackedPairNoInit>
inline void set(PackedPairNoInit<StringRef, Second> & p) inline void set(PackedPairNoInit<StringRef, Second> & p)
{ p.key.size = 0; } {
p.key.size = 0;
}
} }

View File

@ -67,19 +67,6 @@ struct HashTableNoState
}; };
/// These functions can be overloaded for custom types.
namespace ZeroTraits
{
template <typename T>
bool check(const T x) { return x == T{}; }
template <typename T>
void set(T & x) { x = T{}; }
}
/** Numbers are compared bitwise. /** Numbers are compared bitwise.
* Complex types are compared by operator== as usual (this is important if there are gaps). * Complex types are compared by operator== as usual (this is important if there are gaps).
* *
@ -87,18 +74,32 @@ void set(T & x) { x = T{}; }
* Otherwise the invariants in hash table probing do not met when NaNs are present. * Otherwise the invariants in hash table probing do not met when NaNs are present.
*/ */
template <typename T> template <typename T>
inline bool bitEquals(T && a, T && b) inline bool bitEquals(T a, T b)
{ {
using RealT = std::decay_t<T>; if constexpr (std::is_floating_point_v<T>)
/// Note that memcmp with constant size is a compiler builtin.
if constexpr (std::is_floating_point_v<RealT>) return 0 == memcmp(&a, &b, sizeof(T)); /// NOLINT
/// Note that memcmp with constant size is compiler builtin.
return 0 == memcmp(&a, &b, sizeof(RealT)); /// NOLINT
else else
return a == b; return a == b;
} }
/// These functions can be overloaded for custom types.
namespace ZeroTraits
{
template <typename T>
bool check(const T x)
{
return bitEquals(x, T{});
}
template <typename T>
void set(T & x) { x = T{}; }
}
/** /**
* getKey/Mapped -- methods to get key/"mapped" values from the LookupResult returned by find() and * getKey/Mapped -- methods to get key/"mapped" values from the LookupResult returned by find() and
* emplace() methods of HashTable. Must not be called for a null LookupResult. * emplace() methods of HashTable. Must not be called for a null LookupResult.

View File

@ -0,0 +1 @@
WITH number % 1000 = 0 ? (rand() % 2 ? 0.0 : -0.0) : number::Float64 AS x SELECT length(uniqExactState(x)::String) FROM numbers(1000000);