| 761 | |
| 762 | |
| 763 | QueryPipelinePtr StorageDistributed::distributedWrite(const ASTInsertQuery & query, ContextPtr local_context) |
| 764 | { |
| 765 | const Settings & settings = local_context->getSettingsRef(); |
| 766 | std::shared_ptr<StorageDistributed> storage_src; |
| 767 | auto & select = query.select->as<ASTSelectWithUnionQuery &>(); |
| 768 | auto new_query = std::dynamic_pointer_cast<ASTInsertQuery>(query.clone()); |
| 769 | if (select.list_of_selects->children.size() == 1) |
| 770 | { |
| 771 | if (auto * select_query = select.list_of_selects->children.at(0)->as<ASTSelectQuery>()) |
| 772 | { |
| 773 | JoinedTables joined_tables(Context::createCopy(local_context), *select_query); |
| 774 | |
| 775 | if (joined_tables.tablesCount() == 1) |
| 776 | { |
| 777 | storage_src = std::dynamic_pointer_cast<StorageDistributed>(joined_tables.getLeftTableStorage()); |
| 778 | if (storage_src) |
| 779 | { |
| 780 | const auto select_with_union_query = std::make_shared<ASTSelectWithUnionQuery>(); |
| 781 | select_with_union_query->list_of_selects = std::make_shared<ASTExpressionList>(); |
| 782 | |
| 783 | auto new_select_query = std::dynamic_pointer_cast<ASTSelectQuery>(select_query->clone()); |
| 784 | select_with_union_query->list_of_selects->children.push_back(new_select_query); |
| 785 | |
| 786 | new_select_query->replaceDatabaseAndTable(storage_src->getRemoteDatabaseName(), storage_src->getRemoteTableName()); |
| 787 | |
| 788 | new_query->select = select_with_union_query; |
| 789 | } |
| 790 | } |
| 791 | } |
| 792 | } |
| 793 | |
| 794 | if (!storage_src || storage_src->getClusterName() != getClusterName()) |
| 795 | { |
| 796 | return nullptr; |
| 797 | } |
| 798 | |
| 799 | if (settings.parallel_distributed_insert_select == PARALLEL_DISTRIBUTED_INSERT_SELECT_ALL |
| 800 | || settings.distributed_perfect_shard) |
| 801 | { |
| 802 | new_query->table_id = StorageID(getRemoteDatabaseName(), getRemoteTableName()); |
| 803 | } |
| 804 | |
| 805 | const auto & cluster = getCluster(); |
| 806 | const auto & shards_info = cluster->getShardsInfo(); |
| 807 | |
| 808 | std::vector<std::unique_ptr<QueryPipeline>> pipelines; |
| 809 | |
| 810 | String new_query_str = queryToString(new_query); |
| 811 | LOG_TRACE(log, "Parallel insert query: {}", new_query_str); |
| 812 | |
| 813 | for (size_t shard_index : collections::range(0, shards_info.size())) |
| 814 | { |
| 815 | const auto & shard_info = shards_info[shard_index]; |
| 816 | if (shard_info.isLocal()) |
| 817 | { |
| 818 | InterpreterInsertQuery interpreter(new_query, local_context); |
| 819 | pipelines.emplace_back(std::make_unique<QueryPipeline>(interpreter.execute().pipeline)); |
| 820 | } |
nothing calls this directly
no test coverage detected