MCPcopy Create free account
hub / github.com/ClickHouse/ClickHouse / convertToDistributed

Method convertToDistributed

src/Processors/QueryPlan/QueryPlan.cpp:794–936  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

792}
793
794void QueryPlan::convertToDistributed(const QueryPlanOptimizationSettings & optimization_settings)
795{
796 SharedHeader result_header = root->step->getOutputHeader();
797
798 QueryPlan::Nodes old_nodes = std::move(nodes);
799 QueryPlan::Node * old_root = root;
800 root = nullptr;
801 auto distributed_plan = QueryPlanOptimizations::makeDistributedPlan(std::move(old_nodes), old_root, optimization_settings);
802
803 for (const auto & stage : distributed_plan.stages)
804 {
805 auto it = distributed_plan.stage_depends_on.find(stage.first);
806 const auto & dependencies = it != distributed_plan.stage_depends_on.end() ? it->second : std::unordered_map<String, String>{};
807 LOG_TRACE(getLogger("optimize"), "Distributed stage: '{}' depends on: [{}] plan:\n{}",
808 stage.first, fmt::join(dependencies, ", "), dumpQueryPlan(stage.second.query_plan_fragment));
809 }
810
811 if (distributed_plan.stages.size() == 1)
812 {
813 /// For now just replace the plan with the first and only fragment, but preserve
814 /// table locks and storage holders accumulated during planning.
815 QueryPlanResourceHolder preserved_resources = std::move(resources);
816 *this = std::move(distributed_plan.stages.begin()->second.query_plan_fragment);
817 /// QueryPlanResourceHolder's move-assignment appends rhs into lhs without dropping existing entries.
818 resources = std::move(preserved_resources);
819
820 QueryPlanOptimizationSettings local_settings = optimization_settings;
821 local_settings.make_distributed_plan = false;
822 QueryPlanOptimizations::optimizeTreeSecondPass(local_settings, *root, nodes, *this);
823 }
824 else
825 {
826 ExchangeDescription final_result_exchange
827 {
828 .name = "final_result",
829 .kind = optimization_settings.distributed_plan_force_exchange_kind == "Persisted" ? ExchangeDescription::Kind::Persisted : ExchangeDescription::Kind::Streaming,
830 .source_bucket_count = 1,
831 .destination_bucket_count = 1
832 };
833 auto result_stream_id = ExchangeStreamId(final_result_exchange.name, 0, 0);
834
835 /// Add a step that writes the result of the main stage to the file
836 auto & main_stage = distributed_plan.stages["main"];
837 if (!main_stage.query_plan_fragment.isCompleted())
838 {
839 main_stage.query_plan_fragment.addStep(std::make_unique<GatherSendStep>(result_header, final_result_exchange.name));
840 main_stage.tasks.front().output_exchange_streams.emplace_back(result_stream_id);
841 distributed_plan.exchange_descriptions[final_result_exchange.name] = final_result_exchange;
842 distributed_plan.final_result_stream_name = result_stream_id.toString();
843 }
844
845 /// Fail early (before execution) if any fragment contains a step that cannot be serialized
846 /// for remote execution, instead of throwing late from serializeQueryPlan.
847 for (const auto & [stage_name, stage] : distributed_plan.stages)
848 assertFragmentSerializable(stage.query_plan_fragment, stage_name);
849
850 /// Collect the list of all temporary files
851 Strings all_temporary_files_for_cleanup;

Callers

nothing calls this directly

Calls 15

makeDistributedPlanFunction · 0.85
dumpQueryPlanFunction · 0.85
optimizeTreeSecondPassFunction · 0.85
ExchangeStreamIdClass · 0.85
generateV4Function · 0.85
createExchangeLookupFunction · 0.85
createDelayedPipeFunction · 0.85

Tested by

no test coverage detected