| 306 | |
| 307 | |
| 308 | void InterpreterSelectWithUnionQuery::buildQueryPlan(QueryPlan & query_plan) |
| 309 | { |
| 310 | size_t num_plans = nested_interpreters.size(); |
| 311 | const Settings & settings = context->getSettingsRef(); |
| 312 | |
| 313 | auto local_limits = getStorageLimits(*context, options); |
| 314 | storage_limits.emplace_back(local_limits); |
| 315 | for (auto & interpreter : nested_interpreters) |
| 316 | interpreter->addStorageLimits(storage_limits); |
| 317 | |
| 318 | /// Skip union for single interpreter. |
| 319 | if (num_plans == 1) |
| 320 | { |
| 321 | nested_interpreters.front()->buildQueryPlan(query_plan); |
| 322 | } |
| 323 | else |
| 324 | { |
| 325 | std::vector<std::unique_ptr<QueryPlan>> plans(num_plans); |
| 326 | SharedHeaders headers(num_plans); |
| 327 | |
| 328 | for (size_t i = 0; i < num_plans; ++i) |
| 329 | { |
| 330 | plans[i] = std::make_unique<QueryPlan>(); |
| 331 | nested_interpreters[i]->buildQueryPlan(*plans[i]); |
| 332 | |
| 333 | if (!blocksHaveEqualStructure(*plans[i]->getCurrentHeader(), *result_header)) |
| 334 | { |
| 335 | auto actions_dag = ActionsDAG::makeConvertingActions( |
| 336 | plans[i]->getCurrentHeader()->getColumnsWithTypeAndName(), |
| 337 | result_header->getColumnsWithTypeAndName(), |
| 338 | ActionsDAG::MatchColumnsMode::Position, |
| 339 | context); |
| 340 | auto converting_step = std::make_unique<ExpressionStep>(plans[i]->getCurrentHeader(), std::move(actions_dag)); |
| 341 | converting_step->setStepDescription("Conversion before UNION"); |
| 342 | plans[i]->addStep(std::move(converting_step)); |
| 343 | } |
| 344 | |
| 345 | headers[i] = plans[i]->getCurrentHeader(); |
| 346 | } |
| 347 | |
| 348 | auto max_threads = getMaxThreadsForAvailableMemory( |
| 349 | settings[Setting::max_threads], settings[Setting::max_threads_min_free_memory_per_thread]); |
| 350 | auto union_step = std::make_unique<UnionStep>(std::move(headers), max_threads, /* allow_narrowing = */ true); |
| 351 | |
| 352 | query_plan.unitePlans(std::move(union_step), std::move(plans)); |
| 353 | |
| 354 | const auto & query = query_ptr->as<ASTSelectWithUnionQuery &>(); |
| 355 | if (query.union_mode == SelectUnionMode::UNION_DISTINCT) |
| 356 | { |
| 357 | /// Add distinct transform |
| 358 | SizeLimits limits(settings[Setting::max_rows_in_distinct], settings[Setting::max_bytes_in_distinct], settings[Setting::distinct_overflow_mode]); |
| 359 | |
| 360 | auto distinct_step = std::make_unique<DistinctStep>( |
| 361 | query_plan.getCurrentHeader(), |
| 362 | limits, |
| 363 | 0, |
| 364 | result_header->getNames(), |
| 365 | false); |
nothing calls this directly
no test coverage detected