private BoundRelation MergeWithFilter(BoundFilterRelation node, BoundFilterRelation input) { var mergedCondition = Expression.And(input.Condition, node.Condition); var newInput = RewriteRelation(input.Update(input.Input, mergedCondition)); return(newInput); }
private BoundRelation PushOverTop(BoundFilterRelation node, BoundTopRelation input) { var newFilter = RewriteRelation(node.Update(input.Input, node.Condition)); var newInput = input.Update(newFilter, input.Limit, input.TieEntries); return(newInput); }
private BoundRelation PushOverSort(BoundFilterRelation node, BoundSortRelation input) { var newFilter = RewriteRelation(node.Update(input.Input, node.Condition)); var newInput = input.Update(input.IsDistinct, newFilter, input.SortedValues); return(newInput); }
private BoundRelation PushOverProject(BoundFilterRelation node, BoundProjectRelation input) { var newFilter = RewriteRelation(node.Update(input.Input, node.Condition)); var newInput = input.Update(newFilter, input.Outputs); return(newInput); }
protected override BoundRelation RewriteFilterRelation(BoundFilterRelation node) { var input = RewriteRelation(node.Input); var rewrittenRelation = RewriteConjunctions(input, node.Condition); if (rewrittenRelation != null) { // We might have residual subqueries that couldn't be // converted to semi joins. return(RewriteRelation(rewrittenRelation)); } // There were no subqueries that could be expressed as semi joins. // However, there might still exist subqueries, so we need to visit // the expression that will convert them to probing semi joins. var condition = RewriteExpression(node.Condition); var inputWithProbes = RewriteInputWithSubqueries(input); return(node.Update(inputWithProbes, condition)); }
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.Update(RewriteRelation(input), node.Condition)); } if (AllowsMerge(input.JoinType)) { var newCondition = Expression.And(input.Condition, node.Condition); var newInput = input.Update(input.JoinType, input.Left, input.Right, newCondition, null, null); 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); } }