/// <summary>
        ///     Helper method for removing redundant constant keys from GroupByOp and DistictOp.
        ///     It only examines the keys defined in the given varDefListNode.
        ///     It removes all constant and null keys that are not referenced elsewhere,
        ///     but ensuring that at least one key is left.
        ///     It should not be called with empty keyVec.
        /// </summary>
        /// <param name="keyVec"> The keys </param>
        /// <param name="outputVec"> The var vec that needs to be updated along with the keys </param>
        /// <param name="varDefListNode"> Var def list node for the keys </param>
        private void RemoveRedundantConstantKeys(VarVec keyVec, VarVec outputVec, Node varDefListNode)
        {
            //Find all the keys that are nulls and constants
            var constantKeys = varDefListNode.Children.Where(
                d => d.Op.OpType == OpType.VarDef &&
                PlanCompilerUtil.IsConstantBaseOp(d.Child0.Op.OpType)).ToList();

            var constantKeyVars = m_command.CreateVarVec(constantKeys.Select(d => ((VarDefOp)d.Op).Var));

            //Get the list of unreferenced  constant keys
            constantKeyVars.Minus(m_referencedVars);

            //Remove the unreferenced constant keys
            keyVec.Minus(constantKeyVars);
            outputVec.Minus(constantKeyVars);

            varDefListNode.Children.RemoveAll(c => constantKeys.Contains(c) && constantKeyVars.IsSet(((VarDefOp)c.Op).Var));

            //If no keys are left add one.
            if (keyVec.Count == 0)
            {
                var keyNode = constantKeys.First();
                var keyVar  = ((VarDefOp)keyNode.Op).Var;
                keyVec.Set(keyVar);
                outputVec.Set(keyVar);
                varDefListNode.Children.Add(keyNode);
            }
        }
Exemple #2
0
        private void RemoveRedundantConstantKeys(VarVec keyVec, VarVec outputVec, System.Data.Entity.Core.Query.InternalTrees.Node varDefListNode)
        {
            List <System.Data.Entity.Core.Query.InternalTrees.Node> constantKeys = varDefListNode.Children.Where <System.Data.Entity.Core.Query.InternalTrees.Node>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, bool>)(d =>
            {
                if (d.Op.OpType == OpType.VarDef)
                {
                    return(PlanCompilerUtil.IsConstantBaseOp(d.Child0.Op.OpType));
                }
                return(false);
            })).ToList <System.Data.Entity.Core.Query.InternalTrees.Node>();
            VarVec constantKeyVars = this.m_command.CreateVarVec(constantKeys.Select <System.Data.Entity.Core.Query.InternalTrees.Node, Var>((Func <System.Data.Entity.Core.Query.InternalTrees.Node, Var>)(d => ((VarDefOp)d.Op).Var)));

            constantKeyVars.Minus(this.m_referencedVars);
            keyVec.Minus(constantKeyVars);
            outputVec.Minus(constantKeyVars);
            varDefListNode.Children.RemoveAll((Predicate <System.Data.Entity.Core.Query.InternalTrees.Node>)(c =>
            {
                if (constantKeys.Contains(c))
                {
                    return(constantKeyVars.IsSet(((VarDefOp)c.Op).Var));
                }
                return(false);
            }));
            if (keyVec.Count != 0)
            {
                return;
            }
            System.Data.Entity.Core.Query.InternalTrees.Node node = constantKeys.First <System.Data.Entity.Core.Query.InternalTrees.Node>();
            Var var = ((VarDefOp)node.Op).Var;

            keyVec.Set(var);
            outputVec.Set(var);
            varDefListNode.Children.Add(node);
        }
Exemple #3
0
        internal static System.Data.Entity.Core.Query.InternalTrees.Node CombinePredicates(
            System.Data.Entity.Core.Query.InternalTrees.Node predicate1,
            System.Data.Entity.Core.Query.InternalTrees.Node predicate2,
            Command command)
        {
            IEnumerable <System.Data.Entity.Core.Query.InternalTrees.Node> nodes1 = PlanCompilerUtil.BreakIntoAndParts(predicate1);
            IEnumerable <System.Data.Entity.Core.Query.InternalTrees.Node> nodes2 = PlanCompilerUtil.BreakIntoAndParts(predicate2);

            System.Data.Entity.Core.Query.InternalTrees.Node node1 = predicate1;
            foreach (System.Data.Entity.Core.Query.InternalTrees.Node other in nodes2)
            {
                bool flag = false;
                foreach (System.Data.Entity.Core.Query.InternalTrees.Node node2 in nodes1)
                {
                    if (node2.IsEquivalent(other))
                    {
                        flag = true;
                        break;
                    }
                }
                if (!flag)
                {
                    node1 = command.CreateNode((Op)command.CreateConditionalOp(OpType.And), node1, other);
                }
            }
            return(node1);
        }
        public override void Visit(FunctionOp op, Node n)
        {
            VisitDefault(n);
            if (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                return;
            }

            if (n.Children.Count > 1)
            {
                return;
            }

            GroupAggregateVarInfo referencedGroupAggregateVarInfo;
            Node templateNode;
            bool isUnnested;

            if (GroupAggregateVarComputationTranslator.TryTranslateOverGroupAggregateVar(
                    n.Child0, false, _command, _groupAggregateVarInfoManager, out referencedGroupAggregateVarInfo, out templateNode,
                    out isUnnested)
                &&
                (isUnnested || AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, referencedGroupAggregateVarInfo.GroupAggregateVar)))
            {
                referencedGroupAggregateVarInfo.CandidateAggregateNodes.Add(new KeyValuePair <Node, List <Node> >(n, new List <Node> {
                    templateNode
                }));
            }
        }
