blob: 17ee33311e16e89a25813a96bc0f2deff2d68483 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "paimon/common/data/binary_row.h"
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <optional>
#include <set>
#include "gtest/gtest.h"
#include "paimon/common/data/binary_row_writer.h"
#include "paimon/common/data/serializer/binary_row_serializer.h"
#include "paimon/common/io/memory_segment_output_stream.h"
#include "paimon/common/memory/memory_segment.h"
#include "paimon/common/memory/memory_segment_utils.h"
#include "paimon/common/utils/date_time_utils.h"
#include "paimon/common/utils/decimal_utils.h"
#include "paimon/common/utils/serialization_utils.h"
#include "paimon/io/byte_array_input_stream.h"
#include "paimon/io/data_input_stream.h"
#include "paimon/memory/bytes.h"
#include "paimon/memory/memory_pool.h"
#include "paimon/status.h"
#include "paimon/testing/utils/testharness.h"
namespace paimon::test {
class BinaryRowTest : public testing::Test {
private:
void AssertTestWriterRow(const BinaryRow& row) {
ASSERT_EQ(row.GetString(0).ToString(), "1");
ASSERT_EQ(row.GetInt(8), 88);
ASSERT_EQ(row.GetShort(11), static_cast<int16_t>(292));
ASSERT_EQ(row.GetLong(10), 284);
ASSERT_EQ(row.GetByte(2), static_cast<char>(99));
ASSERT_EQ(row.GetDouble(6), static_cast<double>(87.1));
ASSERT_EQ(row.GetFloat(7), 26.1f);
ASSERT_TRUE(row.GetBoolean(1));
ASSERT_EQ(row.GetString(3).ToString(), "1234567");
ASSERT_EQ(row.GetString(5).ToString(), "12345678");
ASSERT_EQ(row.GetString(9).ToString(), "啦啦啦啦啦我是快乐的粉刷匠");
ASSERT_EQ(row.GetString(9).HashCode(),
BinaryString::FromString("啦啦啦啦啦我是快乐的粉刷匠", GetDefaultPool().get())
.HashCode());
ASSERT_TRUE(row.IsNullAt(12));
}
};
TEST_F(BinaryRowTest, TestBasic) {
// consider header 1 byte.
ASSERT_EQ(BinaryRow(0).GetFixedLengthPartSize(), 8);
ASSERT_EQ(BinaryRow(1).GetFixedLengthPartSize(), 16);
ASSERT_EQ(BinaryRow(65).GetFixedLengthPartSize(), 536);
ASSERT_EQ(BinaryRow(128).GetFixedLengthPartSize(), 1048);
auto pool = GetDefaultPool();
std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes(100, pool.get());
MemorySegment segment = MemorySegment::Wrap(bytes);
BinaryRow row(2);
row.PointTo(segment, 10, 48);
row.SetInt(0, 5);
row.SetDouble(1, 5.8);
ASSERT_EQ(5, row.GetInt(0));
ASSERT_EQ(static_cast<double>(5.8), row.GetDouble(1));
row.Clear();
ASSERT_EQ(0, row.HashCode());
std::shared_ptr<Bytes> bytes1 = Bytes::AllocateBytes(100, pool.get());
MemorySegment segment1 = MemorySegment::Wrap(bytes1);
row.PointTo(segment1, 0, 20);
row.SetInt(0, 5);
ASSERT_EQ(5, row.GetInt(0));
}
TEST_F(BinaryRowTest, TestSetAndGet) {
auto pool = GetDefaultPool();
std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes(100, pool.get());
MemorySegment segment = MemorySegment::Wrap(bytes);
BinaryRow row(9);
row.PointTo(segment, 20, 80);
row.SetNullAt(0);
row.SetInt(1, 11);
row.SetLong(2, 22);
row.SetDouble(3, 33);
row.SetBoolean(4, true);
row.SetShort(5, static_cast<int16_t>(55));
row.SetByte(6, static_cast<char>(66));
row.SetFloat(7, static_cast<float>(77));
ASSERT_EQ(row.GetInt(1), 11);
ASSERT_TRUE(row.IsNullAt(0));
ASSERT_EQ(row.GetShort(5), static_cast<int16_t>(55));
ASSERT_EQ(row.GetLong(2), 22L);
ASSERT_TRUE(row.GetBoolean(4));
ASSERT_EQ(row.GetByte(6), static_cast<char>(66));
ASSERT_EQ(row.GetFloat(7), static_cast<float>(77));
ASSERT_EQ(row.GetDouble(3), static_cast<double>(33));
}
TEST_F(BinaryRowTest, TestHeaderSize) {
ASSERT_EQ(BinaryRow::CalculateBitSetWidthInBytes(56), 8);
ASSERT_EQ(BinaryRow::CalculateBitSetWidthInBytes(57), 16);
ASSERT_EQ(BinaryRow::CalculateBitSetWidthInBytes(120), 16);
ASSERT_EQ(BinaryRow::CalculateBitSetWidthInBytes(121), 24);
}
TEST_F(BinaryRowTest, TestWriter) {
auto pool = GetDefaultPool();
int32_t arity = 13;
BinaryRow row(arity);
BinaryRowWriter writer(&row, 20, pool.get());
writer.WriteString(0, BinaryString::FromString("1", pool.get()));
writer.WriteString(3, BinaryString::FromString("1234567", pool.get()));
writer.WriteString(5, BinaryString::FromString("12345678", pool.get()));
writer.WriteString(9, BinaryString::FromString("啦啦啦啦啦我是快乐的粉刷匠", pool.get()));
writer.WriteBoolean(1, true);
writer.WriteByte(2, static_cast<char>(99));
writer.WriteDouble(6, 87.1);
writer.WriteFloat(7, 26.1f);
writer.WriteInt(8, 88);
writer.WriteLong(10, 284);
writer.WriteShort(11, static_cast<int16_t>(292));
writer.SetNullAt(12);
writer.Complete();
AssertTestWriterRow(row);
// test copy
auto copied1 = row.Copy(pool.get());
AssertTestWriterRow(copied1);
ASSERT_EQ(row, copied1);
// test copy
BinaryRow copied2(arity);
row.Copy(&copied2, pool.get());
AssertTestWriterRow(copied2);
ASSERT_EQ(row, copied2);
}
TEST_F(BinaryRowTest, TestWriteString) {
auto pool = GetDefaultPool();
{
// little byte[]
BinaryRow row(1);
BinaryRowWriter writer(&row, 0, pool.get());
char chars[2];
chars[0] = static_cast<char>(0xFFFF);
chars[1] = 0;
writer.WriteString(0, BinaryString::FromString(std::string(chars, 2), pool.get()));
writer.Complete();
std::string str = row.GetString(0).ToString();
ASSERT_EQ(2, str.length());
ASSERT_EQ(str[0], chars[0]);
ASSERT_EQ(str[1], chars[1]);
}
{
// big byte[]
std::string str = "啦啦啦啦啦我是快乐的粉刷匠";
BinaryRow row(2);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteString(0, BinaryString::FromString(str, pool.get()));
writer.WriteString(1, BinaryString::FromBytes(Bytes::AllocateBytes(str, pool.get())));
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), str);
ASSERT_EQ(row.GetString(1).ToString(), str);
}
}
TEST_F(BinaryRowTest, TestWriteBytes) {
auto pool = GetDefaultPool();
{
BinaryRow row(1);
BinaryRowWriter writer(&row, 0, pool.get());
std::string str = "啦啦啦啦啦我是快乐的粉刷匠";
Bytes bytes(str, pool.get());
writer.WriteBytes(0, bytes);
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), str);
}
{
BinaryRow row(1);
BinaryRowWriter writer(&row, 0, pool.get());
std::string str = "啦";
Bytes bytes(str, pool.get());
writer.WriteBytes(0, bytes);
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), str);
}
}
TEST_F(BinaryRowTest, TestReuseWriter) {
auto pool = GetDefaultPool();
BinaryRow row(2);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteString(0, BinaryString::FromString("01234567", pool.get()));
writer.WriteString(1, BinaryString::FromString("012345678", pool.get()));
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), "01234567");
ASSERT_EQ(row.GetString(1).ToString(), "012345678");
writer.Reset();
writer.WriteString(0, BinaryString::FromString("1", pool.get()));
writer.WriteString(1, BinaryString::FromString("0123456789", pool.get()));
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), "1");
ASSERT_EQ(row.GetString(1).ToString(), "0123456789");
}
TEST_F(BinaryRowTest, TestAnyNull) {
auto pool = GetDefaultPool();
{
BinaryRow row(3);
BinaryRowWriter writer(&row, 0, pool.get());
ASSERT_FALSE(row.AnyNull());
// test header should not compute by anyNull
row.SetRowKind(RowKind::UpdateBefore());
ASSERT_FALSE(row.AnyNull());
writer.SetNullAt(2);
ASSERT_TRUE(row.AnyNull());
writer.SetNullAt(0);
ASSERT_TRUE(row.AnyNull({0, 1, 2}));
ASSERT_FALSE(row.AnyNull({1}));
writer.SetNullAt(1);
ASSERT_TRUE(row.AnyNull());
}
int32_t num_fields = 80;
for (int32_t i = 0; i < num_fields; i++) {
BinaryRow row(num_fields);
BinaryRowWriter writer(&row, 0, pool.get());
row.SetRowKind(RowKind::Delete());
ASSERT_FALSE(row.AnyNull());
writer.SetNullAt(i);
ASSERT_TRUE(row.AnyNull());
}
}
TEST_F(BinaryRowTest, TestSingleSegmentBinaryRowHashCode) {
auto pool = GetDefaultPool();
int64_t seed = DateTimeUtils::GetCurrentUTCTimeUs();
std::srand(seed);
// test hash stabilization
BinaryRow row(13);
BinaryRowWriter writer(&row, 0, pool.get());
for (int32_t i = 0; i < 99; i++) {
writer.Reset();
writer.WriteString(
0, BinaryString::FromString("" + std::to_string(static_cast<int32_t>(std::rand())),
pool.get()));
writer.WriteString(3, BinaryString::FromString("01234567", pool.get()));
writer.WriteString(5, BinaryString::FromString("012345678", pool.get()));
writer.WriteString(9, BinaryString::FromString("啦啦啦啦啦我是快乐的粉刷匠", pool.get()));
writer.WriteBoolean(1, true);
writer.WriteByte(2, static_cast<char>(99));
writer.WriteDouble(6, 87.1);
writer.WriteFloat(7, 26.1f);
writer.WriteInt(8, 88);
writer.WriteLong(10, 284);
writer.WriteShort(11, static_cast<int16_t>(292));
writer.SetNullAt(12);
writer.Complete();
BinaryRow copy = row.Copy(pool.get());
ASSERT_EQ(copy.HashCode(), row.HashCode()) << "seed: " << seed << ", idx: " << i;
}
// test hash distribution
int32_t count = 999999;
std::set<int32_t> hash_codes;
for (int32_t i = 0; i < count; i++) {
row.SetInt(8, i);
hash_codes.insert(row.HashCode());
}
ASSERT_EQ(hash_codes.size(), count);
hash_codes.clear();
BinaryRow row2(1);
BinaryRowWriter writer2(&row2, 0, pool.get());
for (int32_t i = 0; i < count; i++) {
writer2.Reset();
writer2.WriteString(0, BinaryString::FromString(
"啦啦啦啦啦我是快乐的粉刷匠" + std::to_string(i), pool.get()));
writer2.Complete();
hash_codes.insert(row2.HashCode());
}
ASSERT_GT(hash_codes.size(), static_cast<size_t>(count * 0.997));
}
TEST_F(BinaryRowTest, TestHeader) {
auto pool = GetDefaultPool();
BinaryRow row(2);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteInt(0, 10);
writer.SetNullAt(1);
writer.WriteRowKind(RowKind::UpdateBefore());
writer.Complete();
BinaryRow new_row = row.Copy(pool.get());
ASSERT_EQ(new_row, row);
ASSERT_EQ(new_row.GetRowKind().value(), RowKind::UpdateBefore());
new_row.SetRowKind(RowKind::Delete());
ASSERT_EQ(new_row.GetRowKind().value(), RowKind::Delete());
}
TEST_F(BinaryRowTest, TestDefaultRowKind) {
auto pool = GetDefaultPool();
BinaryRow row(1);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteInt(0, 10);
writer.Complete();
ASSERT_EQ(row.GetRowKind().value(), RowKind::Insert());
}
TEST_F(BinaryRowTest, TestBinary) {
auto pool = GetDefaultPool();
BinaryRow row(2);
BinaryRowWriter writer(&row, 0, pool.get());
char chars1[3] = {1, -1, 5};
char chars2[8] = {1, -1, 5, 5, 1, 5, 1, 5};
std::string str1(chars1, 3);
std::string str2(chars2, 8);
Bytes bytes1(str1, pool.get());
Bytes bytes2(str2, pool.get());
writer.WriteBinary(0, bytes1);
writer.WriteBinary(1, bytes2);
writer.Complete();
ASSERT_EQ(*row.GetBinary(0), bytes1);
ASSERT_EQ(*row.GetBinary(1), bytes2);
}
TEST_F(BinaryRowTest, TestCompatibleWithJava) {
auto pool = GetDefaultPool();
{
int32_t arity = 1;
BinaryRow row(arity);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteString(0, BinaryString::FromString("Alice2", pool.get()));
writer.Complete();
ASSERT_EQ(row.GetString(0).ToString(), "Alice2");
auto bytes = SerializationUtils::SerializeBinaryRow(row, pool.get());
std::string bytes_view(bytes->data(), bytes->size());
std::vector<uint8_t> expect_bytes = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 65, 108, 105, 99, 101, 50, 0, 134};
std::string expect_view(reinterpret_cast<char*>(expect_bytes.data()), expect_bytes.size());
ASSERT_EQ(bytes_view, expect_view);
ASSERT_OK_AND_ASSIGN(auto de_row, SerializationUtils::DeserializeBinaryRow(bytes));
ASSERT_EQ(1, de_row.GetFieldCount());
ASSERT_EQ(de_row.GetString(0).ToString(), "Alice2");
}
{
int32_t arity = 1;
BinaryRow row(arity);
BinaryRowWriter writer(&row, 0, pool.get());
writer.WriteInt(0, 18);
writer.Complete();
ASSERT_EQ(row.GetInt(0), 18);
auto bytes = SerializationUtils::SerializeBinaryRow(row, pool.get());
std::string bytes_view(bytes->data(), bytes->size());
std::vector<uint8_t> expect_bytes = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
0, 0, 18, 0, 0, 0, 0, 0, 0, 0};
std::string expect_view(reinterpret_cast<char*>(expect_bytes.data()), expect_bytes.size());
ASSERT_EQ(bytes_view, expect_view);
ASSERT_OK_AND_ASSIGN(auto de_row, SerializationUtils::DeserializeBinaryRow(bytes));
ASSERT_EQ(1, de_row.GetFieldCount());
ASSERT_EQ(de_row.GetInt(0), 18);
}
}
TEST_F(BinaryRowTest, TestZeroOutPaddingString) {
srand(static_cast<unsigned>(time(nullptr)));
auto pool = GetDefaultPool();
int32_t bytes_size = 1024;
std::shared_ptr<Bytes> bytes = Bytes::AllocateBytes(1024, pool.get());
BinaryRow row(1);
BinaryRowWriter writer(&row, 0, pool.get());
writer.Reset();
for (int32_t i = 0; i < bytes_size; i++) {
(*bytes)[i] = paimon::test::RandomNumber(0, 255);
}
writer.WriteBinary(0, *bytes);
writer.Reset();
writer.WriteString(0, BinaryString::FromString("wahahah", pool.get()));
writer.Complete();
int32_t hash1 = row.HashCode();
writer.Reset();
for (int32_t i = 0; i < bytes_size; i++) {
(*bytes)[i] = paimon::test::RandomNumber(0, 255);
}
writer.WriteBinary(0, *bytes);
writer.Reset();
writer.WriteString(0, BinaryString::FromString("wahahah", pool.get()));
writer.Complete();
int32_t hash2 = row.HashCode();
ASSERT_EQ(hash2, hash1);
}
TEST_F(BinaryRowTest, TestWriteTimestampAndDecimal) {
auto pool = GetDefaultPool();
BinaryRow row(7);
BinaryRowWriter writer(&row, 0, pool.get());
// timestamp with millis precision, compact
Timestamp timestamp(1723535714123ll, 0);
writer.WriteTimestamp(0, timestamp, Timestamp::MILLIS_PRECISION);
// timestamp with default precision, not compact
Timestamp timestamp1(1723535713000ll, 1234);
writer.WriteTimestamp(1, timestamp1, Timestamp::DEFAULT_PRECISION);
// 1234.56, compact, precision 6, scale 2
Decimal decimal(6, 2, 123456);
writer.WriteDecimal(2, decimal, 6);
// 123456789987654321.45678, not compact, precision 23, scale 5
Decimal decimal3(23, 5, DecimalUtils::StrToInt128("12345678998765432145678").value());
writer.WriteDecimal(3, decimal3, 23);
// 0, not compact, precision 27, scale 4
Decimal decimal4(27, 4, 0);
writer.WriteDecimal(4, decimal4, 27);
// -1234.56, compact, precision 6, scale 2
Decimal decimal5(6, 2, -123456);
writer.WriteDecimal(5, decimal5, 6);
// -123456789987654321.45678, not compact, precision 23, scale 5
Decimal decimal6(23, 5, DecimalUtils::StrToInt128("-12345678998765432145678").value());
writer.WriteDecimal(6, decimal6, 23);
writer.Complete();
// test serialize
std::vector<uint8_t> expected = {
0, 0, 0, 0, 0, 0, 0, 0, 75, 231, 187, 74, 145, 1, 0, 0, 210, 4, 0, 0,
64, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 10, 0, 0, 0, 72, 0, 0, 0,
1, 0, 0, 0, 88, 0, 0, 0, 192, 29, 254, 255, 255, 255, 255, 255, 10, 0, 0, 0,
104, 0, 0, 0, 232, 226, 187, 74, 145, 1, 0, 0, 2, 157, 66, 182, 167, 42, 157, 199,
7, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 253, 98, 189, 73, 88, 213, 98, 56, 248, 242, 0, 0, 0, 0, 0, 0};
auto result_bytes = row.ToBytes(pool.get());
std::vector<uint8_t> result(result_bytes->size(), 0);
memcpy(result.data(), result_bytes->data(), result_bytes->size());
ASSERT_EQ(expected, result);
// test hash code
ASSERT_EQ(0x773cf266, row.HashCode());
ASSERT_EQ(timestamp, row.GetTimestamp(0, Timestamp::MILLIS_PRECISION));
ASSERT_EQ(timestamp1, row.GetTimestamp(1, Timestamp::DEFAULT_PRECISION));
ASSERT_EQ(decimal, row.GetDecimal(2, 6, 2));
ASSERT_EQ(decimal3, row.GetDecimal(3, 23, 5));
ASSERT_EQ(decimal4, row.GetDecimal(4, 27, 4));
ASSERT_EQ(decimal5, row.GetDecimal(5, 6, 2));
ASSERT_EQ(decimal6, row.GetDecimal(6, 23, 5));
}
TEST_F(BinaryRowTest, TestWriteTimestampAndDecimalWithNull) {
auto pool = GetDefaultPool();
BinaryRow row(5);
BinaryRowWriter writer(&row, 0, pool.get());
writer.Reset();
// timestamp with max precision, compact
writer.WriteTimestamp(0, std::nullopt, Timestamp::MAX_PRECISION);
// timestamp with MAX_PRECISION, compact
Timestamp timestamp(1723535713567ll, 1234);
writer.WriteTimestamp(1, timestamp, Timestamp::MAX_PRECISION);
// decimal precision 27, not compact
writer.WriteDecimal(2, std::nullopt, 27);
// -123456789987654321.45678, not compact, precision 23, scale 5
Decimal decimal(23, 5, DecimalUtils::StrToInt128("-12345678998765432145678").value());
writer.WriteDecimal(3, decimal, 23);
writer.SetNullAt(4);
writer.Complete();
// test serialize
std::vector<uint8_t> expected = {
0, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 210, 4, 0, 0, 56, 0, 0, 0,
0, 0, 0, 0, 64, 0, 0, 0, 10, 0, 0, 0, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 31, 229, 187, 74, 145, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 253, 98, 189, 73, 88, 213, 98, 56, 248, 242, 0, 0, 0, 0, 0, 0};
auto result_bytes = row.ToBytes(pool.get());
std::vector<uint8_t> result(result_bytes->size(), 0);
memcpy(result.data(), result_bytes->data(), result_bytes->size());
ASSERT_EQ(expected, result);
// test hash code
ASSERT_EQ(0xedbc7d65, row.HashCode());
// test value in binary row
ASSERT_TRUE(row.IsNullAt(0));
ASSERT_EQ(timestamp, row.GetTimestamp(1, Timestamp::MAX_PRECISION));
ASSERT_TRUE(row.IsNullAt(2));
ASSERT_EQ(decimal, row.GetDecimal(3, 23, 5));
ASSERT_TRUE(row.IsNullAt(4));
}
TEST_F(BinaryRowTest, TestBinaryRowSerializer) {
srand(static_cast<unsigned>(time(nullptr)));
auto pool = GetDefaultPool();
BinaryRow row(3);
BinaryRowWriter writer(&row, /*initial_size=*/1024, pool.get());
writer.WriteInt(0, paimon::test::RandomNumber(0, 2000000));
int32_t str_size = 1024;
std::string test_string1, test_string2;
test_string1.reserve(str_size);
test_string2.reserve(str_size);
for (int32_t j = 0; j < str_size; j++) {
test_string1 += static_cast<char>(paimon::test::RandomNumber(0, 25) + 'a');
test_string2 += static_cast<char>(paimon::test::RandomNumber(0, 25) + 'a');
}
writer.WriteStringView(1, std::string_view{test_string1});
writer.WriteStringView(2, std::string_view{test_string2});
writer.Complete();
BinaryRowSerializer row_serializer(3, pool);
MemorySegmentOutputStream out(MemorySegmentOutputStream::DEFAULT_SEGMENT_SIZE, pool);
ASSERT_OK(row_serializer.Serialize(row, &out));
PAIMON_UNIQUE_PTR<Bytes> bytes_serialize =
MemorySegmentUtils::CopyToBytes(out.Segments(), 0, out.CurrentSize(), pool.get());
ASSERT_GE(bytes_serialize->size(), sizeof(int32_t) + test_string1.size() + test_string2.size());
DataInputStream input(
std::make_shared<ByteArrayInputStream>(bytes_serialize->data(), bytes_serialize->size()));
ASSERT_OK_AND_ASSIGN(auto de_row, row_serializer.Deserialize(&input));
ASSERT_EQ(de_row, row);
ASSERT_EQ(de_row.GetString(1).ToString(), test_string1);
ASSERT_EQ(de_row.GetString(2).ToString(), test_string2);
}
} // namespace paimon::test