`DataTypeFactory::get` locks a mutex inside shared a context, there was a case when many threads were locked inside it

https://pastila.nl/?0043b3e6/c557368f4cf0eb87a3c6f2cc162bc693

It is not clear which thread locked the mutex for a long time. However, it may be possible to lock less inside `DataTypeFactory::get`.
using MergeTreeMetadataCachePtr = std::shared_ptr<MergeTreeMetadataCache>;
#endif
struct IHostContext
{
    virtual ~IHostContext() = default;
};
using IHostContextPtr = std::shared_ptr<IHostContext>;
struct SharedContextHolder
{
    ~SharedContextHolder();
    SharedContextHolder();
    explicit SharedContextHolder(std::unique_ptr<ContextSharedPart> shared_context);
    SharedContextHolder(SharedContextHolder &&) noexcept;
    SharedContextHolder & operator=(SharedContextHolder &&) noexcept;
    ContextSharedPart * get() const { return shared.get(); }
    void reset();
private:
    std::unique_ptr<ContextSharedPart> shared;
};
/** A set of known objects that can be used in the query.
  * Consists of a shared part (always common to all sessions and queries)
  *  and copied part (which can be its own for each session or query).
  *
  * Everything is encapsulated for all sorts of checks and locks.
  */
class Context: public std::enable_shared_from_this<Context>