| 2082 | } |
| 2083 | |
| 2084 | void InterpreterSelectQuery::executeFetchColumns(QueryProcessingStage::Enum processing_stage, QueryPlan & query_plan) |
| 2085 | { |
| 2086 | auto & query = getSelectQuery(); |
| 2087 | const Settings & settings = context->getSettingsRef(); |
| 2088 | |
| 2089 | /// Optimization for trivial query like SELECT count() FROM table. |
| 2090 | bool optimize_trivial_count = |
| 2091 | syntax_analyzer_result->optimize_trivial_count |
| 2092 | && (settings.max_parallel_replicas <= 1) |
| 2093 | && storage |
| 2094 | && storage->getName() != "MaterializeMySQL" |
| 2095 | && !row_policy_filter |
| 2096 | /* |
| 2097 | ** Trivial count optimization for StorageCnchMergeTree. In original Clickhouse implementation, |
| 2098 | ** high-level storage cannot support trival count, but StorageCnchMergeTree is special because it |
| 2099 | ** HAS own metadata. |
| 2100 | */ |
| 2101 | && (processing_stage == QueryProcessingStage::FetchColumns || storage->supportsTrivialCount()) |
| 2102 | && query_analyzer->hasAggregation() |
| 2103 | && (query_analyzer->aggregates().size() == 1) |
| 2104 | && typeid_cast<const AggregateFunctionCount *>(query_analyzer->aggregates()[0].function.get()) |
| 2105 | /* |
| 2106 | ** disable optimize_trival_count since distributed_stages mode cannot read data from local. |
| 2107 | */ |
| 2108 | && !options.distributed_stages; |
| 2109 | |
| 2110 | if (optimize_trivial_count) |
| 2111 | { |
| 2112 | const auto & desc = query_analyzer->aggregates()[0]; |
| 2113 | const auto & func = desc.function; |
| 2114 | std::optional<UInt64> num_rows{}; |
| 2115 | |
| 2116 | if (!query.prewhere() && !query.where() && !query_info.partition_filter && atomic_predicates_expr.empty()) |
| 2117 | { |
| 2118 | num_rows = storage->totalRows(context); |
| 2119 | } |
| 2120 | else // It's possible to optimize count() given only partition predicates |
| 2121 | { |
| 2122 | SelectQueryInfo temp_query_info; |
| 2123 | temp_query_info.query = query_ptr; |
| 2124 | temp_query_info.syntax_analyzer_result = syntax_analyzer_result; |
| 2125 | temp_query_info.sets = query_analyzer->getPreparedSets(); |
| 2126 | if (query_info.partition_filter) |
| 2127 | temp_query_info.partition_filter = query_info.partition_filter->clone(); |
| 2128 | temp_query_info.atomic_predicates_expr = atomic_predicates_expr; |
| 2129 | |
| 2130 | num_rows = storage->totalRowsByPartitionPredicate(temp_query_info, context); |
| 2131 | } |
| 2132 | |
| 2133 | if (num_rows) |
| 2134 | { |
| 2135 | const AggregateFunctionCount & agg_count = static_cast<const AggregateFunctionCount &>(*func); |
| 2136 | |
| 2137 | /// We will process it up to "WithMergeableState". |
| 2138 | std::vector<char> state(agg_count.sizeOfData()); |
| 2139 | AggregateDataPtr place = state.data(); |
| 2140 | |
| 2141 | agg_count.create(place); |
nothing calls this directly
no test coverage detected