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();
        }
        // <summary>
        // The real driver.
        // </summary>
        // <param name="providerCommands"> list of provider commands </param>
        // <param name="resultColumnMap"> column map for the result </param>
        // <param name="entitySets"> the entity sets exposed in this query </param>
        private void Compile(
            out List <ProviderCommandInfo> providerCommands, out ColumnMap resultColumnMap, out int columnCount,
            out Set <md.EntitySet> entitySets)
        {
            Initialize(); // initialize the ITree

            var beforePreProcessor      = String.Empty;
            var beforeAggregatePushdown = String.Empty;
            var beforeNormalization     = String.Empty;
            var beforeNTE = String.Empty;
            var beforeProjectionPruning1   = String.Empty;
            var beforeNestPullup           = String.Empty;
            var beforeProjectionPruning2   = String.Empty;
            var beforeTransformationRules1 = String.Empty;
            var beforeProjectionPruning3   = String.Empty;
            var beforeTransformationRules2 = String.Empty;
            var beforeJoinElimination1     = String.Empty;
            var beforeTransformationRules3 = String.Empty;
            var beforeJoinElimination2     = String.Empty;
            var beforeTransformationRules4 = String.Empty;
            var beforeNullSemantics        = String.Empty;
            var beforeTransformationRules5 = String.Empty;
            var beforeCodeGen = String.Empty;

            //
            // We always need the pre-processor and the codegen phases.
            // It is generally a good thing to run through the transformation rules, and
            // the projection pruning phases.
            // The "optional" phases are AggregatePushdown, Normalization, NTE, NestPullup and JoinElimination
            //
            m_neededPhases = (1 << (int)PlanCompilerPhase.PreProcessor) |
                             // (1 << (int)PlanCompilerPhase.AggregatePushdown) |
                             // (1 << (int)PlanCompilerPhase.Normalization) |
                             // (1 << (int)PlanCompilerPhase.NTE) |
                             (1 << (int)PlanCompilerPhase.ProjectionPruning) |
                             // (1 << (int)PlanCompilerPhase.NestPullup) |
                             (1 << (int)PlanCompilerPhase.Transformations) |
                             // (1 << (int)PlanCompilerPhase.JoinElimination) |
                             // (1 << (int)PlanCompilerPhase.NullSemantics) |
                             (1 << (int)PlanCompilerPhase.CodeGen);

            // Perform any necessary preprocessing
            StructuredTypeInfo typeInfo;
            Dictionary <md.EdmFunction, md.EdmProperty[]> tvfResultKeys;

            beforePreProcessor = SwitchToPhase(PlanCompilerPhase.PreProcessor);
            PreProcessor.Process(this, out typeInfo, out tvfResultKeys);
            entitySets = typeInfo.GetEntitySets();

            if (IsPhaseNeeded(PlanCompilerPhase.AggregatePushdown))
            {
                beforeAggregatePushdown = SwitchToPhase(PlanCompilerPhase.AggregatePushdown);
                AggregatePushdown.Process(this);
            }

            if (IsPhaseNeeded(PlanCompilerPhase.Normalization))
            {
                beforeNormalization = SwitchToPhase(PlanCompilerPhase.Normalization);
                Normalizer.Process(this);
            }

            // Eliminate "structured" types.
            if (IsPhaseNeeded(PlanCompilerPhase.NTE))
            {
                beforeNTE = SwitchToPhase(PlanCompilerPhase.NTE);
                NominalTypeEliminator.Process(this, typeInfo, tvfResultKeys);
            }

            // Projection pruning - eliminate unreferenced expressions
            if (IsPhaseNeeded(PlanCompilerPhase.ProjectionPruning))
            {
                beforeProjectionPruning1 = SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                ProjectionPruner.Process(this);
            }

            // Nest Pull-up on the ITree
            if (IsPhaseNeeded(PlanCompilerPhase.NestPullup))
            {
                beforeNestPullup = SwitchToPhase(PlanCompilerPhase.NestPullup);

                NestPullup.Process(this);

                //If we do Nest Pull-up, we should again do projection pruning
                beforeProjectionPruning2 = SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                ProjectionPruner.Process(this);
            }

            // Run transformations on the tree
            if (IsPhaseNeeded(PlanCompilerPhase.Transformations))
            {
                var projectionPrunningNeeded = ApplyTransformations(ref beforeTransformationRules1, TransformationRulesGroup.All);

                if (projectionPrunningNeeded)
                {
                    beforeProjectionPruning3 = SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                    ProjectionPruner.Process(this);
                    ApplyTransformations(ref beforeTransformationRules2, TransformationRulesGroup.Project);
                }
            }

            // Join elimination
            if (IsPhaseNeeded(PlanCompilerPhase.JoinElimination))
            {
                beforeJoinElimination1 = SwitchToPhase(PlanCompilerPhase.JoinElimination);
                var modified = JoinElimination.Process(this);
                if (modified)
                {
                    ApplyTransformations(ref beforeTransformationRules3, TransformationRulesGroup.PostJoinElimination);
                    beforeJoinElimination2 = SwitchToPhase(PlanCompilerPhase.JoinElimination);
                    modified = JoinElimination.Process(this);
                    if (modified)
                    {
                        ApplyTransformations(ref beforeTransformationRules4, TransformationRulesGroup.PostJoinElimination);
                    }
                }
            }

            if (IsPhaseNeeded(PlanCompilerPhase.NullSemantics) &&
                !m_ctree.UseDatabaseNullSemantics)
            {
                beforeNullSemantics = SwitchToPhase(PlanCompilerPhase.NullSemantics);

                if (NullSemantics.Process(Command))
                {
                    ApplyTransformations(ref beforeTransformationRules5, TransformationRulesGroup.NullSemantics);
                }
            }

            // Code generation
            beforeCodeGen = SwitchToPhase(PlanCompilerPhase.CodeGen);
            CodeGen.Process(this, out providerCommands, out resultColumnMap, out columnCount);

#if DEBUG
            // GC.KeepAlive makes FxCop Grumpy.
            var size = beforePreProcessor.Length;
            size = beforeAggregatePushdown.Length;
            size = beforeNormalization.Length;
            size = beforeNTE.Length;
            size = beforeProjectionPruning1.Length;
            size = beforeNestPullup.Length;
            size = beforeProjectionPruning2.Length;
            size = beforeTransformationRules1.Length;
            size = beforeProjectionPruning3.Length;
            size = beforeTransformationRules2.Length;
            size = beforeJoinElimination1.Length;
            size = beforeTransformationRules3.Length;
            size = beforeJoinElimination2.Length;
            size = beforeTransformationRules4.Length;
            size = beforeNullSemantics.Length;
            size = beforeTransformationRules5.Length;
            size = beforeCodeGen.Length;
#endif
        }
 // <summary>
 // Apply Aggregate Pushdown over the tree in the given plan complier state.
 // </summary>
 internal static void Process(PlanCompiler planCompilerState)
 {
     var aggregatePushdown = new AggregatePushdown(planCompilerState.Command);
     aggregatePushdown.Process();
 }
        /// <summary>
        ///     Apply Aggregate Pushdown over the tree in the given plan complier state.
        /// </summary>
        /// <param name="planCompilerState"> </param>
        internal static void Process(PlanCompiler planCompilerState)
        {
            var aggregatePushdown = new AggregatePushdown(planCompilerState.Command);

            aggregatePushdown.Process();
        }
