Наследование: BranchQueryPlanNode
Пример #1
0
        protected virtual IQueryPlanNode VisitLogicalUnion(LogicalUnionNode node)
        {
            var left  = node.Left;
            var right = node.Right;

            if (left != null)
            {
                left = VisitNode(left);
            }
            if (right != null)
            {
                right = VisitNode(right);
            }

            return(new LogicalUnionNode(left, right));
        }
Пример #2
0
        private void PlanExpression(SqlExpression expression)
        {
            if (expression is SqlBinaryExpression &&
                expression.ExpressionType.IsLogical()) {
                var binary = (SqlBinaryExpression) expression;

                if (expression.ExpressionType == SqlExpressionType.Or) {
                    // parsing an OR block
                    // Split left and right of logical operator.
                    var exps = new[]{binary.Left, binary.Right};

                    // If we are an 'or' then evaluate left and right and union the
                    // result.

                    // Before we branch set cache points.
                    SetCachePoints();

                    // Make copies of the left and right planner
                    var leftPlanner = Clone();
                    var rightPlanner = Clone();

                    // Plan the left and right side of the OR
                    leftPlanner.PlanExpression(exps[0]);
                    rightPlanner.PlanExpression(exps[1]);

                    // Fix the left and right planner so that they represent the same
                    // 'group'.
                    // The current implementation naturally joins all sources if the
                    // number of sources is different than the original size.
                    int leftSz = leftPlanner.tablePlans.Count;
                    int rightSz = rightPlanner.tablePlans.Count;
                    if (leftSz != rightSz || leftPlanner.HasJoin || rightPlanner.HasJoin) {
                        // Naturally join all in the left and right plan
                        leftPlanner.NaturalJoinAll();
                        rightPlanner.NaturalJoinAll();
                    }

                    // Union all table sources, but only if they have changed.
                    var leftTableList = leftPlanner.tablePlans;
                    var rightTableList = rightPlanner.tablePlans;
                    int sz = leftTableList.Count;

                    // First we must determine the plans that need to be joined in the
                    // left and right plan.
                    var leftJoinList = new List<TablePlan>();
                    var rightJoinList = new List<TablePlan>();
                    for (int i = 0; i < sz; ++i) {
                        var leftPlan = leftTableList[i];
                        var rightPlan = rightTableList[i];
                        if (leftPlan.IsUpdated || rightPlan.IsUpdated) {
                            leftJoinList.Add(leftPlan);
                            rightJoinList.Add(rightPlan);
                        }
                    }

                    // Make sure the plans are joined in the left and right planners
                    leftPlanner.JoinToSingle(leftJoinList);
                    rightPlanner.JoinToSingle(rightJoinList);

                    // Since the planner lists may have changed we update them here.
                    leftTableList = leftPlanner.tablePlans;
                    rightTableList = rightPlanner.tablePlans;
                    sz = leftTableList.Count;

                    var newTableList = new List<TablePlan>(sz);

                    for (int i = 0; i < sz; ++i) {
                        var leftPlan = leftTableList[i];
                        var rightPlan = rightTableList[i];

                        TablePlan newPlan;

                        // If left and right plan updated so we need to union them
                        if (leftPlan.IsUpdated || rightPlan.IsUpdated) {
                            // In many causes, the left and right branches will contain
                            //   identical branches that would best be optimized out.

                            // Take the left plan, add the logical union to it, and make it
                            // the plan for this.
                            var node = new LogicalUnionNode(leftPlan.Plan, rightPlan.Plan);

                            // Update the plan in this table list
                            leftPlan.UpdatePlan(node);

                            newPlan = leftPlan;
                        } else {
                            // If the left and right plan didn't update, then use the
                            // left plan (it doesn't matter if we use left or right because
                            // they are the same).
                            newPlan = leftPlan;
                        }

                        // Add the left plan to the new table list we are creating
                        newTableList.Add(newPlan);

                    }

                    // Set the new table list
                    tablePlans = newTableList;
                } else if (expression.ExpressionType == SqlExpressionType.And) {
                    PlanExpressionList(new[]{binary.Left, binary.Right});
                } else {
                    throw new InvalidOperationException();
                }
            } else {
                PlanExpressionList(new []{expression});
            }
        }
