@@ -7480,6 +7480,9 @@ class UserDefinedIndexTest : public BlockBasedTableTestBase {
74807480 const Slice* first_key_in_next_block,
74817481 const BlockHandle& block_handle,
74827482 std::string* separator_scratch) override {
7483+ if (keys_added_ == 0 ) {
7484+ return last_key_in_current_block;
7485+ }
74837486 EXPECT_EQ (last_key_in_current_block.size (), 5 );
74847487 if (first_key_in_next_block) {
74857488 EXPECT_EQ (first_key_in_next_block->size (), 5 );
@@ -7500,12 +7503,19 @@ class UserDefinedIndexTest : public BlockBasedTableTestBase {
75007503
75017504 void OnKeyAdded (const Slice& key, ValueType /* value*/ ,
75027505 const Slice& /* value*/ ) override {
7506+ if (key.starts_with (" dummy" )) {
7507+ return ;
7508+ }
75037509 EXPECT_EQ (key.size (), 5 );
75047510 // Track keys added to the index
75057511 keys_added_++;
75067512 }
75077513
75087514 Status Finish (Slice* index_contents) override {
7515+ if (entries_added_ == 0 ) {
7516+ *index_contents = Slice ();
7517+ return Status::OK ();
7518+ }
75097519 // Serialize the index data
75107520 std::string result;
75117521 for (const auto & entry : index_data_) {
@@ -8020,6 +8030,7 @@ TEST_F(UserDefinedIndexTest, IngestTest) {
80208030
80218031// Verify that external file ingestion fails if we try to ingest an SST file
80228032// without the UDI and a UDI factory is configured in BlockBasedTableOptions
8033+ // and fail_if_no_udi_on_open is true in BlockBasedTableOptions.
80238034TEST_F (UserDefinedIndexTest, IngestFailTest) {
80248035 Options options;
80258036 BlockBasedTableOptions table_options;
@@ -8051,6 +8062,7 @@ TEST_F(UserDefinedIndexTest, IngestFailTest) {
80518062 auto user_defined_index_factory =
80528063 std::make_shared<TestUserDefinedIndexFactory>();
80538064 table_options.user_defined_index_factory = user_defined_index_factory;
8065+ table_options.fail_if_no_udi_on_open = true ;
80548066 options.table_factory .reset (NewBlockBasedTableFactory (table_options));
80558067
80568068 std::unique_ptr<DB > db;
@@ -8065,6 +8077,72 @@ TEST_F(UserDefinedIndexTest, IngestFailTest) {
80658077 s = db->IngestExternalFile (cfh, {ingest_file}, ifo);
80668078 ASSERT_NOK (s);
80678079
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+
80688146 ASSERT_OK (db->DestroyColumnFamilyHandle (cfh));
80698147 ASSERT_OK (db->Close ());
80708148 ASSERT_OK (DestroyDB (dbname, options));
0 commit comments