Exemple #5
0
        public override Node Visit(FunctionOp op, Node n)
        {
            this.VisitScalarOpDefault((ScalarOp)op, n);
            Node node = !TypeSemantics.IsCollectionType(op.Type) ? (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n) ? n : this.VisitCollectionAggregateFunction(op, n)) : this.VisitCollectionFunction(op, n);

            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(node != null, "failure to construct a functionOp?");
            return(node);
        }
Exemple #6
0
 private static bool IsConstant(System.Data.Entity.Core.Query.InternalTrees.Node node)
 {
     System.Data.Entity.Core.Query.InternalTrees.Node node1 = node;
     while (node1.Op.OpType == OpType.Cast)
     {
         node1 = node1.Child0;
     }
     return(PlanCompilerUtil.IsConstantBaseOp(node1.Op.OpType));
 }
        // <summary>
        // Determines whether the given Node is a constant subtree
        // It only recognizes any of the constant base ops
        // and possibly casts over these nodes.
        // </summary>
        private static bool IsConstant(Node node)
        {
            var currentNode = node;

            while (currentNode.Op.OpType
                   == OpType.Cast)
            {
                currentNode = currentNode.Child0;
            }
            return(PlanCompilerUtil.IsConstantBaseOp(currentNode.Op.OpType));
        }
Exemple #8
0
        public override void Visit(FunctionOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
        {
            this.VisitDefault(n);
            if (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                return;
            }
            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(n.Children.Count == 1, "Aggregate Function must have one argument");
            System.Data.Entity.Core.Query.InternalTrees.Node child0 = n.Child0;
            GroupAggregateVarInfo groupAggregateVarInfo;

            System.Data.Entity.Core.Query.InternalTrees.Node templateNode;
            bool isUnnested;

            if (!GroupAggregateVarComputationTranslator.TryTranslateOverGroupAggregateVar(n.Child0, false, this._command, this._groupAggregateVarInfoManager, out groupAggregateVarInfo, out templateNode, out isUnnested) || !isUnnested && !AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, groupAggregateVarInfo.GroupAggregateVar))
            {
                return;
            }
            groupAggregateVarInfo.CandidateAggregateNodes.Add(new KeyValuePair <System.Data.Entity.Core.Query.InternalTrees.Node, System.Data.Entity.Core.Query.InternalTrees.Node>(n, templateNode));
        }
Exemple #9
0
        public override Node Visit(FunctionOp op, Node n)
        {
            VisitScalarOpDefault(op, n);
            Node newNode = null;

            // Is this a TVF?
            if (TypeSemantics.IsCollectionType(op.Type))
            {
                newNode = VisitCollectionFunction(op, n);
            }
            // Is this a collection-aggregate function?
            else if (PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                newNode = VisitCollectionAggregateFunction(op, n);
            }
            else
            {
                newNode = n;
            }

            PlanCompiler.Assert(newNode != null, "failure to construct a functionOp?");
            return(newNode);
        }