Пример #3
0
        protected virtual IQueryPlanNode VisitLogicalUnion(LogicalUnionNode node)
        {
            var left = node.Left;
            var right = node.Right;
            if (left != null)
                left = VisitNode(left);
            if (right != null)
                right = VisitNode(right);

            return new LogicalUnionNode(left, right);
        }
Пример #4
0
        private void PlanExpression(SqlExpression expression)
        {
            if (expression is SqlBinaryExpression &&
                expression.ExpressionType.IsLogical())
            {
                var binary = (SqlBinaryExpression)expression;

                if (expression.ExpressionType == SqlExpressionType.Or)
                {
                    // parsing an OR block
                    // Split left and right of logical operator.
                    var exps = new[] { binary.Left, binary.Right };

                    // If we are an 'or' then evaluate left and right and union the
                    // result.

                    // Before we branch set cache points.
                    SetCachePoints();

                    // Make copies of the left and right planner
                    var leftPlanner  = Clone();
                    var rightPlanner = Clone();

                    // Plan the left and right side of the OR
                    leftPlanner.PlanExpression(exps[0]);
                    rightPlanner.PlanExpression(exps[1]);

                    // Fix the left and right planner so that they represent the same
                    // 'group'.
                    // The current implementation naturally joins all sources if the
                    // number of sources is different than the original size.
                    int leftSz  = leftPlanner.tablePlans.Count;
                    int rightSz = rightPlanner.tablePlans.Count;
                    if (leftSz != rightSz || leftPlanner.HasJoin || rightPlanner.HasJoin)
                    {
                        // Naturally join all in the left and right plan
                        leftPlanner.NaturalJoinAll();
                        rightPlanner.NaturalJoinAll();
                    }

                    // Union all table sources, but only if they have changed.
                    var leftTableList  = leftPlanner.tablePlans;
                    var rightTableList = rightPlanner.tablePlans;
                    int sz             = leftTableList.Count;

                    // First we must determine the plans that need to be joined in the
                    // left and right plan.
                    var leftJoinList  = new List <TablePlan>();
                    var rightJoinList = new List <TablePlan>();
                    for (int i = 0; i < sz; ++i)
                    {
                        var leftPlan  = leftTableList[i];
                        var rightPlan = rightTableList[i];
                        if (leftPlan.IsUpdated || rightPlan.IsUpdated)
                        {
                            leftJoinList.Add(leftPlan);
                            rightJoinList.Add(rightPlan);
                        }
                    }

                    // Make sure the plans are joined in the left and right planners
                    leftPlanner.JoinToSingle(leftJoinList);
                    rightPlanner.JoinToSingle(rightJoinList);

                    // Since the planner lists may have changed we update them here.
                    leftTableList  = leftPlanner.tablePlans;
                    rightTableList = rightPlanner.tablePlans;
                    sz             = leftTableList.Count;

                    var newTableList = new List <TablePlan>(sz);

                    for (int i = 0; i < sz; ++i)
                    {
                        var leftPlan  = leftTableList[i];
                        var rightPlan = rightTableList[i];

                        TablePlan newPlan;

                        // If left and right plan updated so we need to union them
                        if (leftPlan.IsUpdated || rightPlan.IsUpdated)
                        {
                            // In many causes, the left and right branches will contain
                            //   identical branches that would best be optimized out.

                            // Take the left plan, add the logical union to it, and make it
                            // the plan for this.
                            var node = new LogicalUnionNode(leftPlan.Plan, rightPlan.Plan);

                            // Update the plan in this table list
                            leftPlan.UpdatePlan(node);

                            newPlan = leftPlan;
                        }
                        else
                        {
                            // If the left and right plan didn't update, then use the
                            // left plan (it doesn't matter if we use left or right because
                            // they are the same).
                            newPlan = leftPlan;
                        }

                        // Add the left plan to the new table list we are creating
                        newTableList.Add(newPlan);
                    }

                    // Set the new table list
                    tablePlans = newTableList;
                }
                else if (expression.ExpressionType == SqlExpressionType.And)
                {
                    PlanExpressionList(new[] { binary.Left, binary.Right });
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                PlanExpressionList(new [] { expression });
            }
        }