@@ -7480,6 +7480,9 @@ class UserDefinedIndexTest : public BlockBasedTableTestBase {
7480
7480
const Slice* first_key_in_next_block,
7481
7481
const BlockHandle& block_handle,
7482
7482
std::string* separator_scratch) override {
7483
+ if (keys_added_ == 0 ) {
7484
+ return last_key_in_current_block;
7485
+ }
7483
7486
EXPECT_EQ (last_key_in_current_block.size (), 5 );
7484
7487
if (first_key_in_next_block) {
7485
7488
EXPECT_EQ (first_key_in_next_block->size (), 5 );
@@ -7500,12 +7503,19 @@ class UserDefinedIndexTest : public BlockBasedTableTestBase {
7500
7503
7501
7504
void OnKeyAdded (const Slice& key, ValueType /* value*/ ,
7502
7505
const Slice& /* value*/ ) override {
7506
+ if (key.starts_with (" dummy" )) {
7507
+ return ;
7508
+ }
7503
7509
EXPECT_EQ (key.size (), 5 );
7504
7510
// Track keys added to the index
7505
7511
keys_added_++;
7506
7512
}
7507
7513
7508
7514
Status Finish (Slice* index_contents) override {
7515
+ if (entries_added_ == 0 ) {
7516
+ *index_contents = Slice ();
7517
+ return Status::OK ();
7518
+ }
7509
7519
// Serialize the index data
7510
7520
std::string result;
7511
7521
for (const auto & entry : index_data_) {
@@ -8020,6 +8030,7 @@ TEST_F(UserDefinedIndexTest, IngestTest) {
8020
8030
8021
8031
// Verify that external file ingestion fails if we try to ingest an SST file
8022
8032
// without the UDI and a UDI factory is configured in BlockBasedTableOptions
8033
+ // and fail_if_no_udi_on_open is true in BlockBasedTableOptions.
8023
8034
TEST_F (UserDefinedIndexTest, IngestFailTest) {
8024
8035
Options options;
8025
8036
BlockBasedTableOptions table_options;
@@ -8051,6 +8062,7 @@ TEST_F(UserDefinedIndexTest, IngestFailTest) {
8051
8062
auto user_defined_index_factory =
8052
8063
std::make_shared<TestUserDefinedIndexFactory>();
8053
8064
table_options.user_defined_index_factory = user_defined_index_factory;
8065
+ table_options.fail_if_no_udi_on_open = true ;
8054
8066
options.table_factory .reset (NewBlockBasedTableFactory (table_options));
8055
8067
8056
8068
std::unique_ptr<DB> db;
@@ -8065,6 +8077,72 @@ TEST_F(UserDefinedIndexTest, IngestFailTest) {
8065
8077
s = db->IngestExternalFile (cfh, {ingest_file}, ifo);
8066
8078
ASSERT_NOK (s);
8067
8079
8080
+ ASSERT_OK (db->SetOptions (
8081
+ cfh, {{" block_based_table_factory" , " {fail_if_no_udi_on_open=false;}" }}));
8082
+ s = db->IngestExternalFile (cfh, {ingest_file}, ifo);
8083
+ ASSERT_OK (s);
8084
+
8085
+ ASSERT_OK (db->DestroyColumnFamilyHandle (cfh));
8086
+ ASSERT_OK (db->Close ());
8087
+ ASSERT_OK (DestroyDB (dbname, options));
8088
+ }
8089
+
8090
+ TEST_F (UserDefinedIndexTest, IngestEmptyUDI) {
8091
+ Options options;
8092
+ BlockBasedTableOptions table_options;
8093
+ std::string dbname = test::PerThreadDBPath (" user_defined_index_test" );
8094
+ std::string ingest_file = dbname + " test.sst" ;
8095
+ std::string ingest_file2 = dbname + " dummy.sst" ;
8096
+
8097
+ // Set up the user-defined index factory
8098
+ auto user_defined_index_factory =
8099
+ std::make_shared<TestUserDefinedIndexFactory>();
8100
+ table_options.user_defined_index_factory = user_defined_index_factory;
8101
+ // Set up custom flush block policy that flushes every 3 keys
8102
+ table_options.flush_block_policy_factory =
8103
+ std::make_shared<CustomFlushBlockPolicyFactory>();
8104
+
8105
+ options.table_factory .reset (NewBlockBasedTableFactory (table_options));
8106
+
8107
+ std::unique_ptr<SstFileWriter> writer;
8108
+ writer.reset (new SstFileWriter (EnvOptions (), options));
8109
+ ASSERT_OK (writer->Open (ingest_file));
8110
+
8111
+ // Add 100 keys instead of just 5
8112
+ for (int i = 0 ; i < 100 ; i++) {
8113
+ std::stringstream ss;
8114
+ ss << std::setw (2 ) << std::setfill (' 0' ) << i;
8115
+ std::string key = " key" + ss.str ();
8116
+ std::string value = " value" + ss.str ();
8117
+ ASSERT_OK (writer->Put (key, value));
8118
+ }
8119
+ ASSERT_OK (writer->Finish ());
8120
+ writer.reset ();
8121
+ writer.reset (new SstFileWriter (EnvOptions (), options));
8122
+ ASSERT_OK (writer->Open (ingest_file2));
8123
+ ASSERT_OK (writer->Put (" dummy" , " val" ));
8124
+ ASSERT_OK (writer->Finish ());
8125
+ writer.reset ();
8126
+
8127
+ table_options.fail_if_no_udi_on_open = true ;
8128
+ options.table_factory .reset (NewBlockBasedTableFactory (table_options));
8129
+
8130
+ std::unique_ptr<DB> db;
8131
+ options.create_if_missing = true ;
8132
+ Status s = DB::Open (options, dbname, &db);
8133
+ ASSERT_OK (s);
8134
+ ASSERT_TRUE (db != nullptr );
8135
+ ColumnFamilyHandle* cfh = nullptr ;
8136
+ ASSERT_OK (db->CreateColumnFamily (options, " new_cf" , &cfh));
8137
+
8138
+ std::vector<IngestExternalFileArg> ifa;
8139
+ ifa.emplace_back ();
8140
+ ifa[0 ].column_family = cfh;
8141
+ ifa[0 ].external_files .emplace_back (ingest_file);
8142
+ ifa[0 ].external_files .emplace_back (ingest_file2);
8143
+ s = db->IngestExternalFiles (ifa);
8144
+ ASSERT_OK (s);
8145
+
8068
8146
ASSERT_OK (db->DestroyColumnFamilyHandle (cfh));
8069
8147
ASSERT_OK (db->Close ());
8070
8148
ASSERT_OK (DestroyDB (dbname, options));
0 commit comments