MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / constructTreeNode

Method constructTreeNode

src/planner/join_order/join_tree_constructor.cpp:60–132  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

58}
59
60JoinTreeConstructor::IntermediateResult JoinTreeConstructor::constructTreeNode(
61 std::shared_ptr<BoundJoinHintNode> hintNode) {
62 // Construct leaf scans.
63 if (hintNode->isLeaf()) {
64 if (ExpressionUtil::isNodePattern(*hintNode->nodeOrRel)) {
65 return constructNodeScan(hintNode->nodeOrRel);
66 } else {
67 DASSERT(ExpressionUtil::isRelPattern(*hintNode->nodeOrRel) ||
68 ExpressionUtil::isRecursiveRelPattern(*hintNode->nodeOrRel));
69 return constructRelScan(hintNode->nodeOrRel);
70 }
71 }
72 // Construct binary join.
73 if (hintNode->isBinary()) {
74 auto left = constructTreeNode(hintNode->children[0]);
75 auto right = constructTreeNode(hintNode->children[1]);
76 auto joinNodes = getJoinNodes(left.subqueryGraph, right.subqueryGraph);
77 if (joinNodes.empty()) {
78 joinNodes = getJoinNodes(right.subqueryGraph, left.subqueryGraph);
79 }
80 if (joinNodes.empty()) {
81 throw BinderException(std::format("Cannot resolve join condition between {} and {}.",
82 left.treeNode->toString(), right.treeNode->toString()));
83 }
84 auto newSubgraph = left.subqueryGraph;
85 newSubgraph.addSubqueryGraph(right.subqueryGraph);
86 auto predicates = Planner::getNewlyMatchedExprs(left.subqueryGraph, right.subqueryGraph,
87 newSubgraph, queryGraphPredicates);
88 // First try to construct as index nested loop join.
89 auto nestedLoopTreeNode =
90 tryConstructNestedLoopJoin(joinNodes, *left.treeNode, *right.treeNode, predicates);
91 if (nestedLoopTreeNode != nullptr) {
92 return {nestedLoopTreeNode, newSubgraph};
93 }
94 // Cannot construct index nested loop join. Fall back to hash join.
95 auto extraInfo = std::make_unique<ExtraJoinTreeNodeInfo>(joinNodes);
96 extraInfo->predicates = predicates;
97 auto treeNode =
98 std::make_shared<JoinTreeNode>(TreeNodeType::BINARY_JOIN, std::move(extraInfo));
99 treeNode->addChild(left.treeNode);
100 treeNode->addChild(right.treeNode);
101 return {treeNode, newSubgraph};
102 }
103 // Construct multi-way join
104 DASSERT(hintNode->isMultiWay());
105 auto probe = constructTreeNode(hintNode->children[0]);
106 auto newSubgraph = probe.subqueryGraph;
107 std::vector<std::shared_ptr<JoinTreeNode>> childrenNodes;
108 childrenNodes.push_back(probe.treeNode);
109 std::vector<SubqueryGraph> buildSubgraphs;
110 for (auto i = 1u; i < hintNode->children.size(); ++i) {
111 auto build = constructTreeNode(hintNode->children[i]);
112 if (build.treeNode->type != TreeNodeType::REL_SCAN) {
113 throw BinderException(std::format(
114 "Cannot construct multi-way join because build side is not a relationship table."));
115 }
116 newSubgraph.addSubqueryGraph(build.subqueryGraph);
117 childrenNodes.push_back(build.treeNode);

Callers

nothing calls this directly

Calls 11

getJoinNodesFunction · 0.85
getIntersectNodeFunction · 0.85
addSubqueryGraphMethod · 0.80
isMultiWayMethod · 0.80
isLeafMethod · 0.45
isBinaryMethod · 0.45
emptyMethod · 0.45
toStringMethod · 0.45
addChildMethod · 0.45
push_backMethod · 0.45
sizeMethod · 0.45

Tested by

no test coverage detected