Deveel.Data.Sql.Query.QueryTablePlanner.PlanExpression C# (CSharp) Method

PlanExpression() private method

private PlanExpression ( SqlExpression expression ) : void
expression Deveel.Data.Sql.Expressions.SqlExpression
return void
        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});
            }
        }

Usage Example

コード例 #1
0
 public override void AddToPlanTree()
 {
     planner.PlanExpression(expression);
 }