상속: SingleQueryPlanNode
예제 #1
0
        protected virtual IQueryPlanNode VisitLeftOuterJoin(LeftOuterJoinNode node)
        {
            var child = node.Child;

            if (child != null)
            {
                child = VisitNode(child);
            }

            return(new LeftOuterJoinNode(child, node.MarkerName));
        }
예제 #2
0
        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);
        }
예제 #3
0
        protected virtual IQueryPlanNode VisitLeftOuterJoin(LeftOuterJoinNode node)
        {
            var child = node.Child;
            if (child != null)
                child = VisitNode(child);

            return new LeftOuterJoinNode(child, node.MarkerName);
        }
예제 #4
0
        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));
        }