diff --git a/presto-native-execution/presto_cpp/presto_protocol/Base64Util.cpp b/presto-native-execution/presto_cpp/presto_protocol/Base64Util.cpp index 1c123cf267f00..07b588632b38c 100644 --- a/presto-native-execution/presto_cpp/presto_protocol/Base64Util.cpp +++ b/presto-native-execution/presto_cpp/presto_protocol/Base64Util.cpp @@ -38,6 +38,8 @@ struct ByteStream { template T read() { + // Directly reading int128 values is not yet supported in ByteStream. + static_assert(sizeof(T) <= sizeof(uint64_t)); T value = *reinterpret_cast(data_ + offset_); offset_ += sizeof(T); return value; @@ -59,6 +61,16 @@ struct ByteStream { int32_t offset_; }; +// ByteStream::read specialization for int128_t +template <> +velox::int128_t ByteStream::read() { + // Fetching int128_t value by reading two 64-bit blocks rather than one + // 128-bit block to avoid general protection exception. + auto low = read(); + auto high = read(); + return velox::buildInt128(high, low); +} + velox::BufferPtr readNulls(int32_t count, ByteStream& stream, velox::memory::MemoryPool* pool) { bool mayHaveNulls = stream.read(); diff --git a/presto-native-execution/presto_cpp/presto_protocol/tests/Base64Test.cpp b/presto-native-execution/presto_cpp/presto_protocol/tests/Base64Test.cpp index c2a41da0dfc25..9e4c61dcd671a 100644 --- a/presto-native-execution/presto_cpp/presto_protocol/tests/Base64Test.cpp +++ b/presto-native-execution/presto_cpp/presto_protocol/tests/Base64Test.cpp @@ -82,6 +82,81 @@ TEST_F(Base64Test, singleTinyint) { ASSERT_EQ(1, intVector->valueAt(0)); } +TEST_F(Base64Test, simpleLongDecimal) { + // Note: string values of block representations in following test cases (e.g., + // "data0") can be obtained by reading the actual block representations of + // corresponding unscaled values in running services of Prestissimo. + + // Unscaled value = 0 + const std::string data0 = + "DAAAAElOVDEyOF9BUlJBWQEAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; + auto vector0 = readBlock(LONG_DECIMAL(24, 2), data0, pool_.get()); + + ASSERT_EQ(TypeKind::LONG_DECIMAL, vector0->typeKind()); + ASSERT_EQ(1, vector0->size()); + ASSERT_FALSE(vector0->isNullAt(0)); + + auto decimalVector0 = + vector0->as>(); + ASSERT_EQ(UnscaledLongDecimal(0), decimalVector0->valueAt(0)); + + // Unscaled value = 100 + const std::string data1 = + "DAAAAElOVDEyOF9BUlJBWQEAAAAAZAAAAAAAAAAAAAAAAAAAAA=="; + auto vector1 = readBlock(LONG_DECIMAL(24, 2), data1, pool_.get()); + + ASSERT_EQ(TypeKind::LONG_DECIMAL, vector1->typeKind()); + ASSERT_EQ(1, vector1->size()); + ASSERT_FALSE(vector1->isNullAt(0)); + + auto decimalVector1 = + vector1->as>(); + ASSERT_EQ(UnscaledLongDecimal(100), decimalVector1->valueAt(0)); + + // Unscaled value = -100 + const std::string data2 = + "DAAAAElOVDEyOF9BUlJBWQEAAAAAZAAAAAAAAAAAAAAAAAAAgA=="; + auto vector2 = readBlock(LONG_DECIMAL(24, 2), data2, pool_.get()); + + ASSERT_EQ(TypeKind::LONG_DECIMAL, vector2->typeKind()); + ASSERT_EQ(1, vector2->size()); + ASSERT_FALSE(vector2->isNullAt(0)); + + auto decimalVector2 = + vector2->as>(); + ASSERT_EQ(UnscaledLongDecimal(-100), decimalVector2->valueAt(0)); + + // Unscaled value = 10^20 + const std::string data3 = + "DAAAAElOVDEyOF9BUlJBWQEAAAAAAAAQYy1ex2sFAAAAAAAAAA=="; + auto vector3 = readBlock(LONG_DECIMAL(24, 2), data3, pool_.get()); + + ASSERT_EQ(TypeKind::LONG_DECIMAL, vector3->typeKind()); + ASSERT_EQ(1, vector3->size()); + ASSERT_FALSE(vector3->isNullAt(0)); + + auto decimalVector3 = + vector3->as>(); + ASSERT_EQ( + UnscaledLongDecimal(DecimalUtil::kPowersOfTen[20]), + decimalVector3->valueAt(0)); + + // Unscaled value = -10^20 + const std::string data4 = + "DAAAAElOVDEyOF9BUlJBWQEAAAAAAAAQYy1ex2sFAAAAAAAAgA=="; + auto vector4 = readBlock(LONG_DECIMAL(24, 2), data4, pool_.get()); + + ASSERT_EQ(TypeKind::LONG_DECIMAL, vector4->typeKind()); + ASSERT_EQ(1, vector4->size()); + ASSERT_FALSE(vector4->isNullAt(0)); + + auto decimalVector4 = + vector4->as>(); + ASSERT_EQ( + UnscaledLongDecimal(-DecimalUtil::kPowersOfTen[20]), + decimalVector4->valueAt(0)); +} + TEST_F(Base64Test, singleString) { std::string data = "DgAAAFZBUklBQkxFX1dJRFRIAQAAAAoAAAAACgAAADIwMTktMTEtMTA=";