|
19 | 19 |
|
20 | 20 | #include "paimon/common/global_index/btree/key_serializer.h" |
21 | 21 |
|
| 22 | +#include <cstdint> |
| 23 | +#include <cstring> |
| 24 | +#include <string> |
| 25 | + |
22 | 26 | #include "gtest/gtest.h" |
23 | 27 | #include "paimon/data/decimal.h" |
24 | 28 | #include "paimon/data/timestamp.h" |
25 | 29 | #include "paimon/testing/utils/testharness.h" |
26 | 30 |
|
27 | 31 | namespace paimon::test { |
| 32 | +namespace { |
| 33 | + |
| 34 | +template <typename FloatingPoint, typename UInt> |
| 35 | +FloatingPoint FloatingPointFromBits(UInt bits) { |
| 36 | + static_assert(sizeof(FloatingPoint) == sizeof(UInt)); |
| 37 | + FloatingPoint value; |
| 38 | + std::memcpy(&value, &bits, sizeof(value)); |
| 39 | + return value; |
| 40 | +} |
| 41 | + |
| 42 | +} // namespace |
28 | 43 |
|
29 | 44 | class KeySerializerTest : public ::testing::Test { |
30 | 45 | protected: |
@@ -208,6 +223,30 @@ TEST_F(KeySerializerTest, SerializeAndDeserializeAllTypes) { |
208 | 223 | } |
209 | 224 | } |
210 | 225 |
|
| 226 | +TEST_F(KeySerializerTest, CanonicalizesFloatingPointNaN) { |
| 227 | + const float float_nan = FloatingPointFromBits<float>(uint32_t{0xffc12345}); |
| 228 | + const float canonical_float_nan = FloatingPointFromBits<float>(uint32_t{0x7fc00000}); |
| 229 | + ASSERT_OK_AND_ASSIGN( |
| 230 | + std::shared_ptr<Bytes> float_bytes, |
| 231 | + KeySerializer::SerializeKey(Literal(float_nan), arrow::float32(), pool_.get())); |
| 232 | + ASSERT_OK_AND_ASSIGN( |
| 233 | + std::shared_ptr<Bytes> canonical_float_bytes, |
| 234 | + KeySerializer::SerializeKey(Literal(canonical_float_nan), arrow::float32(), pool_.get())); |
| 235 | + ASSERT_EQ(std::string(float_bytes->data(), float_bytes->size()), |
| 236 | + std::string(canonical_float_bytes->data(), canonical_float_bytes->size())); |
| 237 | + |
| 238 | + const double double_nan = FloatingPointFromBits<double>(uint64_t{0xfff8123456789abc}); |
| 239 | + const double canonical_double_nan = FloatingPointFromBits<double>(uint64_t{0x7ff8000000000000}); |
| 240 | + ASSERT_OK_AND_ASSIGN( |
| 241 | + std::shared_ptr<Bytes> double_bytes, |
| 242 | + KeySerializer::SerializeKey(Literal(double_nan), arrow::float64(), pool_.get())); |
| 243 | + ASSERT_OK_AND_ASSIGN( |
| 244 | + std::shared_ptr<Bytes> canonical_double_bytes, |
| 245 | + KeySerializer::SerializeKey(Literal(canonical_double_nan), arrow::float64(), pool_.get())); |
| 246 | + ASSERT_EQ(std::string(double_bytes->data(), double_bytes->size()), |
| 247 | + std::string(canonical_double_bytes->data(), canonical_double_bytes->size())); |
| 248 | +} |
| 249 | + |
211 | 250 | TEST_F(KeySerializerTest, RejectsMalformedSerializedKeys) { |
212 | 251 | auto wrap = [this](const std::string& value) { |
213 | 252 | return MemorySlice::Wrap(std::make_shared<Bytes>(value, pool_.get())); |
|
0 commit comments