1 | #include <TableFunctions/TableFunctionFactory.h> |
2 | |
3 | #include <Interpreters/Context.h> |
4 | #include <Common/Exception.h> |
5 | #include <IO/WriteHelpers.h> |
6 | |
7 | |
8 | namespace DB |
9 | { |
10 | |
11 | namespace ErrorCodes |
12 | { |
13 | extern const int READONLY; |
14 | extern const int UNKNOWN_FUNCTION; |
15 | extern const int LOGICAL_ERROR; |
16 | } |
17 | |
18 | |
19 | void TableFunctionFactory::registerFunction(const std::string & name, Creator creator, CaseSensitiveness case_sensitiveness) |
20 | { |
21 | if (!table_functions.emplace(name, creator).second) |
22 | throw Exception("TableFunctionFactory: the table function name '" + name + "' is not unique" , |
23 | ErrorCodes::LOGICAL_ERROR); |
24 | |
25 | if (case_sensitiveness == CaseInsensitive |
26 | && !case_insensitive_table_functions.emplace(Poco::toLower(name), creator).second) |
27 | throw Exception("TableFunctionFactory: the case insensitive table function name '" + name + "' is not unique" , |
28 | ErrorCodes::LOGICAL_ERROR); |
29 | } |
30 | |
31 | TableFunctionPtr TableFunctionFactory::get( |
32 | const std::string & name, |
33 | const Context & context) const |
34 | { |
35 | if (context.getSettings().readonly == 1) /** For example, for readonly = 2 - allowed. */ |
36 | throw Exception("Table functions are forbidden in readonly mode" , ErrorCodes::READONLY); |
37 | |
38 | auto res = tryGet(name, context); |
39 | if (!res) |
40 | { |
41 | auto hints = getHints(name); |
42 | if (!hints.empty()) |
43 | throw Exception("Unknown table function " + name + ". Maybe you meant: " + toString(hints), ErrorCodes::UNKNOWN_FUNCTION); |
44 | else |
45 | throw Exception("Unknown table function " + name, ErrorCodes::UNKNOWN_FUNCTION); |
46 | } |
47 | |
48 | return res; |
49 | } |
50 | |
51 | TableFunctionPtr TableFunctionFactory::tryGet( |
52 | const std::string & name_param, |
53 | const Context &) const |
54 | { |
55 | String name = getAliasToOrName(name_param); |
56 | |
57 | auto it = table_functions.find(name); |
58 | if (table_functions.end() != it) |
59 | return it->second(); |
60 | |
61 | it = case_insensitive_table_functions.find(Poco::toLower(name)); |
62 | if (case_insensitive_table_functions.end() != it) |
63 | return it->second(); |
64 | |
65 | return {}; |
66 | } |
67 | |
68 | bool TableFunctionFactory::isTableFunctionName(const std::string & name) const |
69 | { |
70 | return table_functions.count(name); |
71 | } |
72 | |
73 | TableFunctionFactory & TableFunctionFactory::instance() |
74 | { |
75 | static TableFunctionFactory ret; |
76 | return ret; |
77 | } |
78 | |
79 | } |
80 | |