| 960 | } |
| 961 | |
| 962 | void Call::createExternalTables() |
| 963 | { |
| 964 | while (true) |
| 965 | { |
| 966 | for (const auto & external_table : query_info.external_tables()) |
| 967 | { |
| 968 | String name = external_table.name(); |
| 969 | if (name.empty()) |
| 970 | name = "_data"; |
| 971 | auto temporary_id = StorageID::createEmpty(); |
| 972 | temporary_id.table_name = name; |
| 973 | |
| 974 | /// If such a table does not exist, create it. |
| 975 | StoragePtr storage; |
| 976 | if (auto resolved = query_context->tryResolveStorageID(temporary_id, Context::ResolveExternal)) |
| 977 | { |
| 978 | storage = DatabaseCatalog::instance().getTable(resolved, query_context); |
| 979 | } |
| 980 | else |
| 981 | { |
| 982 | NamesAndTypesList columns; |
| 983 | for (size_t column_idx : collections::range(external_table.columns_size())) |
| 984 | { |
| 985 | const auto & name_and_type = external_table.columns(column_idx); |
| 986 | NameAndTypePair column; |
| 987 | column.name = name_and_type.name(); |
| 988 | if (column.name.empty()) |
| 989 | column.name = "_" + std::to_string(column_idx + 1); |
| 990 | column.type = DataTypeFactory::instance().get(name_and_type.type()); |
| 991 | columns.emplace_back(std::move(column)); |
| 992 | } |
| 993 | auto temporary_table = TemporaryTableHolder(query_context, ColumnsDescription{columns}, {}, {}, {}); |
| 994 | storage = temporary_table.getTable(); |
| 995 | query_context->addExternalTable(temporary_id.table_name, std::move(temporary_table)); |
| 996 | } |
| 997 | |
| 998 | if (!external_table.data().empty()) |
| 999 | { |
| 1000 | /// The data will be written directly to the table. |
| 1001 | auto metadata_snapshot = storage->getInMemoryMetadataPtr(); |
| 1002 | auto out_stream = storage->write(ASTPtr(), metadata_snapshot, query_context); |
| 1003 | ReadBufferFromMemory data(external_table.data().data(), external_table.data().size()); |
| 1004 | String format = external_table.format(); |
| 1005 | if (format.empty()) |
| 1006 | format = "TabSeparated"; |
| 1007 | ContextMutablePtr external_table_context = query_context; |
| 1008 | ContextMutablePtr temp_context; |
| 1009 | if (!external_table.settings().empty()) |
| 1010 | { |
| 1011 | temp_context = Context::createCopy(query_context); |
| 1012 | external_table_context = temp_context; |
| 1013 | SettingsChanges settings_changes; |
| 1014 | for (const auto & [key, value] : external_table.settings()) |
| 1015 | settings_changes.push_back({key, value}); |
| 1016 | external_table_context->checkSettingsConstraints(settings_changes); |
| 1017 | external_table_context->applySettingsChanges(settings_changes); |
| 1018 | } |
| 1019 | auto in_stream = external_table_context->getInputFormat( |
nothing calls this directly
no test coverage detected