This is an automated email from the ASF dual-hosted git repository.
airborne pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 52d649ff5fc [test](inverted index) add more unit tests for
InvertedIndexFileWriter exception scenarios (#52016)
52d649ff5fc is described below
commit 52d649ff5fc19c3990c21a4901a67eb62b7feae3
Author: airborne12 <[email protected]>
AuthorDate: Sat Jun 21 20:03:27 2025 +0800
[test](inverted index) add more unit tests for InvertedIndexFileWriter
exception scenarios (#52016)
add more unit tests for InvertedIndexFileWriter exception scenarios
---
.../segment_v2/inverted_index_writer_test.cpp | 561 +++++++++++++++++++++
1 file changed, 561 insertions(+)
diff --git a/be/test/olap/rowset/segment_v2/inverted_index_writer_test.cpp
b/be/test/olap/rowset/segment_v2/inverted_index_writer_test.cpp
index ae3551a60b7..37b7e8c5a5b 100644
--- a/be/test/olap/rowset/segment_v2/inverted_index_writer_test.cpp
+++ b/be/test/olap/rowset/segment_v2/inverted_index_writer_test.cpp
@@ -825,4 +825,565 @@ TEST_F(InvertedIndexWriterTest,
CompareUnicodeStringWriteResults) {
}
}
+// Test case for error handling in inverted index file writer
+TEST_F(InvertedIndexWriterTest, ErrorHandlingInFileWriter) {
+ auto tablet_schema = create_schema();
+
+ // Create index meta
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(1); // c2 column id
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_error_handling", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ // Create index file writer with error conditions
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_error_handling", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for column c2
+ const TabletColumn& column = tablet_schema->column(1); // c2 is the second
column
+ ASSERT_NE(&column, nullptr);
+ std::unique_ptr<Field> field(FieldFactory::create(column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Test with empty values array to trigger certain error paths
+ std::vector<Slice> empty_values;
+ status = column_writer->add_values("c2", empty_values.data(), 0);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Test with very large strings that might trigger ignore_above behavior
+ std::vector<Slice> large_values;
+ std::string large_string(100000, 'a'); // Very large string
+ large_values.push_back(Slice(large_string));
+ status = column_writer->add_values("c2", large_values.data(),
large_values.size());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for array values with mixed null and non-null elements
+TEST_F(InvertedIndexWriterTest, ArrayValuesWithNulls) {
+ // Create TabletSchema with array column (reference
inverted_index_array_test.cpp)
+ TabletSchemaSPtr tablet_schema = std::make_shared<TabletSchema>();
+ TabletSchemaPB tablet_schema_pb;
+ tablet_schema_pb.set_keys_type(DUP_KEYS);
+ tablet_schema->init_from_pb(tablet_schema_pb);
+
+ TabletColumn array_column;
+ array_column.set_name("arr1");
+ array_column.set_type(FieldType::OLAP_FIELD_TYPE_ARRAY);
+ array_column.set_length(0);
+ array_column.set_index_length(0);
+ array_column.set_is_nullable(false);
+
+ TabletColumn child_column;
+ child_column.set_name("arr_sub_string");
+ child_column.set_type(FieldType::OLAP_FIELD_TYPE_STRING);
+ child_column.set_length(INT_MAX);
+ array_column.add_sub_column(child_column);
+ tablet_schema->append_column(array_column);
+
+ // Create index meta for array
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(0); // array column id
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_array_nulls", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_array_nulls", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for array column
+ std::unique_ptr<Field> field(FieldFactory::create(array_column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Construct arrays with mixed null and non-null elements (reference
inverted_index_array_test.cpp)
+ // Array 1: ["apple", null, "cherry"]
+ // Array 2: ["banana"]
+ // Array 3: [null, "date"]
+ vectorized::Array a1, a2, a3;
+ a1.push_back(vectorized::Field::create_field<TYPE_STRING>("apple"));
+ a1.push_back(vectorized::Field()); // null element
+ a1.push_back(vectorized::Field::create_field<TYPE_STRING>("cherry"));
+
+ a2.push_back(vectorized::Field::create_field<TYPE_STRING>("banana"));
+
+ a3.push_back(vectorized::Field()); // null element
+ a3.push_back(vectorized::Field::create_field<TYPE_STRING>("date"));
+
+ // Construct array type: DataTypeArray(DataTypeNullable(DataTypeString))
+ vectorized::DataTypePtr inner_string_type =
std::make_shared<vectorized::DataTypeNullable>(
+ std::make_shared<vectorized::DataTypeString>());
+ vectorized::DataTypePtr array_type =
+ std::make_shared<vectorized::DataTypeArray>(inner_string_type);
+ vectorized::MutableColumnPtr col = array_type->create_column();
+ col->insert(vectorized::Field::create_field<TYPE_ARRAY>(a1));
+ col->insert(vectorized::Field::create_field<TYPE_ARRAY>(a2));
+ col->insert(vectorized::Field::create_field<TYPE_ARRAY>(a3));
+ vectorized::ColumnPtr column_array = std::move(col);
+ vectorized::ColumnWithTypeAndName type_and_name(column_array, array_type,
"arr1");
+
+ // Put the array column into the Block
+ vectorized::Block block;
+ block.insert(type_and_name);
+
+ // Use OlapBlockDataConvertor to convert (reference
inverted_index_array_test.cpp)
+ vectorized::OlapBlockDataConvertor convertor(tablet_schema.get(), {0});
+ convertor.set_source_content(&block, 0, block.rows());
+ auto [st, accessor] = convertor.convert_column_data(0);
+ EXPECT_EQ(st, Status::OK());
+
+ // The conversion result is an array of 4 pointers:
+ // [0]: Total number of elements (elem_cnt)
+ // [1]: Offsets array pointer
+ // [2]: Nested item data pointer
+ // [3]: Nested nullmap pointer
+ const auto* data_ptr = reinterpret_cast<const
uint64_t*>(accessor->get_data());
+ const auto* offsets_ptr = reinterpret_cast<const uint8_t*>(data_ptr[1]);
+ const void* item_data = reinterpret_cast<const void*>(data_ptr[2]);
+ const auto* item_nullmap = reinterpret_cast<const uint8_t*>(data_ptr[3]);
+
+ // Get the length of the subfield
+ auto field_size = field->get_sub_field(0)->size();
+
+ // Call the inverted index writing interface
+ status = column_writer->add_array_values(field_size, item_data,
item_nullmap, offsets_ptr,
+ block.rows());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add array nulls
+ const auto* null_map = accessor->get_nullmap();
+ status = column_writer->add_array_nulls(null_map, block.rows());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for numeric array values with error conditions
+TEST_F(InvertedIndexWriterTest, NumericArrayWithErrorConditions) {
+ // Create TabletSchema with numeric array column (reference
inverted_index_array_test.cpp)
+ TabletSchemaSPtr tablet_schema = std::make_shared<TabletSchema>();
+ TabletSchemaPB tablet_schema_pb;
+ tablet_schema_pb.set_keys_type(DUP_KEYS);
+ tablet_schema->init_from_pb(tablet_schema_pb);
+
+ TabletColumn array_column;
+ array_column.set_name("arr_num");
+ array_column.set_type(FieldType::OLAP_FIELD_TYPE_ARRAY);
+ array_column.set_length(0);
+ array_column.set_index_length(0);
+ array_column.set_is_nullable(false);
+
+ TabletColumn child_column;
+ child_column.set_name("arr_sub_int");
+ child_column.set_type(FieldType::OLAP_FIELD_TYPE_INT);
+ child_column.set_length(4);
+ array_column.add_sub_column(child_column);
+ tablet_schema->append_column(array_column);
+
+ // Create index meta for numeric BKD
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(0); // array column id
+
+ // Set index properties for BKD index
+ auto* properties = index_meta_pb->mutable_properties();
+ (*properties)["type"] = "bkd";
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_numeric_array_error", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_numeric_array_error", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for array column
+ std::unique_ptr<Field> field(FieldFactory::create(array_column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Construct numeric arrays (reference inverted_index_array_test.cpp)
+ // Array 1: [42, 100]
+ // Array 2: [200, 300, 400]
+ vectorized::DataTypePtr inner_int_type =
std::make_shared<vectorized::DataTypeInt32>();
+ vectorized::DataTypePtr array_type =
+ std::make_shared<vectorized::DataTypeArray>(inner_int_type);
+ vectorized::MutableColumnPtr col = array_type->create_column();
+
+ // Array 1: [42, 100]
+ {
+ vectorized::Array arr;
+ arr.push_back(vectorized::Field::create_field<TYPE_INT>(42));
+ arr.push_back(vectorized::Field::create_field<TYPE_INT>(100));
+ col->insert(vectorized::Field::create_field<TYPE_ARRAY>(arr));
+ }
+
+ // Array 2: [200, 300, 400]
+ {
+ vectorized::Array arr;
+ arr.push_back(vectorized::Field::create_field<TYPE_INT>(200));
+ arr.push_back(vectorized::Field::create_field<TYPE_INT>(300));
+ arr.push_back(vectorized::Field::create_field<TYPE_INT>(400));
+ col->insert(vectorized::Field::create_field<TYPE_ARRAY>(arr));
+ }
+
+ vectorized::ColumnPtr column_array = std::move(col);
+ vectorized::ColumnWithTypeAndName type_and_name(column_array, array_type,
"arr_num");
+
+ // Put the array column into the Block
+ vectorized::Block block;
+ block.insert(type_and_name);
+
+ // Use OlapBlockDataConvertor to convert (reference
inverted_index_array_test.cpp)
+ vectorized::OlapBlockDataConvertor convertor(tablet_schema.get(), {0});
+ convertor.set_source_content(&block, 0, block.rows());
+ auto [st, accessor] = convertor.convert_column_data(0);
+ EXPECT_EQ(st, Status::OK());
+
+ // The conversion result is an array of 4 pointers:
+ // [0]: Total number of elements (elem_cnt)
+ // [1]: Offsets array pointer
+ // [2]: Nested item data pointer
+ // [3]: Nested nullmap pointer
+ const auto* data_ptr = reinterpret_cast<const
uint64_t*>(accessor->get_data());
+ const auto* offsets_ptr = reinterpret_cast<const uint8_t*>(data_ptr[1]);
+ const void* item_data = reinterpret_cast<const void*>(data_ptr[2]);
+ const auto* item_nullmap = reinterpret_cast<const uint8_t*>(data_ptr[3]);
+
+ // Get the length of the subfield
+ auto field_size = field->get_sub_field(0)->size();
+
+ // Call the inverted index writing interface
+ status = column_writer->add_array_values(field_size, item_data,
item_nullmap, offsets_ptr,
+ block.rows());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add array nulls
+ const auto* null_map = accessor->get_nullmap();
+ status = column_writer->add_array_nulls(null_map, block.rows());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Test with zero count to trigger specific branch
+ status = column_writer->add_array_values(field_size, item_data, nullptr,
offsets_ptr, 0);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for copy file error handling
+TEST_F(InvertedIndexWriterTest, CopyFileErrorHandling) {
+ auto tablet_schema = create_schema();
+
+ // Create index meta
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(1); // c2 column id
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_copy_error", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_copy_error", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for column c2
+ const TabletColumn& column = tablet_schema->column(1); // c2 is the second
column
+ ASSERT_NE(&column, nullptr);
+ std::unique_ptr<Field> field(FieldFactory::create(column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add some values to create index files
+ std::vector<Slice> values = {Slice("test1"), Slice("test2"),
Slice("test3")};
+ status = column_writer->add_values("c2", values.data(), values.size());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for Collection value processing
+TEST_F(InvertedIndexWriterTest, CollectionValueProcessing) {
+ auto tablet_schema = create_schema();
+
+ // Create index meta
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(1); // c2 column id
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_collection", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_collection", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for column c2
+ const TabletColumn& column = tablet_schema->column(1); // c2 is the second
column
+ ASSERT_NE(&column, nullptr);
+ std::unique_ptr<Field> field(FieldFactory::create(column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Create collection values for testing
+ std::vector<std::string> test_strings = {"apple", "banana", "cherry"};
+ std::vector<Slice> slices;
+ for (const auto& s : test_strings) {
+ slices.emplace_back(s);
+ }
+
+ // Create CollectionValue instances
+ std::vector<CollectionValue> collections;
+ CollectionValue collection1;
+ collection1.set_data(reinterpret_cast<uint8_t*>(slices.data()));
+ collection1.set_length(3);
+ collection1.set_null_signs(nullptr);
+ collections.push_back(collection1);
+
+ // Test add_array_values with CollectionValue
+ status = column_writer->add_array_values(sizeof(Slice),
collections.data(), 1);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for BKD writer error conditions
+TEST_F(InvertedIndexWriterTest, BKDWriterErrorConditions) {
+ auto tablet_schema = create_schema();
+
+ // Create index meta for BKD
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(0); // c1 column id
+
+ // Set index properties for BKD index
+ auto* properties = index_meta_pb->mutable_properties();
+ (*properties)["type"] = "bkd";
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_bkd_error", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_bkd_error", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for column c1
+ const TabletColumn& column = tablet_schema->column(0);
+ ASSERT_NE(&column, nullptr);
+ std::unique_ptr<Field> field(FieldFactory::create(column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add some numeric values with edge cases
+ std::vector<int32_t> values = {std::numeric_limits<int32_t>::min(), 0,
+ std::numeric_limits<int32_t>::max()};
+
+ status = column_writer->add_values("c1", values.data(), values.size());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add some nulls to test null handling in BKD
+ status = column_writer->add_nulls(5);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Finish and write
+ status = column_writer->finish();
+ EXPECT_TRUE(status.ok()) << status;
+
+ status = index_file_writer->write();
+ EXPECT_TRUE(status.ok()) << status;
+}
+
+// Test case for file creation and output error handling
+TEST_F(InvertedIndexWriterTest, FileCreationAndOutputErrorHandling) {
+ auto tablet_schema = create_schema();
+
+ // Create index meta
+ auto index_meta_pb = std::make_unique<TabletIndexPB>();
+ index_meta_pb->set_index_type(IndexType::INVERTED);
+ index_meta_pb->set_index_id(1);
+ index_meta_pb->set_index_name("test");
+ index_meta_pb->clear_col_unique_id();
+ index_meta_pb->add_col_unique_id(1); // c2 column id
+
+ TabletIndex idx_meta;
+ idx_meta.init_from_pb(*index_meta_pb.get());
+
+ std::string index_path_prefix
{InvertedIndexDescriptor::get_index_file_path_prefix(
+ local_segment_path(kTestDir, "test_file_error", 0))};
+ std::string index_path =
InvertedIndexDescriptor::get_index_file_path_v2(index_path_prefix);
+
+ io::FileWriterPtr file_writer;
+ io::FileWriterOptions opts;
+ auto fs = io::global_local_filesystem();
+ Status sts = fs->create_file(index_path, &file_writer, &opts);
+ ASSERT_TRUE(sts.ok()) << sts;
+
+ auto index_file_writer = std::make_unique<InvertedIndexFileWriter>(
+ fs, index_path_prefix, "test_file_error", 0,
InvertedIndexStorageFormatPB::V2,
+ std::move(file_writer));
+
+ // Get field for column c2
+ const TabletColumn& column = tablet_schema->column(1); // c2 is the second
column
+ ASSERT_NE(&column, nullptr);
+ std::unique_ptr<Field> field(FieldFactory::create(column));
+ ASSERT_NE(field.get(), nullptr);
+
+ // Create column writer
+ std::unique_ptr<InvertedIndexColumnWriter> column_writer;
+ auto status = InvertedIndexColumnWriter::create(field.get(),
&column_writer,
+ index_file_writer.get(),
&idx_meta);
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Add some values to ensure files are created
+ std::vector<Slice> values = {Slice("test1"), Slice("test2")};
+ status = column_writer->add_values("c2", values.data(), values.size());
+ EXPECT_TRUE(status.ok()) << status;
+
+ // Force close on error to test error handling paths
+ column_writer->close_on_error();
+
+ // Try to finish after close_on_error (should handle gracefully)
+ status = column_writer->finish();
+ // The finish might succeed or fail depending on implementation,
+ // but it should not crash
+}
+
} // namespace doris::segment_v2
\ No newline at end of file
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]