Exemple #5
0
        private void Compile(
            out List <ProviderCommandInfo> providerCommands,
            out ColumnMap resultColumnMap,
            out int columnCount,
            out Set <EntitySet> entitySets)
        {
            this.Initialize();
            string empty1  = string.Empty;
            string empty2  = string.Empty;
            string empty3  = string.Empty;
            string empty4  = string.Empty;
            string empty5  = string.Empty;
            string empty6  = string.Empty;
            string empty7  = string.Empty;
            string empty8  = string.Empty;
            string empty9  = string.Empty;
            string empty10 = string.Empty;
            string empty11 = string.Empty;
            string empty12 = string.Empty;
            string empty13 = string.Empty;
            string empty14 = string.Empty;
            string empty15 = string.Empty;

            this.m_neededPhases = 593;
            this.SwitchToPhase(PlanCompilerPhase.PreProcessor);
            StructuredTypeInfo typeInfo;
            Dictionary <EdmFunction, EdmProperty[]> tvfResultKeys;

            PreProcessor.Process(this, out typeInfo, out tvfResultKeys);
            entitySets = typeInfo.GetEntitySets();
            if (this.IsPhaseNeeded(PlanCompilerPhase.AggregatePushdown))
            {
                this.SwitchToPhase(PlanCompilerPhase.AggregatePushdown);
                AggregatePushdown.Process(this);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.Normalization))
            {
                this.SwitchToPhase(PlanCompilerPhase.Normalization);
                Normalizer.Process(this);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.NTE))
            {
                this.SwitchToPhase(PlanCompilerPhase.NTE);
                NominalTypeEliminator.Process(this, typeInfo, tvfResultKeys);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.ProjectionPruning))
            {
                this.SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                ProjectionPruner.Process(this);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.NestPullup))
            {
                this.SwitchToPhase(PlanCompilerPhase.NestPullup);
                NestPullup.Process(this);
                this.SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                ProjectionPruner.Process(this);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.Transformations) && this.ApplyTransformations(ref empty8, TransformationRulesGroup.All))
            {
                this.SwitchToPhase(PlanCompilerPhase.ProjectionPruning);
                ProjectionPruner.Process(this);
                this.ApplyTransformations(ref empty10, TransformationRulesGroup.Project);
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.NullSemantics))
            {
                this.SwitchToPhase(PlanCompilerPhase.NullSemantics);
                if (!this.m_ctree.UseDatabaseNullSemantics && NullSemantics.Process(this.Command))
                {
                    this.ApplyTransformations(ref empty12, TransformationRulesGroup.NullSemantics);
                }
            }
            if (this.IsPhaseNeeded(PlanCompilerPhase.JoinElimination))
            {
                for (int index = 0; index < 10; ++index)
                {
                    this.SwitchToPhase(PlanCompilerPhase.JoinElimination);
                    if (JoinElimination.Process(this) || this.TransformationsDeferred)
                    {
                        this.TransformationsDeferred = false;
                        this.ApplyTransformations(ref empty14, TransformationRulesGroup.PostJoinElimination);
                    }
                    else
                    {
                        break;
                    }
                }
            }
            this.SwitchToPhase(PlanCompilerPhase.CodeGen);
            CodeGen.Process(this, out providerCommands, out resultColumnMap, out columnCount);
        }