#pragma once #include #include #include #include #include #include #include #include #include #include namespace DB { using FunctionCreator = std::function; using FunctionSimpleCreator = std::function; using FunctionFactoryData = std::pair; /** Creates function by name. * The provided Context is guaranteed to outlive the created function. Functions may use it for * things like settings, current database, permission checks, etc. */ class FunctionFactory : private boost::noncopyable, public IFactoryWithAliases { public: static FunctionFactory & instance(); template void registerFunction(FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive) { registerFunction(Function::name, std::move(doc), case_sensitiveness); } /// This function is used by YQL - innovative transactional DBMS that depends on ClickHouse by source code. std::vector getAllNames() const; bool has(const std::string & name) const; /// Throws an exception if not found. FunctionOverloadResolverPtr get(const std::string & name, ContextPtr context) const; /// Returns nullptr if not found. FunctionOverloadResolverPtr tryGet(const std::string & name, ContextPtr context) const; /// The same methods to get developer interface implementation. FunctionOverloadResolverPtr getImpl(const std::string & name, ContextPtr context) const; FunctionOverloadResolverPtr tryGetImpl(const std::string & name, ContextPtr context) const; /// Register a function by its name. /// No locking, you must register all functions before usage of get. void registerFunction( const std::string & name, FunctionCreator creator, FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive); void registerFunction( const std::string & name, FunctionSimpleCreator creator, FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive); FunctionDocumentation getDocumentation(const std::string & name) const; private: using Functions = std::unordered_map; Functions functions; Functions case_insensitive_functions; const Functions & getMap() const override { return functions; } const Functions & getCaseInsensitiveMap() const override { return case_insensitive_functions; } String getFactoryName() const override { return "FunctionFactory"; } template void registerFunction(const std::string & name, FunctionDocumentation doc = {}, CaseSensitiveness case_sensitiveness = CaseSensitive) { registerFunction(name, &Function::create, std::move(doc), case_sensitiveness); } }; const String & getFunctionCanonicalNameIfAny(const String & name); }