void registerStorageJoin(StorageFactory & factory) { factory.registerStorage("Join", [](const StorageFactory::Arguments & args) { /// Join(ANY, LEFT, k1, k2, ...) ASTs & engine_args = args.engine_args; if (engine_args.size() < 3) throw Exception( "Storage Join requires at least 3 parameters: Join(ANY|ALL, LEFT|INNER, keys...).", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); const ASTIdentifier * strictness_id = typeid_cast<const ASTIdentifier *>(engine_args[0].get()); if (!strictness_id) throw Exception("First parameter of storage Join must be ANY or ALL (without quotes).", ErrorCodes::BAD_ARGUMENTS); const String strictness_str = Poco::toLower(strictness_id->name); ASTTableJoin::Strictness strictness; if (strictness_str == "any") strictness = ASTTableJoin::Strictness::Any; else if (strictness_str == "all") strictness = ASTTableJoin::Strictness::All; else throw Exception("First parameter of storage Join must be ANY or ALL (without quotes).", ErrorCodes::BAD_ARGUMENTS); const ASTIdentifier * kind_id = typeid_cast<const ASTIdentifier *>(engine_args[1].get()); if (!kind_id) throw Exception("Second parameter of storage Join must be LEFT or INNER (without quotes).", ErrorCodes::BAD_ARGUMENTS); const String kind_str = Poco::toLower(kind_id->name); ASTTableJoin::Kind kind; if (kind_str == "left") kind = ASTTableJoin::Kind::Left; else if (kind_str == "inner") kind = ASTTableJoin::Kind::Inner; else if (kind_str == "right") kind = ASTTableJoin::Kind::Right; else if (kind_str == "full") kind = ASTTableJoin::Kind::Full; else throw Exception("Second parameter of storage Join must be LEFT or INNER or RIGHT or FULL (without quotes).", ErrorCodes::BAD_ARGUMENTS); Names key_names; key_names.reserve(engine_args.size() - 2); for (size_t i = 2, size = engine_args.size(); i < size; ++i) { const ASTIdentifier * key = typeid_cast<const ASTIdentifier *>(engine_args[i].get()); if (!key) throw Exception("Parameter №" + toString(i + 1) + " of storage Join don't look like column name.", ErrorCodes::BAD_ARGUMENTS); key_names.push_back(key->name); } return StorageJoin::create( args.data_path, args.table_name, key_names, kind, strictness, args.columns); }); }
void registerStorageMerge(StorageFactory & factory) { factory.registerStorage("Merge", [](const StorageFactory::Arguments & args) { /** In query, the name of database is specified as table engine argument which contains source tables, * as well as regex for source-table names. */ ASTs & engine_args = args.engine_args; if (engine_args.size() != 2) throw Exception("Storage Merge requires exactly 2 parameters" " - name of source database and regexp for table names.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); engine_args[0] = evaluateConstantExpressionOrIdentifierAsLiteral(engine_args[0], args.local_context); engine_args[1] = evaluateConstantExpressionAsLiteral(engine_args[1], args.local_context); String source_database = static_cast<const ASTLiteral &>(*engine_args[0]).value.safeGet<String>(); String table_name_regexp = static_cast<const ASTLiteral &>(*engine_args[1]).value.safeGet<String>(); return StorageMerge::create( args.table_name, args.columns, source_database, table_name_regexp, args.context); }); }
void registerStorageView(StorageFactory & factory) { factory.registerStorage("View", [](const StorageFactory::Arguments & args) { if (args.query.storage) throw Exception("Specifying ENGINE is not allowed for a View", ErrorCodes::INCORRECT_QUERY); return StorageView::create(args.table_name, args.query, args.columns); }); }
void registerStorageMemory(StorageFactory & factory) { factory.registerStorage("Memory", [](const StorageFactory::Arguments & args) { if (!args.engine_args.empty()) throw Exception( "Engine " + args.engine_name + " doesn't support any arguments (" + toString(args.engine_args.size()) + " given)", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); return StorageMemory::create(args.table_name, args.columns); }); }
void registerStorageFile(StorageFactory & factory) { factory.registerStorage("File", [](const StorageFactory::Arguments & args) { ASTs & engine_args = args.engine_args; if (!(engine_args.size() == 1 || engine_args.size() == 2)) throw Exception( "Storage File requires 1 or 2 arguments: name of used format and source.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); engine_args[0] = evaluateConstantExpressionOrIdentifierAsLiteral(engine_args[0], args.local_context); String format_name = static_cast<const ASTLiteral &>(*engine_args[0]).value.safeGet<String>(); int source_fd = -1; String source_path; if (engine_args.size() >= 2) { /// Will use FD if engine_args[1] is int literal or identifier with std* name if (const ASTIdentifier * identifier = typeid_cast<const ASTIdentifier *>(engine_args[1].get())) { if (identifier->name == "stdin") source_fd = STDIN_FILENO; else if (identifier->name == "stdout") source_fd = STDOUT_FILENO; else if (identifier->name == "stderr") source_fd = STDERR_FILENO; else throw Exception("Unknown identifier '" + identifier->name + "' in second arg of File storage constructor", ErrorCodes::UNKNOWN_IDENTIFIER); } else if (const ASTLiteral * literal = typeid_cast<const ASTLiteral *>(engine_args[1].get())) { auto type = literal->value.getType(); if (type == Field::Types::Int64) source_fd = static_cast<int>(literal->value.get<Int64>()); else if (type == Field::Types::UInt64) source_fd = static_cast<int>(literal->value.get<UInt64>()); else if (type == Field::Types::String) source_path = literal->value.get<String>(); } } return StorageFile::create( source_path, source_fd, args.data_path, args.table_name, format_name, args.columns, args.context); }); }
void registerStorageTinyLog(StorageFactory & factory) { factory.registerStorage("TinyLog", [](const StorageFactory::Arguments & args) { if (!args.engine_args.empty()) throw Exception( "Engine " + args.engine_name + " doesn't support any arguments (" + toString(args.engine_args.size()) + " given)", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); return StorageTinyLog::create( args.data_path, args.table_name, args.columns, args.attach, args.context.getSettings().max_compress_block_size); }); }
void registerStorageODBC(StorageFactory & factory) { factory.registerStorage("ODBC", [](const StorageFactory::Arguments & args) { ASTs & engine_args = args.engine_args; if (engine_args.size() != 3) throw Exception( "Storage ODBC requires exactly 3 parameters: ODBC('DSN', database, table).", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); for (size_t i = 0; i < 2; ++i) engine_args[i] = evaluateConstantExpressionOrIdentifierAsLiteral(engine_args[i], args.local_context); return StorageODBC::create(args.table_name, static_cast<const ASTLiteral &>(*engine_args[0]).value.safeGet<String>(), static_cast<const ASTLiteral &>(*engine_args[1]).value.safeGet<String>(), static_cast<const ASTLiteral &>(*engine_args[2]).value.safeGet<String>(), args.columns); }); }
void registerStorageHDFS(StorageFactory & factory) { factory.registerStorage("HDFS", [](const StorageFactory::Arguments & args) { ASTs & engine_args = args.engine_args; if (!(engine_args.size() == 1 || engine_args.size() == 2)) throw Exception( "Storage HDFS requires exactly 2 arguments: url and name of used format.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); engine_args[0] = evaluateConstantExpressionOrIdentifierAsLiteral(engine_args[0], args.local_context); String url = static_cast<const ASTLiteral &>(*engine_args[0]).value.safeGet<String>(); engine_args[1] = evaluateConstantExpressionOrIdentifierAsLiteral(engine_args[1], args.local_context); String format_name = static_cast<const ASTLiteral &>(*engine_args[1]).value.safeGet<String>(); return StorageHDFS::create(url, args.table_name, format_name, args.columns, args.context); }); }