Fix double free for shared exception message in case of dictGet from not loaded dictionary.

This commit is contained in:
Nikolai Kochetov 2020-10-27 16:07:58 +03:00
parent 30325689c4
commit afc28c84a0

View File

@ -57,6 +57,7 @@ namespace ErrorCodes
extern const int TYPE_MISMATCH;
extern const int ILLEGAL_COLUMN;
extern const int BAD_ARGUMENTS;
extern const int DICTIONARIES_WAS_NOT_LOADED;
}
@ -81,6 +82,12 @@ public:
explicit FunctionDictHelper(const Context & context_) : context(context_), external_loader(context.getExternalDictionariesLoader()) {}
std::shared_ptr<const IDictionaryBase> getDictionary(const String & dictionary_name)
{
// Exception from external_loader may be shared for dictGet call from multiple threads.
// Don't just rethrow it, because sharing the same exception object
// between multiple threads can lead to weird effects if they decide to
// modify it, for example, by adding some error context.
try
{
String resolved_name = DatabaseCatalog::instance().resolveDictionaryName(dictionary_name);
auto dict = external_loader.getDictionary(resolved_name);
@ -91,6 +98,15 @@ public:
}
return dict;
}
catch (...)
{
throw DB::Exception(ErrorCodes::DICTIONARIES_WAS_NOT_LOADED,
"Failed to load dictionary '{}': {}",
dictionary_name,
getCurrentExceptionMessage(true /*with stack trace*/,
true /*check embedded stack trace*/));
}
}
std::shared_ptr<const IDictionaryBase> getDictionary(const ColumnWithTypeAndName & column)
{