| 374 | } |
| 375 | |
| 376 | QueryProcessingStage::Enum StorageMerge::getQueryProcessingStage( |
| 377 | ContextPtr local_context, |
| 378 | QueryProcessingStage::Enum to_stage, |
| 379 | const StorageSnapshotPtr &, |
| 380 | SelectQueryInfo & query_info) const |
| 381 | { |
| 382 | /// In case of JOIN or ARRAY JOIN the first stage (which includes JOIN/ARRAY JOIN) |
| 383 | /// should be done on the initiator always. |
| 384 | /// |
| 385 | /// Since in case of JOIN query on shards will receive query without JOIN (and their columns). |
| 386 | /// (see removeJoin()) |
| 387 | /// |
| 388 | /// ARRAY JOIN also requires FetchColumns because `buildQueryPlanForArrayJoinNode` expects |
| 389 | /// the child plan to be at FetchColumns stage. If we return a later stage here, |
| 390 | /// the ARRAY JOIN processing is skipped entirely in `buildJoinTreeQueryPlan` |
| 391 | /// (see the early return when stage != FetchColumns), leading to missing chunk info |
| 392 | /// in MergingAggregatedTransform. |
| 393 | /// |
| 394 | /// And for this we need to return FetchColumns. |
| 395 | if (const auto * select = query_info.query->as<ASTSelectQuery>(); select && (hasJoin(*select) || hasArrayJoin(*select))) |
| 396 | return QueryProcessingStage::FetchColumns; |
| 397 | |
| 398 | auto stage_in_source_tables = QueryProcessingStage::FetchColumns; |
| 399 | |
| 400 | DatabaseTablesIterators database_table_iterators = database_name_or_regexp.getDatabaseIterators(local_context); |
| 401 | |
| 402 | size_t selected_table_size = 0; |
| 403 | |
| 404 | for (const auto & iterator : database_table_iterators) |
| 405 | { |
| 406 | while (iterator->isValid()) |
| 407 | { |
| 408 | const auto & table = iterator->table(); |
| 409 | if (table && table.get() != this) |
| 410 | { |
| 411 | ++selected_table_size; |
| 412 | const auto table_metadata = table->getInMemoryMetadataPtr(local_context, false); |
| 413 | stage_in_source_tables = std::max( |
| 414 | stage_in_source_tables, |
| 415 | table->getQueryProcessingStage(local_context, to_stage, |
| 416 | table->getStorageSnapshot(table_metadata, local_context), query_info)); |
| 417 | } |
| 418 | |
| 419 | iterator->next(); |
| 420 | } |
| 421 | } |
| 422 | |
| 423 | auto stage = selected_table_size == 1 ? stage_in_source_tables : std::min(stage_in_source_tables, QueryProcessingStage::WithMergeableState); |
| 424 | |
| 425 | /// Caller asked for WithMergeableState but a child reported a higher stage |
| 426 | /// (e.g. Distributed with `distributed_group_by_no_merge=1` reports Complete). |
| 427 | /// Cap to WithMergeableState so we don't emit finalized values where the caller |
| 428 | /// expects AggregateFunction states - otherwise `convertAndFilterSourceStream` |
| 429 | /// throws CANNOT_CONVERT_TYPE. The multi-table branch above already caps at |
| 430 | /// WithMergeableState for the same reason; this extends it to the single-table branch. |
| 431 | /// |
| 432 | /// Only when the caller asked for exactly WithMergeableState: for FetchColumns the |
| 433 | /// caller wants raw columns, the child's higher stage (Complete from a single-shard |
no test coverage detected