#pragma once #include #include #include #include #include #include #include namespace DB { class Context; /** Creates function by name. * Function could use for initialization (take ownership of shared_ptr, for example) * some dictionaries from Context. */ class FunctionFactory : private boost::noncopyable, public IFactoryWithAliases> { public: static FunctionFactory & instance(); template void registerFunction(CaseSensitiveness case_sensitiveness = CaseSensitive) { registerFunction(Function::name, case_sensitiveness); } template void registerFunction(const std::string & name, CaseSensitiveness case_sensitiveness = CaseSensitive) { if constexpr (std::is_base_of::value) registerFunction(name, &createDefaultFunction, case_sensitiveness); else registerFunction(name, &Function::create, case_sensitiveness); } /// This function is used by YQL - internal Yandex product that depends on ClickHouse by source code. std::vector getAllNames() const; /// Throws an exception if not found. FunctionOverloadResolverPtr get(const std::string & name, const Context & context) const; /// Returns nullptr if not found. FunctionOverloadResolverPtr tryGet(const std::string & name, const Context & context) const; /// The same methods to get developer interface implementation. FunctionOverloadResolverImplPtr getImpl(const std::string & name, const Context & context) const; FunctionOverloadResolverImplPtr tryGetImpl(const std::string & name, const Context & context) const; private: using Functions = std::unordered_map; Functions functions; Functions case_insensitive_functions; template static FunctionOverloadResolverImplPtr createDefaultFunction(const Context & context) { return std::make_unique(Function::create(context)); } const Functions & getMap() const override { return functions; } const Functions & getCaseInsensitiveMap() const override { return case_insensitive_functions; } String getFactoryName() const override { return "FunctionFactory"; } /// Register a function by its name. /// No locking, you must register all functions before usage of get. void registerFunction( const std::string & name, Value creator, CaseSensitiveness case_sensitiveness = CaseSensitive); }; }