Exemplo n.º 1
0
 public override System.Data.Entity.Core.Query.InternalTrees.Node Visit(
     GroupByIntoOp op,
     System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     System.Data.Entity.Core.Query.InternalTrees.Node node = this.VisitGroupByOp((GroupByBaseOp)op, n);
     if (node.Op.OpType == OpType.GroupByInto && n.Child3.Children.Count == 0)
     {
         GroupByIntoOp op1 = (GroupByIntoOp)node.Op;
         node = this.m_command.CreateNode((Op)this.m_command.CreateGroupByOp(op1.Keys, op1.Outputs), node.Child0, node.Child1, node.Child2);
     }
     return(node);
 }
Exemplo n.º 2
0
 public override void Visit(GroupByIntoOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     this.VisitGroupByOp((GroupByBaseOp)op, n);
     foreach (System.Data.Entity.Core.Query.InternalTrees.Node child in n.Child3.Children)
     {
         Var var = ((VarDefOp)child.Op).Var;
         GroupAggregateVarRefInfo groupAggregateVarRefInfo;
         if (!this._groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(var, out groupAggregateVarRefInfo))
         {
             this._groupAggregateVarInfoManager.Add(var, new GroupAggregateVarInfo(n, var), this._command.CreateNode((Op)this._command.CreateVarRefOp(var)), false);
         }
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// First defer to default handling for groupby nodes
        /// If all group aggregate vars are prunned out turn it into a GroupBy.
        /// </summary>
        /// <param name="op"></param>
        /// <param name="n"></param>
        /// <returns></returns>
        public override Node Visit(GroupByIntoOp op, Node n)
        {
            Node result = VisitGroupByOp(op, n);

            //Transform the GroupByInto into a GroupBy if all group aggregate vars were prunned out
            if (result.Op.OpType == OpType.GroupByInto && n.Child3.Children.Count == 0)
            {
                GroupByIntoOp newOp = (GroupByIntoOp)result.Op;

                result = m_command.CreateNode(m_command.CreateGroupByOp(newOp.Keys, newOp.Outputs),
                                              result.Child0, result.Child1, result.Child2);
            }
            return(result);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Registers the group aggregate var with the group aggregate var info manager
 /// </summary>
 /// <param name="op"></param>
 /// <param name="n"></param>
 public override void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
     foreach (Node child in n.Child3.Children)
     {
         Var groupAggregateVar = ((VarDefOp)child.Op).Var;
         GroupAggregateVarRefInfo groupAggregateVarRefInfo;
         // If the group by is over a group, it may be already tracked as referencing a group var
         // An optimization would be to separately track this groupAggregateVar too, for the cases when the aggregate can
         // not be pushed to the group by node over which this one is defined but can be propagated to this group by node.
         if (!_groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(groupAggregateVar, out groupAggregateVarRefInfo))
         {
             _groupAggregateVarInfoManager.Add(groupAggregateVar, new GroupAggregateVarInfo(n, groupAggregateVar), this._command.CreateNode(this._command.CreateVarRefOp(groupAggregateVar)), false);
         }
     }
 }
        private void TryProcessCandidate(
            KeyValuePair <System.Data.Entity.Core.Query.InternalTrees.Node, System.Data.Entity.Core.Query.InternalTrees.Node> candidate,
            GroupAggregateVarInfo groupAggregateVarInfo)
        {
            System.Data.Entity.Core.Query.InternalTrees.Node         definingGroupNode = groupAggregateVarInfo.DefiningGroupNode;
            IList <System.Data.Entity.Core.Query.InternalTrees.Node> ancestors1;
            IList <System.Data.Entity.Core.Query.InternalTrees.Node> ancestors2;

            this.FindPathsToLeastCommonAncestor(candidate.Key, definingGroupNode, out ancestors1, out ancestors2);
            if (!AggregatePushdown.AreAllNodesSupportedForPropagation(ancestors2))
            {
                return;
            }
            GroupByIntoOp op1 = (GroupByIntoOp)definingGroupNode.Op;

            System.Data.Entity.Core.Query.PlanCompiler.PlanCompiler.Assert(op1.Inputs.Count == 1, "There should be one input var to GroupByInto at this stage");
            Var        first = op1.Inputs.First;
            FunctionOp op2   = (FunctionOp)candidate.Key.Op;

            System.Data.Entity.Core.Query.InternalTrees.Node subTree = OpCopier.Copy(this.m_command, candidate.Value);
            new VarRemapper(this.m_command, new Dictionary <Var, Var>(1)
            {
                {
                    groupAggregateVarInfo.GroupAggregateVar,
                    first
                }
            }).RemapSubtree(subTree);
            Var computedVar;

            System.Data.Entity.Core.Query.InternalTrees.Node varDefNode = this.m_command.CreateVarDefNode(this.m_command.CreateNode((Op)this.m_command.CreateAggregateOp(op2.Function, false), subTree), out computedVar);
            definingGroupNode.Child2.Children.Add(varDefNode);
            ((GroupByBaseOp)definingGroupNode.Op).Outputs.Set(computedVar);
            for (int index = 0; index < ancestors2.Count; ++index)
            {
                System.Data.Entity.Core.Query.InternalTrees.Node node = ancestors2[index];
                if (node.Op.OpType == OpType.Project)
                {
                    ((ProjectOp)node.Op).Outputs.Set(computedVar);
                }
            }
            candidate.Key.Op = (Op)this.m_command.CreateVarRefOp(computedVar);
            candidate.Key.Children.Clear();
        }
Exemplo n.º 6
0
        public override Node Visit(GroupByIntoOp op, Node n)
        {
            PlanCompiler.Assert(n.HasChild3 && n.Child3.Children.Count > 0, "GroupByIntoOp with no group aggregates?");
            var varDefListNode = n.Child3;

            var projectOpOutputs = Command.CreateVarVec(op.Outputs);
            var groupByOutputs = op.Outputs;

            // Local definitions
            foreach (var chi in varDefListNode.Children)
            {
                var varDefOp = chi.Op as VarDefOp;
                groupByOutputs.Clear(varDefOp.Var);
            }

            //Create the new groupByOp
            var groupByNode = Command.CreateNode(
                Command.CreateGroupByOp(op.Keys, groupByOutputs), n.Child0, n.Child1, n.Child2);

            var projectNode = Command.CreateNode(
                Command.CreateProjectOp(projectOpOutputs),
                groupByNode, varDefListNode);

            return VisitNode(projectNode);
        }
        /// <summary>
        ///     GroupByInto
        ///     Again, VisitChildren - for the Keys and Properties VarDefList nodes - does
        ///     the real work.
        ///     The "Keys", "InputVars" and "OutputVars" varsets are updated to flatten out
        ///     references to any structured Vars.
        /// </summary>
        /// <param name="op"> </param>
        /// <param name="n"> </param>
        /// <returns> </returns>
        public override Node Visit(GroupByIntoOp op, Node n)
        {
            VisitChildren(n);

            // update the output Vars and the key vars with the right sets
            var newKeys = FlattenVarSet(op.Keys);
            var newInputs = FlattenVarSet(op.Inputs);
            var newOutputs = FlattenVarSet(op.Outputs);

            if (newKeys != op.Keys
                || newInputs != op.Inputs
                || newOutputs != op.Outputs)
            {
                n.Op = m_command.CreateGroupByIntoOp(newKeys, newInputs, newOutputs);
            }

            return n;
        }
Exemplo n.º 8
0
 /// <summary>
 /// Mark AggregatePushdown as needed
 /// </summary>
 /// <param name="op">the groupByInto op</param>
 /// <param name="n">the node tree</param>
 /// <returns></returns>
 public override Node Visit(GroupByIntoOp op, Node n)
 {
     m_compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.AggregatePushdown);
     return base.Visit(op, n);
 }
Exemplo n.º 9
0
 public override void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
     Assert(n.Child3.Children.Count > 0, "GroupByInto with no group aggregate vars");
 }
 // <summary>
 // Registers the group aggregate var with the group aggregate var info manager
 // </summary>
 public override void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
     foreach (var child in n.Child3.Children)
     {
         var groupAggregateVar = ((VarDefOp)child.Op).Var;
         GroupAggregateVarRefInfo groupAggregateVarRefInfo;
         // If the group by is over a group, it may be already tracked as referencing a group var
         // An optimization would be to separately track this groupAggregateVar too, for the cases when the aggregate can 
         // not be pushed to the group by node over which this one is defined but can be propagated to this group by node.
         if (!_groupAggregateVarInfoManager.TryGetReferencedGroupAggregateVarInfo(groupAggregateVar, out groupAggregateVarRefInfo))
         {
             _groupAggregateVarInfoManager.Add(
                 groupAggregateVar, new GroupAggregateVarInfo(n, groupAggregateVar),
                 _command.CreateNode(_command.CreateVarRefOp(groupAggregateVar)), false);
         }
     }
 }
 /// <summary>
 ///     Visitor pattern method for GroupByIntoOp
 /// </summary>
 /// <param name="op"> The GroupByIntoOp being visited </param>
 /// <param name="n"> The Node that references the Op </param>
 public virtual void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
 }
