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)); }
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}); } }
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); }
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 }); } }