diff --git a/src/Common/Config/AbstractConfigurationComparison.cpp b/src/Common/Config/AbstractConfigurationComparison.cpp index 33d7549adaf..eb677debb02 100644 --- a/src/Common/Config/AbstractConfigurationComparison.cpp +++ b/src/Common/Config/AbstractConfigurationComparison.cpp @@ -32,60 +32,60 @@ bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const P return isSameConfiguration(left, key, right, key); } +bool isSameConfigurationWithMultipleKeys(const Poco::Util::AbstractConfiguration & left, const Poco::Util::AbstractConfiguration & right, const String & root, const String & name) +{ + if (&left == &right) + return true; + + auto left_multiple_keys = getMultipleKeysFromConfig(left, root, name); + auto right_multiple_keys = getMultipleKeysFromConfig(right, root, name); + if (left_multiple_keys.size() != right_multiple_keys.size()) + return false; + + for (auto & key : left_multiple_keys) + if (!isSameConfiguration(left, right, concatKeyAndSubKey(root, key))) + return false; + + return true; +} + bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const String & left_key, const Poco::Util::AbstractConfiguration & right, const String & right_key) { if (&left == &right && left_key == right_key) return true; - /// Config may have multiple keys with one name. For example: - /// - /// ... - /// ... - /// - /// In this case we need to compare all of them. - auto left_multiple_keys = getMultipleKeysFromConfig(left, "", left_key); - auto right_multiple_keys = getMultipleKeysFromConfig(right, "", right_key); - if (left_multiple_keys.size() != right_multiple_keys.size()) + bool has_property = left.hasProperty(left_key); + if (has_property != right.hasProperty(right_key)) return false; - - for (size_t i = 0; i != left_multiple_keys.size(); ++i) + if (has_property) { - if (left_multiple_keys[i] != right_multiple_keys[i]) + /// The left and right configurations contains values so we can compare them. + if (left.getRawString(left_key) != right.getRawString(right_key)) return false; + } - bool has_property = left.hasProperty(left_multiple_keys[i]); - if (has_property != right.hasProperty(right_multiple_keys[i])) + /// Get the subkeys of the left and right configurations. + Poco::Util::AbstractConfiguration::Keys subkeys; + left.keys(left_key, subkeys); + + { + /// Check that the right configuration has the same set of subkeys as the left configuration. + Poco::Util::AbstractConfiguration::Keys right_subkeys; + right.keys(right_key, right_subkeys); + std::unordered_set left_subkeys{subkeys.begin(), subkeys.end()}; + if ((left_subkeys.size() != right_subkeys.size()) || (left_subkeys.size() != subkeys.size())) return false; - if (has_property) - { - /// The left and right configurations contains values so we can compare them. - if (left.getRawString(left_multiple_keys[i]) != right.getRawString(right_multiple_keys[i])) - return false; - } - - /// Get the subkeys of the left and right configurations. - Poco::Util::AbstractConfiguration::Keys subkeys; - left.keys(left_multiple_keys[i], subkeys); - - { - /// Check that the right configuration has the same set of subkeys as the left configuration. - Poco::Util::AbstractConfiguration::Keys right_subkeys; - right.keys(right_multiple_keys[i], right_subkeys); - std::unordered_set left_subkeys{subkeys.begin(), subkeys.end()}; - if ((left_subkeys.size() != right_subkeys.size()) || (left_subkeys.size() != subkeys.size())) - return false; - for (const auto & right_subkey : right_subkeys) - if (!left_subkeys.count(right_subkey)) - return false; - } - - /// Go through all the subkeys and compare corresponding parts of the configurations. - for (const auto & subkey : subkeys) - if (!isSameConfiguration(left, concatKeyAndSubKey(left_multiple_keys[i], subkey), right, concatKeyAndSubKey(right_multiple_keys[i], subkey))) + for (const auto & right_subkey : right_subkeys) + if (!left_subkeys.count(right_subkey)) return false; } + /// Go through all the subkeys and compare corresponding parts of the configurations. + for (const auto & subkey : subkeys) + if (!isSameConfiguration(left, concatKeyAndSubKey(left_key, subkey), right, concatKeyAndSubKey(right_key, subkey))) + return false; + return true; } diff --git a/src/Common/Config/AbstractConfigurationComparison.h b/src/Common/Config/AbstractConfigurationComparison.h index 795fca2af8e..6e1d8a890bb 100644 --- a/src/Common/Config/AbstractConfigurationComparison.h +++ b/src/Common/Config/AbstractConfigurationComparison.h @@ -13,6 +13,17 @@ namespace DB bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const Poco::Util::AbstractConfiguration & right); + /// Config may have multiple keys with one name. For example: + /// + /// ... + /// ... + /// + /// Returns true if the specified subview of the two configurations contains + /// the same keys and values for each key with the given name. + bool isSameConfigurationWithMultipleKeys(const Poco::Util::AbstractConfiguration & left, + const Poco::Util::AbstractConfiguration & right, + const String & root, const String & name); + /// Returns true if the specified subview of the two configurations contains the same keys and values. bool isSameConfiguration(const Poco::Util::AbstractConfiguration & left, const Poco::Util::AbstractConfiguration & right, diff --git a/src/Interpreters/Context.cpp b/src/Interpreters/Context.cpp index 50f85b7d452..f2bc801643f 100644 --- a/src/Interpreters/Context.cpp +++ b/src/Interpreters/Context.cpp @@ -1374,11 +1374,11 @@ void Context::setExternalModelsConfig(const ConfigurationPtr & config, const std { std::lock_guard lock(shared->external_models_mutex); - if (shared->external_models_config && isSameConfiguration(*config, *shared->external_models_config, config_name)) + if (shared->external_models_config && isSameConfigurationWithMultipleKeys(*config, *shared->external_models_config, "", config_name)) return; shared->external_models_config = config; - shared->models_repository_guard.reset(); + shared->models_repository_guard .reset(); shared->models_repository_guard = getExternalModelsLoaderUnlocked().addConfigRepository( std::make_unique(*config, config_name)); }