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

Function analyzeAggregation

src/Planner/PlannerExpressionAnalysis.cpp:131–306  ·  view source on GitHub ↗

Construct aggregation analysis result if query tree has GROUP BY or aggregates. * Actions before aggregation are added into actions chain, if result is not null optional. */

Source from the content-addressed store, hash-verified

129 * Actions before aggregation are added into actions chain, if result is not null optional.
130 */
131std::optional<AggregationAnalysisResult> analyzeAggregation(
132 const QueryTreeNodePtr & query_tree,
133 const ColumnsWithTypeAndName & input_columns,
134 const PlannerContextPtr & planner_context,
135 const ColumnNodePtrWithHashSet & correlated_columns_set,
136 ActionsChain & actions_chain)
137{
138 auto & query_node = query_tree->as<QueryNode &>();
139
140 auto aggregate_function_nodes = collectAggregateFunctionNodes(query_tree);
141 auto aggregates_descriptions = extractAggregateDescriptions(aggregate_function_nodes, *planner_context);
142
143 ColumnsWithTypeAndName available_columns_after_aggregation;
144 available_columns_after_aggregation.reserve(aggregates_descriptions.size());
145 for (auto & aggregate_description : aggregates_descriptions)
146 available_columns_after_aggregation.emplace_back(nullptr, aggregate_description.function->getResultType(), aggregate_description.column_name);
147
148 Names aggregation_keys;
149
150 ActionsAndProjectInputsFlagPtr before_aggregation_actions = std::make_shared<ActionsAndProjectInputsFlag>();
151 /// Here it is OK to materialize const columns: if column is used in GROUP BY, it may be expected to become non-const
152 /// See https://github.com/ClickHouse/ClickHouse/issues/70655 for example
153 before_aggregation_actions->dag = ActionsDAG(input_columns, false);
154 before_aggregation_actions->dag.getOutputs().clear();
155
156 std::unordered_set<std::string_view> before_aggregation_actions_output_node_names;
157
158 GroupingSetsParamsList grouping_sets_parameters_list;
159 bool group_by_with_constant_keys = false;
160
161 PlannerActionsVisitor actions_visitor(planner_context, correlated_columns_set);
162
163 /// Add expressions from GROUP BY
164 bool group_by_use_nulls = planner_context->getQueryContext()->getSettingsRef()[Setting::group_by_use_nulls]
165 && (query_node.isGroupByWithGroupingSets() || query_node.isGroupByWithRollup() || query_node.isGroupByWithCube());
166
167 bool is_secondary_query = planner_context->getQueryContext()->getClientInfo().query_kind == ClientInfo::QueryKind::SECONDARY_QUERY;
168 bool is_distributed_query = planner_context->getQueryContext()->isDistributed();
169 bool check_constants_for_group_by_key = is_secondary_query || is_distributed_query;
170
171 if (query_node.hasGroupBy())
172 {
173 if (query_node.isGroupByWithGroupingSets())
174 {
175 for (auto & grouping_set_keys_list_node : query_node.getGroupBy().getNodes())
176 {
177 auto & grouping_set_keys_list_node_typed = grouping_set_keys_list_node->as<ListNode &>();
178 grouping_sets_parameters_list.emplace_back();
179 auto & grouping_sets_parameters = grouping_sets_parameters_list.back();
180
181 for (auto & grouping_set_key_node : grouping_set_keys_list_node_typed.getNodes())
182 {
183 const auto * constant_key = grouping_set_key_node->as<ConstantNode>();
184 group_by_with_constant_keys |= (constant_key != nullptr);
185
186 if (constant_key && !aggregates_descriptions.empty() && (!check_constants_for_group_by_key || canRemoveConstantFromGroupByKey(*constant_key)))
187 continue;
188

Callers 2

ExpressionAnalyzerMethod · 0.85

Calls 15

isGroupByWithRollupMethod · 0.80
isGroupByWithCubeMethod · 0.80
isDistributedMethod · 0.80
hasGroupByMethod · 0.80
getNodesMethod · 0.80
assertEmptyMethod · 0.80
ActionsDAGClass · 0.70

Tested by

no test coverage detected