diff --git a/options/options_parser.cc b/options/options_parser.cc index b3754de79..d423f76ff 100644 --- a/options/options_parser.cc +++ b/options/options_parser.cc @@ -679,6 +679,15 @@ Status RocksDBOptionsParser::VerifyCFOptions( Status s = base_config->GetOption(config_options, mismatch, &base_value); if (s.ok()) { s = file_config->GetOption(config_options, mismatch, &file_value); + // In file_opt, certain options like MergeOperator may be nullptr due to + // factor methods not available. So we use opt_map to get + // option value to use in the error message below. + if (s.ok() && file_value == kNullptrString && opt_map) { + auto const& opt_val_str = (opt_map->find(mismatch)); + if (opt_val_str != opt_map->end()) { + file_value = opt_val_str->second; + } + } } int offset = snprintf(buffer, sizeof(buffer), "[RocksDBOptionsParser]: " diff --git a/options/options_test.cc b/options/options_test.cc index 556815745..c22df98c6 100644 --- a/options/options_test.cc +++ b/options/options_test.cc @@ -3927,6 +3927,36 @@ class OptionsSanityCheckTest : public OptionsParserTest, const std::string kOptionsFileName = "OPTIONS"; }; +TEST_P(OptionsSanityCheckTest, MergeOperatorErrorMessage) { + ColumnFamilyOptions opts; + Random rnd(301); + opts.merge_operator.reset(test::RandomMergeOperator(&rnd)); + std::string merge_op_name = opts.merge_operator->Name(); + ASSERT_OK(PersistCFOptions(opts)); + + // Test when going from merge operator -> nullptr + opts.merge_operator = nullptr; + Status s = + SanityCheckCFOptions(opts, ConfigOptions::kSanityLevelLooselyCompatible); + ASSERT_TRUE(s.IsInvalidArgument()); + std::string err_msg = s.ToString(); + std::string specified = "The specified one is " + kNullptrString; + std::string persisted = "the persisted one is " + merge_op_name; + ASSERT_TRUE(err_msg.find(specified) != std::string::npos); + ASSERT_TRUE(err_msg.find(persisted) != std::string::npos); + + // Test when using a different merge operator + opts.merge_operator.reset(test::RandomMergeOperator(&rnd)); + s = SanityCheckCFOptions(opts, ConfigOptions::kSanityLevelLooselyCompatible); + ASSERT_TRUE(s.IsInvalidArgument()); + err_msg = s.ToString(); + specified = + "The specified one is " + std::string(opts.merge_operator->Name()); + persisted = "the persisted one is " + merge_op_name; + ASSERT_TRUE(err_msg.find(specified) != std::string::npos); + ASSERT_TRUE(err_msg.find(persisted) != std::string::npos); +} + TEST_P(OptionsSanityCheckTest, CFOptionsSanityCheck) { ColumnFamilyOptions opts; Random rnd(301);