1 | #include <Common/OptimizedRegularExpression.h> |
2 | #include <Common/typeid_cast.h> |
3 | #include <Storages/StorageMerge.h> |
4 | #include <Parsers/ASTLiteral.h> |
5 | #include <Parsers/ASTFunction.h> |
6 | #include <TableFunctions/ITableFunction.h> |
7 | #include <Interpreters/evaluateConstantExpression.h> |
8 | #include <Interpreters/Context.h> |
9 | #include <TableFunctions/TableFunctionMerge.h> |
10 | #include <TableFunctions/TableFunctionFactory.h> |
11 | #include "registerTableFunctions.h" |
12 | |
13 | |
14 | namespace DB |
15 | { |
16 | |
17 | |
18 | namespace ErrorCodes |
19 | { |
20 | extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; |
21 | extern const int UNKNOWN_TABLE; |
22 | } |
23 | |
24 | |
25 | static NamesAndTypesList chooseColumns(const String & source_database, const String & table_name_regexp_, const Context & context) |
26 | { |
27 | OptimizedRegularExpression table_name_regexp(table_name_regexp_); |
28 | auto table_name_match = [&](const String & table_name) { return table_name_regexp.match(table_name); }; |
29 | |
30 | StoragePtr any_table; |
31 | |
32 | { |
33 | auto database = context.getDatabase(source_database); |
34 | auto iterator = database->getTablesIterator(context, table_name_match); |
35 | |
36 | if (iterator->isValid()) |
37 | any_table = iterator->table(); |
38 | } |
39 | |
40 | if (!any_table) |
41 | throw Exception("Error while executing table function merge. In database " + source_database + " no one matches regular expression: " |
42 | + table_name_regexp_, ErrorCodes::UNKNOWN_TABLE); |
43 | |
44 | return any_table->getColumns().getAllPhysical(); |
45 | } |
46 | |
47 | |
48 | StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const |
49 | { |
50 | ASTs & args_func = ast_function->children; |
51 | |
52 | if (args_func.size() != 1) |
53 | throw Exception("Table function 'merge' requires exactly 2 arguments" |
54 | " - name of source database and regexp for table names." , |
55 | ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); |
56 | |
57 | ASTs & args = args_func.at(0)->children; |
58 | |
59 | if (args.size() != 2) |
60 | throw Exception("Table function 'merge' requires exactly 2 arguments" |
61 | " - name of source database and regexp for table names." , |
62 | ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); |
63 | |
64 | args[0] = evaluateConstantExpressionOrIdentifierAsLiteral(args[0], context); |
65 | args[1] = evaluateConstantExpressionAsLiteral(args[1], context); |
66 | |
67 | String source_database = args[0]->as<ASTLiteral &>().value.safeGet<String>(); |
68 | String table_name_regexp = args[1]->as<ASTLiteral &>().value.safeGet<String>(); |
69 | |
70 | auto res = StorageMerge::create( |
71 | getDatabaseName(), |
72 | table_name, |
73 | ColumnsDescription{chooseColumns(source_database, table_name_regexp, context)}, |
74 | source_database, |
75 | table_name_regexp, |
76 | context); |
77 | res->startup(); |
78 | return res; |
79 | } |
80 | |
81 | |
82 | void registerTableFunctionMerge(TableFunctionFactory & factory) |
83 | { |
84 | factory.registerFunction<TableFunctionMerge>(); |
85 | } |
86 | |
87 | } |
88 | |