#include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int UNKNOWN_TABLE; } static NamesAndTypesList chooseColumns(const String & source_database, const String & table_name_regexp_, const Context & context) { OptimizedRegularExpression table_name_regexp(table_name_regexp_); auto table_name_match = [&](const String & table_name) { return table_name_regexp.match(table_name); }; StoragePtr any_table; { auto database = context.getDatabase(source_database); auto iterator = database->getIterator(context, table_name_match); if (iterator->isValid()) any_table = iterator->table(); } if (!any_table) throw Exception("Error while executing table function merge. In database " + source_database + " no one matches regular expression: " + table_name_regexp_, ErrorCodes::UNKNOWN_TABLE); return any_table->getColumns().getAllPhysical(); } StoragePtr TableFunctionMerge::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const { ASTs & args_func = ast_function->children; if (args_func.size() != 1) throw Exception("Table function 'merge' requires exactly 2 arguments" " - name of source database and regexp for table names.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); ASTs & args = args_func.at(0)->children; if (args.size() != 2) throw Exception("Table function 'merge' requires exactly 2 arguments" " - name of source database and regexp for table names.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); args[0] = evaluateConstantExpressionOrIdentifierAsLiteral(args[0], context); args[1] = evaluateConstantExpressionAsLiteral(args[1], context); String source_database = args[0]->as().value.safeGet(); String table_name_regexp = args[1]->as().value.safeGet(); auto res = StorageMerge::create( getDatabaseName(), table_name, ColumnsDescription{chooseColumns(source_database, table_name_regexp, context)}, source_database, table_name_regexp, context); res->startup(); return res; } void registerTableFunctionMerge(TableFunctionFactory & factory) { factory.registerFunction(); } }