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

Function buildQueryTreeForShard

src/Storages/buildQueryTreeForShard.cpp:601–733  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

599}
600
601QueryTreeNodePtr buildQueryTreeForShard(const PlannerContextPtr & planner_context, QueryTreeNodePtr query_tree_to_modify, bool allow_global_join_for_right_table)
602{
603 CollectColumnSourceToColumnsVisitor collect_column_source_to_columns_visitor;
604 collect_column_source_to_columns_visitor.visit(query_tree_to_modify);
605
606 const auto & column_source_to_columns = collect_column_source_to_columns_visitor.getColumnSourceToColumns();
607
608 DistributedProductModeRewriteInJoinVisitor visitor(planner_context->getQueryContext());
609 visitor.visit(query_tree_to_modify);
610
611 auto replacement_map = visitor.getReplacementMap();
612 const auto & global_in_or_join_nodes = visitor.getGlobalInOrJoinNodes();
613
614 QueryTreeNodePtrWithHashMap<TableNodePtr> global_in_temporary_tables;
615
616 bool enable_add_distinct_to_in_subqueries = planner_context->getQueryContext()->getSettingsRef()[Setting::enable_add_distinct_to_in_subqueries];
617
618 for (const auto & global_in_or_join_node : global_in_or_join_nodes)
619 {
620 if (auto * join_node = global_in_or_join_node.query_node->as<JoinNode>())
621 {
622 QueryTreeNodePtr join_table_expression;
623 const auto join_kind = join_node->getKind();
624 if (!allow_global_join_for_right_table || join_kind == JoinKind::Left || join_kind == JoinKind::Inner)
625 {
626 join_table_expression = join_node->getRightTableExpression();
627 }
628 else if (join_kind == JoinKind::Right)
629 {
630 join_table_expression = join_node->getLeftTableExpression();
631 }
632 else
633 {
634 throw Exception(ErrorCodes::INCOMPATIBLE_TYPE_OF_JOIN, "Unexpected global join kind: {}", toString(join_kind));
635 }
636
637 auto subquery_node = getSubqueryFromTableExpression(join_table_expression, column_source_to_columns, planner_context->getQueryContext());
638
639 auto temporary_table_expression_node = executeSubqueryNode(subquery_node,
640 planner_context->getMutableQueryContext(),
641 global_in_or_join_node.subquery_depth);
642 temporary_table_expression_node->setAlias(join_table_expression->getAlias());
643
644 /** When a compound node like ARRAY_JOIN is replaced, its descendants (e.g., the inner TABLE)
645 * are not traversed by cloneAndReplace. Column nodes that reference these descendants
646 * as their source would get dangling weak pointers when the original tree is released.
647 * Map all descendants of the replaced node to the temporary table so that
648 * weak pointer updates in cloneAndReplace can find them.
649 */
650 std::vector<const IQueryTreeNode *> descendants_to_map;
651 for (const auto & child : join_table_expression->getChildren())
652 if (child)
653 descendants_to_map.push_back(child.get());
654
655 while (!descendants_to_map.empty())
656 {
657 const auto * descendant = descendants_to_map.back();
658 descendants_to_map.pop_back();

Calls 15

executeSubqueryNodeFunction · 0.85
addDistinctRecursivelyFunction · 0.85
getNodesMethod · 0.80
cloneAndReplaceMethod · 0.80
clearSettingsChangesMethod · 0.80
toStringFunction · 0.70
ExceptionClass · 0.50
visitMethod · 0.45

Tested by

no test coverage detected