Exemplo n.º 12
0
 public override void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
     Map(op.Inputs);
 }
Exemplo n.º 13
0
        // <summary>
        // Copies a group by into node
        // </summary>
        // <param name="op"> The Op to Copy </param>
        // <param name="n"> The Node that references the Op </param>
        // <returns> A copy of the original Node that references a copy of the original Op </returns>
        public override Node Visit(GroupByIntoOp op, Node n)
        {
            // Visit the Node's children and map their Vars
            var children = ProcessChildren(n);

            // Create a new GroupByOp that uses copies of the Key and Output VarSets of the original GroupByOp
            var newGroupOp = m_destCmd.CreateGroupByIntoOp(Copy(op.Keys), Copy(op.Inputs), Copy(op.Outputs));

            // Return a new Node that references the copied GroupByOp and has the copied child Nodes as its children
            return m_destCmd.CreateNode(newGroupOp, children);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Try to push the given function aggregate candidate to the corresponding group into node.
        /// The candidate can be pushed if all ancestors of the group into node up to the least common
        /// ancestor between the group into node and the function aggregate have one of the following node op types:
        ///     Project
        ///     Filter
        ///     ConstraintSortOp
        /// </summary>
        /// <param name="command"></param>
        /// <param name="candidate"></param>
        /// <param name="groupAggregateVarInfo"></param>
        /// <param name="m_childToParent"></param>
        private void TryProcessCandidate(
            KeyValuePair <Node, Node> candidate,
            GroupAggregateVarInfo groupAggregateVarInfo)
        {
            IList <Node> functionAncestors;
            IList <Node> groupByAncestors;
            Node         definingGroupNode = groupAggregateVarInfo.DefiningGroupNode;

            FindPathsToLeastCommonAncestor(candidate.Key, definingGroupNode, out functionAncestors, out groupByAncestors);

            //Check whether all ancestors of the GroupByInto node are of type that we support propagating through
            if (!AreAllNodesSupportedForPropagation(groupByAncestors))
            {
                return;
            }

            //Add the function to the group by node
            GroupByIntoOp definingGroupOp = (GroupByIntoOp)definingGroupNode.Op;

            PlanCompiler.Assert(definingGroupOp.Inputs.Count == 1, "There should be one input var to GroupByInto at this stage");
            Var        inputVar   = definingGroupOp.Inputs.First;
            FunctionOp functionOp = (FunctionOp)candidate.Key.Op;

            //
            // Remap the template from referencing the groupAggregate var to reference the input to
            // the group by into
            //
            Node argumentNode = OpCopier.Copy(m_command, candidate.Value);
            Dictionary <Var, Var> dictionary = new Dictionary <Var, Var>(1);

            dictionary.Add(groupAggregateVarInfo.GroupAggregateVar, inputVar);
            VarRemapper remapper = new VarRemapper(m_command, dictionary);

            remapper.RemapSubtree(argumentNode);

            Node newFunctionDefiningNode = m_command.CreateNode(
                m_command.CreateAggregateOp(functionOp.Function, false),
                argumentNode);

            Var  newFunctionVar;
            Node varDefNode = m_command.CreateVarDefNode(newFunctionDefiningNode, out newFunctionVar);

            // Add the new aggregate to the list of aggregates
            definingGroupNode.Child2.Children.Add(varDefNode);
            GroupByIntoOp groupByOp = (GroupByIntoOp)definingGroupNode.Op;

            groupByOp.Outputs.Set(newFunctionVar);

            //Propagate the new var throught the ancestors of the GroupByInto
            for (int i = 0; i < groupByAncestors.Count; i++)
            {
                Node groupByAncestor = groupByAncestors[i];
                if (groupByAncestor.Op.OpType == OpType.Project)
                {
                    ProjectOp ancestorProjectOp = (ProjectOp)groupByAncestor.Op;
                    ancestorProjectOp.Outputs.Set(newFunctionVar);
                }
            }

            //Update the functionNode
            candidate.Key.Op = m_command.CreateVarRefOp(newFunctionVar);
            candidate.Key.Children.Clear();
        }
Exemplo n.º 15
0
 public override void Visit(GroupByIntoOp op, Node n)
 {
     VisitGroupByOp(op, n);
     Map(op.Inputs);
 }
Exemplo n.º 16
0
 public override void Visit(GroupByIntoOp op, System.Data.Entity.Core.Query.InternalTrees.Node n)
 {
     this.VisitGroupByOp((GroupByBaseOp)op, n);
     this.Map(op.Inputs);
 }