public override AlgebraNode VisitJoinAlgebraNode(JoinAlgebraNode node) { // Get declared tables of left and right RowBufferEntry[] leftDefinedValues = AstUtil.GetDefinedValueEntries(node.Left); RowBufferEntry[] rightDefinedValues = AstUtil.GetDefinedValueEntries(node.Right); // Analyze AND-parts of Condition if (node.Predicate != null) { List <ExpressionNode> leftAndParts = new List <ExpressionNode>(); List <ExpressionNode> rightAndParts = new List <ExpressionNode>(); List <ExpressionNode> remainingAndParts = new List <ExpressionNode>(); foreach (ExpressionNode andPart in AstUtil.SplitCondition(LogicalOperator.And, node.Predicate)) { // Check if we can push this AND-part down. if (AstUtil.AllowsLeftPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, rightDefinedValues)) { leftAndParts.Add(andPart); } else if (AstUtil.AllowsRightPushDown(node.Op) && AstUtil.ExpressionDoesNotReference(andPart, leftDefinedValues)) { rightAndParts.Add(andPart); } else { remainingAndParts.Add(andPart); } } if (leftAndParts.Count > 0) { node.Left = GetFilterFromAndParts(leftAndParts, node.Left); } if (rightAndParts.Count > 0) { node.Right = GetFilterFromAndParts(rightAndParts, node.Right); } node.Predicate = AstUtil.CombineConditions(LogicalOperator.And, remainingAndParts); } // Visit children node.Left = VisitAlgebraNode(node.Left); node.Right = VisitAlgebraNode(node.Right); return(node); }