protected virtual IQueryPlanNode VisitNaturalJoin(NaturalJoinNode node) { var left = node.Left; var right = node.Right; if (left != null) { left = VisitNode(left); } if (right != null) { right = VisitNode(right); } return(new NaturalJoinNode(left, right)); }
private TablePlan NaturallyJoinPlans(TablePlan plan1, TablePlan plan2) { JoinType joinType; SqlExpression onExpr; TablePlan leftPlan, rightPlan; // Are the plans linked by common join information? if (plan1.RightPlan == plan2) { joinType = plan1.RightJoinType; onExpr = plan1.RightOnExpression; leftPlan = plan1; rightPlan = plan2; } else if (plan1.LeftPlan == plan2) { joinType = plan1.LeftJoinType; onExpr = plan1.LeftOnExpression; leftPlan = plan2; rightPlan = plan1; } else { // Assertion - make sure no join clashes! if ((plan1.LeftPlan != null && plan2.LeftPlan != null) || (plan1.RightPlan != null && plan2.RightPlan != null)) { throw new InvalidOperationException("Plans can not be naturally join because " + "the left/right join plans clash."); } // Else we must assume a non-dependent join (not an outer join). // Perform a natural join IQueryPlanNode node1 = new NaturalJoinNode(plan1.Plan, plan2.Plan); return MergePlans(plan1, plan2, node1); } // This means plan1 and plan2 are linked by a common join and ON // expression which we evaluate now. bool outerJoin; if (joinType == JoinType.Left) { // Mark the left plan leftPlan.UpdatePlan(new MarkerNode(leftPlan.Plan, "OUTER_JOIN")); outerJoin = true; } else if (joinType == JoinType.Right) { // Mark the right plan rightPlan.UpdatePlan(new MarkerNode(rightPlan.Plan, "OUTER_JOIN")); outerJoin = true; } else if (joinType == JoinType.Inner) { // Inner join with ON expression outerJoin = false; } else { throw new InvalidOperationException(String.Format("Join type ({0}) is not supported.", joinType)); } // Make a Planner object for joining these plans. var planner = new QueryTablePlanner(); planner.AddPlan(leftPlan.Clone()); planner.AddPlan(rightPlan.Clone()); // Evaluate the on expression var node = planner.LogicalEvaluate(onExpr); // If outer join add the left outer join node if (outerJoin) node = new LeftOuterJoinNode(node, "OUTER_JOIN"); // And merge the plans in this set with the new node. return MergePlans(plan1, plan2, node); }
protected virtual IQueryPlanNode VisitNaturalJoin(NaturalJoinNode node) { var left = node.Left; var right = node.Right; if (left != null) left = VisitNode(left); if (right != null) right = VisitNode(right); return new NaturalJoinNode(left, right); }
private TablePlan NaturallyJoinPlans(TablePlan plan1, TablePlan plan2) { JoinType joinType; SqlExpression onExpr; TablePlan leftPlan, rightPlan; // Are the plans linked by common join information? if (plan1.RightPlan == plan2) { joinType = plan1.RightJoinType; onExpr = plan1.RightOnExpression; leftPlan = plan1; rightPlan = plan2; } else if (plan1.LeftPlan == plan2) { joinType = plan1.LeftJoinType; onExpr = plan1.LeftOnExpression; leftPlan = plan2; rightPlan = plan1; } else { // Assertion - make sure no join clashes! if ((plan1.LeftPlan != null && plan2.LeftPlan != null) || (plan1.RightPlan != null && plan2.RightPlan != null)) { throw new InvalidOperationException("Plans can not be naturally join because " + "the left/right join plans clash."); } // Else we must assume a non-dependent join (not an outer join). // Perform a natural join var node1 = new NaturalJoinNode(plan1.Plan, plan2.Plan); return(MergePlans(plan1, plan2, node1)); } // This means plan1 and plan2 are linked by a common join and ON // expression which we evaluate now. bool outerJoin; if (joinType == JoinType.Left) { // Mark the left plan leftPlan.UpdatePlan(new MarkerNode(leftPlan.Plan, "OUTER_JOIN")); outerJoin = true; } else if (joinType == JoinType.Right) { // Mark the right plan rightPlan.UpdatePlan(new MarkerNode(rightPlan.Plan, "OUTER_JOIN")); outerJoin = true; } else if (joinType == JoinType.Inner) { // Inner join with ON expression outerJoin = false; } else { throw new InvalidOperationException(String.Format("Join type ({0}) is not supported.", joinType)); } // Make a Planner object for joining these plans. var planner = new QueryTablePlanner(); planner.AddPlan(leftPlan.Clone()); planner.AddPlan(rightPlan.Clone()); // Evaluate the on expression var node = planner.LogicalEvaluate(onExpr); // If outer join add the left outer join node if (outerJoin) { node = new LeftOuterJoinNode(node, "OUTER_JOIN"); } // And merge the plans in this set with the new node. return(MergePlans(plan1, plan2, node)); }