| 2714 | } |
| 2715 | |
| 2716 | void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum processing_stage, QueryPlan & query_plan) |
| 2717 | { |
| 2718 | auto & query = getSelectQuery(); |
| 2719 | const Settings & settings = context->getSettingsRef(); |
| 2720 | std::optional<UInt64> num_rows; |
| 2721 | |
| 2722 | /// Optimization for trivial query like SELECT count() FROM table. |
| 2723 | if (processing_stage == QueryProcessingStage::FetchColumns && (num_rows = getTrivialCount(settings[Setting::allow_experimental_parallel_reading_from_replicas]))) |
| 2724 | { |
| 2725 | const auto & desc = query_analyzer->aggregates()[0]; |
| 2726 | const auto & func = desc.function; |
| 2727 | const AggregateFunctionCount & agg_count = static_cast<const AggregateFunctionCount &>(*func); |
| 2728 | |
| 2729 | /// We will process it up to "WithMergeableState". |
| 2730 | std::vector<char> state(agg_count.sizeOfData()); |
| 2731 | AggregateDataPtr place = state.data(); |
| 2732 | |
| 2733 | agg_count.create(place); |
| 2734 | SCOPE_EXIT_MEMORY_SAFE(agg_count.destroy(place)); |
| 2735 | |
| 2736 | AggregateFunctionCount::set(place, *num_rows); |
| 2737 | |
| 2738 | auto column = ColumnAggregateFunction::create(func); |
| 2739 | column->insertFrom(place); |
| 2740 | |
| 2741 | Block header = analysis_result.before_aggregation->dag.getResultColumns(); |
| 2742 | size_t arguments_size = desc.argument_names.size(); |
| 2743 | DataTypes argument_types(arguments_size); |
| 2744 | for (size_t j = 0; j < arguments_size; ++j) |
| 2745 | argument_types[j] = header.getByName(desc.argument_names[j]).type; |
| 2746 | |
| 2747 | auto block_with_count = std::make_shared<const Block>(Block{ |
| 2748 | {std::move(column), std::make_shared<DataTypeAggregateFunction>(func, argument_types, desc.parameters), desc.column_name}}); |
| 2749 | |
| 2750 | auto source = std::make_shared<SourceFromSingleChunk>(block_with_count); |
| 2751 | auto prepared_count = std::make_unique<ReadFromPreparedSource>(Pipe(std::move(source))); |
| 2752 | prepared_count->setStepDescription("Optimized trivial count"); |
| 2753 | query_plan.addStep(std::move(prepared_count)); |
| 2754 | from_stage = QueryProcessingStage::WithMergeableState; |
| 2755 | analysis_result.first_stage = false; |
| 2756 | return; |
| 2757 | } |
| 2758 | |
| 2759 | /// Limitation on the number of columns to read. |
| 2760 | /// It's not applied in 'only_analyze' mode, because the query could be analyzed without removal of unnecessary columns. |
| 2761 | if (!options.only_analyze && settings[Setting::max_columns_to_read] && required_columns.size() > settings[Setting::max_columns_to_read]) |
| 2762 | throw Exception( |
| 2763 | ErrorCodes::TOO_MANY_COLUMNS, |
| 2764 | "Limit for number of columns to read exceeded. Requested: {}, maximum: {}", |
| 2765 | required_columns.size(), |
| 2766 | settings[Setting::max_columns_to_read].value); |
| 2767 | |
| 2768 | /// General limit for the number of threads. |
| 2769 | size_t max_threads_execute_query = getMaxThreadsForAvailableMemory( |
| 2770 | settings[Setting::max_threads], settings[Setting::max_threads_min_free_memory_per_thread]); |
| 2771 | |
| 2772 | /** |
| 2773 | * To simultaneously query more remote servers when async_socket_for_remote is off |
nothing calls this directly
no test coverage detected