Exemple #10
0
        public override void Visit(FunctionOp op, Node n)
        {
            VisitDefault(n);
            if (!PlanCompilerUtil.IsCollectionAggregateFunction(op, n))
            {
                return;
            }
            PlanCompiler.Assert(n.Children.Count == 1, "Aggregate Function must have one argument");

            var argumentNode = n.Child0;

            GroupAggregateVarInfo referencedGroupAggregateVarInfo;
            Node templateNode;
            bool isUnnested;

            if (GroupAggregateVarComputationTranslator.TryTranslateOverGroupAggregateVar(
                    n.Child0, false, _command, _groupAggregateVarInfoManager, out referencedGroupAggregateVarInfo, out templateNode,
                    out isUnnested)
                &&
                (isUnnested || AggregatePushdownUtil.IsVarRefOverGivenVar(templateNode, referencedGroupAggregateVarInfo.GroupAggregateVar)))
            {
                referencedGroupAggregateVarInfo.CandidateAggregateNodes.Add(new KeyValuePair <Node, Node>(n, templateNode));
            }
        }
        private static bool ProcessFilterOverJoin(RuleProcessingContext context, Node filterNode, out Node newNode)
        {
            newNode = filterNode;
            var trc = (TransformationRulesContext)context;

            //
            // Have we shut off filter pushdown for this node? Return
            //
            if (trc.IsFilterPushdownSuppressed(filterNode))
            {
                return(false);
            }

            var joinNode            = filterNode.Child0;
            var joinOp              = joinNode.Op;
            var leftInputNode       = joinNode.Child0;
            var rightInputNode      = joinNode.Child1;
            var command             = trc.Command;
            var needsTransformation = false;

            var rightTableNodeInfo = command.GetExtendedNodeInfo(rightInputNode);
            var predicate          = new Predicate(command, filterNode.Child1);
            var leftTableInfo      = command.GetExtendedNodeInfo(leftInputNode);

            //
            // Check to see if the predicate contains any "single-table-filters". In those
            // cases, we could simply push that filter down to the child.
            // We can do this for inner joins and cross joins - for both inputs.
            // For left-outer joins, however, we can only do this for the left-side input
            // Further note that we only want to do the pushdown if it will help us - if
            // the join input is a ScanTable (or some other cases), then it doesn't help us.
            //
            Node leftSingleTablePredicateNode = null;

            if (leftInputNode.Op.OpType
                != OpType.ScanTable)
            {
                var leftSingleTablePredicates = predicate.GetSingleTablePredicates(leftTableInfo.Definitions, out predicate);
                leftSingleTablePredicateNode = leftSingleTablePredicates.BuildAndTree();
            }

            Node rightSingleTablePredicateNode = null;

            if ((rightInputNode.Op.OpType != OpType.ScanTable)
                &&
                (joinOp.OpType != OpType.LeftOuterJoin))
            {
                var rightSingleTablePredicates = predicate.GetSingleTablePredicates(rightTableNodeInfo.Definitions, out predicate);
                rightSingleTablePredicateNode = rightSingleTablePredicates.BuildAndTree();
            }

            //
            // Now check to see if the predicate contains some "join predicates". We can
            // add these to the existing join predicate (if any).
            // We can only do this for inner joins and cross joins - not for LOJs
            //
            Node newJoinPredicateNode = null;

            if (joinOp.OpType == OpType.CrossJoin ||
                joinOp.OpType == OpType.InnerJoin)
            {
                var joinPredicate = predicate.GetJoinPredicates(leftTableInfo.Definitions, rightTableNodeInfo.Definitions, out predicate);
                newJoinPredicateNode = joinPredicate.BuildAndTree();
            }

            //
            // Now for the dirty work. We've identified some predicates that could be pushed
            // into the left table, some predicates that could be pushed into the right table
            // and some that could become join predicates.
            //
            if (leftSingleTablePredicateNode != null)
            {
                leftInputNode       = command.CreateNode(command.CreateFilterOp(), leftInputNode, leftSingleTablePredicateNode);
                needsTransformation = true;
            }
            if (rightSingleTablePredicateNode != null)
            {
                rightInputNode      = command.CreateNode(command.CreateFilterOp(), rightInputNode, rightSingleTablePredicateNode);
                needsTransformation = true;
            }

            // Identify the new join predicate
            if (newJoinPredicateNode != null)
            {
                needsTransformation = true;
                if (joinOp.OpType
                    == OpType.CrossJoin)
                {
                    joinOp = command.CreateInnerJoinOp();
                }
                else
                {
                    PlanCompiler.Assert(joinOp.OpType == OpType.InnerJoin, "unexpected non-InnerJoin?");
                    newJoinPredicateNode = PlanCompilerUtil.CombinePredicates(joinNode.Child2, newJoinPredicateNode, command);
                }
            }
            else
            {
                newJoinPredicateNode = (joinOp.OpType == OpType.CrossJoin) ? null : joinNode.Child2;
            }

            //
            // If nothing has changed, then just return the current node. Otherwise,
            // we will loop forever
            //
            if (!needsTransformation)
            {
                return(false);
            }

            Node newJoinNode;

            //
            // Finally build up a new join node
            //
            if (joinOp.OpType
                == OpType.CrossJoin)
            {
                newJoinNode = command.CreateNode(joinOp, leftInputNode, rightInputNode);
            }
            else
            {
                newJoinNode = command.CreateNode(joinOp, leftInputNode, rightInputNode, newJoinPredicateNode);
            }

            //
            // Build up a new filterNode above this join node. But only if we have a filter left
            //
            var newFilterPredicateNode = predicate.BuildAndTree();

            if (newFilterPredicateNode == null)
            {
                newNode = newJoinNode;
            }
            else
            {
                newNode = command.CreateNode(command.CreateFilterOp(), newJoinNode, newFilterPredicateNode);
            }
            return(true);
        }