private BoundRelation PushOverSort(BoundFilterRelation node, BoundSortRelation input) { var newFilter = RewriteRelation(node.WithInput(input.Input)); var newInput = input.Update(input.IsDistinct, newFilter, input.SortedValues); return(newInput); }
private BoundRelation PushOverTop(BoundFilterRelation node, BoundTopRelation input) { var newFilter = RewriteRelation(node.WithInput(input.Input)); var newInput = input.Update(newFilter, input.Limit, input.TieEntries); return(newInput); }
private BoundRelation PushOverProject(BoundFilterRelation node, BoundProjectRelation input) { var newFilter = RewriteRelation(node.WithInput(input.Input)); var newInput = input.Update(newFilter, input.Outputs); return(newInput); }
private BoundRelation MergeWithOrPushOverJoin(BoundFilterRelation node, BoundJoinRelation input) { // TODO: Right now, we're not pushing over a join if it has any probing. // // That might be too restristive. It should be OK to push a over // a join to the side that isn't affecting the probe column. // // In other words: // // * pushing to the left is OK if it's a left (anti) semi join // * pushing to the right is OK if it's a right (anti) semi join if (input.Probe != null) { return(node.WithInput(RewriteRelation(input))); } if (AllowsMerge(input.JoinType)) { var newCondition = Expression.And(input.Condition, node.Condition); var newInput = input.WithCondition(newCondition); return(RewriteRelation(newInput)); } else { BoundExpression pushedLeft = null; BoundExpression pushedRight = null; BoundExpression remainder = null; foreach (var conjunction in Expression.SplitConjunctions(node.Condition)) { if (AllowsLeftPushOver(input.JoinType) && !conjunction.DependsOnAny(input.Right.GetOutputValues())) { pushedLeft = Expression.And(pushedLeft, conjunction); } else if (AllowsRightPushOver(input.JoinType) && !conjunction.DependsOnAny(input.Left.GetOutputValues())) { pushedRight = Expression.And(pushedRight, conjunction); } else { remainder = Expression.And(remainder, conjunction); } } var newLeft = pushedLeft == null ? input.Left : new BoundFilterRelation(input.Left, pushedLeft); var newRight = pushedRight == null ? input.Right : new BoundFilterRelation(input.Right, pushedRight); var newInput = input.Update(input.JoinType, RewriteRelation(newLeft), RewriteRelation(newRight), input.Condition, RewriteValueSlot(input.Probe), RewriteExpression(input.PassthruPredicate)); var newNode = remainder == null ? (BoundRelation)newInput : node.Update(newInput, remainder); return(newNode); } }