Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        private BoundRelation PushOverProject(BoundFilterRelation node, BoundProjectRelation input)
        {
            var newFilter = RewriteRelation(node.WithInput(input.Input));
            var newInput  = input.Update(newFilter, input.Outputs);

            return(newInput);
        }
Пример #4
0
        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);
            }
        }