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

Method visitFunction

src/Planner/PlannerActionsVisitor.cpp:1191–1321  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1189}
1190
1191PlannerActionsVisitorImpl::NodeNameAndNodeMinLevel PlannerActionsVisitorImpl::visitFunction(const QueryTreeNodePtr & node)
1192{
1193 const auto & function_node = node->as<FunctionNode &>();
1194
1195 if (function_node.getFunctionName() == "indexHint")
1196 return visitIndexHintFunction(node);
1197 if (function_node.getFunctionName() == "exists")
1198 return visitExistsFunction(node);
1199
1200 std::optional<NodeNameAndNodeMinLevel> in_function_second_argument_node_name_with_level;
1201
1202 if (isNameOfInFunction(function_node.getFunctionName()))
1203 in_function_second_argument_node_name_with_level = makeSetForInFunction(node);
1204
1205 auto function_node_name = action_node_name_helper.calculateActionNodeName(node);
1206
1207 /* Aggregate functions, window functions, and GROUP BY expressions were already analyzed in the previous steps.
1208 * If we have already visited some expression, we don't need to revisit it or its arguments again.
1209 * For example, the expression from the aggregation step is also present in the projection:
1210 * SELECT foo(a, b, c) as x FROM table GROUP BY foo(a, b, c)
1211 * In this case we should not analyze `a`, `b`, `c` again.
1212 * Moreover, it can lead to an error if we have arrayJoin in the arguments because it will be calculated twice.
1213 *
1214 * The expression can also be present as a constant COLUMN node: when a GROUP BY key expression
1215 * is constant-foldable, the aggregation step exposes it as a constant column, and the ActionsDAG
1216 * constructor duplicates constant inputs as COLUMN nodes. Visiting the arguments in this case can
1217 * lead to an error: for example, after aggregation with group_by_use_nulls, GROUP BY key constants
1218 * are wrapped into Nullable but keep their names, and a lambda capture built over such a constant
1219 * fails with a type mismatch.
1220 */
1221 bool is_input_node = function_node.isAggregateFunction() || function_node.isWindowFunction()
1222 || actions_stack.front().containsInputOrConstantNode(function_node_name);
1223 if (is_input_node)
1224 {
1225 size_t actions_stack_size = actions_stack.size();
1226
1227 for (size_t i = 0; i < actions_stack_size; ++i)
1228 {
1229 auto & actions_stack_node = actions_stack[i];
1230 actions_stack_node.addInputColumnIfNecessary(function_node_name, function_node.getResultType());
1231 }
1232
1233 return {function_node_name, Levels(0)};
1234 }
1235
1236 const auto & function_arguments = function_node.getArguments().getNodes();
1237 size_t function_arguments_size = function_arguments.size();
1238
1239 Names function_arguments_node_names;
1240 function_arguments_node_names.reserve(function_arguments_size);
1241
1242 Levels levels(0);
1243 for (size_t function_argument_index = 0; function_argument_index < function_arguments_size; ++function_argument_index)
1244 {
1245 if (in_function_second_argument_node_name_with_level && function_argument_index == 1)
1246 {
1247 auto & [node_name, node_levels] = *in_function_second_argument_node_name_with_level;
1248 function_arguments_node_names.push_back(std::move(node_name));

Callers

nothing calls this directly

Calls 15

isNameOfInFunctionFunction · 0.85
LevelsClass · 0.85
getNodesMethod · 0.80
getNodeOrThrowMethod · 0.80
getArgumentTypesMethod · 0.80
ExceptionClass · 0.50
getFunctionNameMethod · 0.45

Tested by

no test coverage detected