#include #include #include #include #include #include #include #include #include #include #include namespace DB { enum class FunctionOrigin : Int8 { SYSTEM = 0, SQL_USER_DEFINED = 1, EXECUTABLE_USER_DEFINED = 2 }; namespace { template void fillRow( MutableColumns & res_columns, const String & name, UInt64 is_aggregate, const String & create_query, FunctionOrigin function_origin, const Factory & factory) { res_columns[0]->insert(name); res_columns[1]->insert(is_aggregate); if constexpr (std::is_same_v || std::is_same_v) { res_columns[2]->insert(false); res_columns[3]->insertDefault(); } else { res_columns[2]->insert(factory.isCaseInsensitive(name)); if (factory.isAlias(name)) res_columns[3]->insert(factory.aliasTo(name)); else res_columns[3]->insertDefault(); } res_columns[4]->insert(create_query); res_columns[5]->insert(static_cast(function_origin)); if constexpr (std::is_same_v) { if (factory.isAlias(name)) res_columns[6]->insertDefault(); else res_columns[6]->insert(factory.getDocumentation(name).description); } else res_columns[6]->insertDefault(); } } std::vector> getOriginEnumsAndValues() { return std::vector>{ {"System", static_cast(FunctionOrigin::SYSTEM)}, {"SQLUserDefined", static_cast(FunctionOrigin::SQL_USER_DEFINED)}, {"ExecutableUserDefined", static_cast(FunctionOrigin::EXECUTABLE_USER_DEFINED)} }; } NamesAndTypesList StorageSystemFunctions::getNamesAndTypes() { return { {"name", std::make_shared()}, {"is_aggregate", std::make_shared()}, {"case_insensitive", std::make_shared()}, {"alias_to", std::make_shared()}, {"create_query", std::make_shared()}, {"origin", std::make_shared(getOriginEnumsAndValues())}, {"description", std::make_shared()}, }; } void StorageSystemFunctions::fillData(MutableColumns & res_columns, ContextPtr context, const SelectQueryInfo &) const { const auto & functions_factory = FunctionFactory::instance(); const auto & function_names = functions_factory.getAllRegisteredNames(); for (const auto & function_name : function_names) { fillRow(res_columns, function_name, UInt64(0), "", FunctionOrigin::SYSTEM, functions_factory); } const auto & aggregate_functions_factory = AggregateFunctionFactory::instance(); const auto & aggregate_function_names = aggregate_functions_factory.getAllRegisteredNames(); for (const auto & function_name : aggregate_function_names) { fillRow(res_columns, function_name, UInt64(1), "", FunctionOrigin::SYSTEM, aggregate_functions_factory); } const auto & user_defined_sql_functions_factory = UserDefinedSQLFunctionFactory::instance(); const auto & user_defined_sql_functions_names = user_defined_sql_functions_factory.getAllRegisteredNames(); for (const auto & function_name : user_defined_sql_functions_names) { auto create_query = queryToString(user_defined_sql_functions_factory.get(function_name)); fillRow(res_columns, function_name, UInt64(0), create_query, FunctionOrigin::SQL_USER_DEFINED, user_defined_sql_functions_factory); } const auto & user_defined_executable_functions_factory = UserDefinedExecutableFunctionFactory::instance(); const auto & user_defined_executable_functions_names = user_defined_executable_functions_factory.getRegisteredNames(context); for (const auto & function_name : user_defined_executable_functions_names) { fillRow(res_columns, function_name, UInt64(0), "", FunctionOrigin::EXECUTABLE_USER_DEFINED, user_defined_executable_functions_factory); } } void StorageSystemFunctions::backupData(BackupEntriesCollector & backup_entries_collector, const String & data_path_in_backup, const std::optional & /* partitions */) { UserDefinedSQLFunctionFactory::instance().backup(backup_entries_collector, data_path_in_backup); } void StorageSystemFunctions::restoreDataFromBackup(RestorerFromBackup & restorer, const String & data_path_in_backup, const std::optional & /* partitions */) { UserDefinedSQLFunctionFactory::instance().restore(restorer, data_path_in_backup); } }