/// <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 Common.Utils.Set <md.EntitySet> entitySets)
        {
            Initialize(); // initialize the ITree

            string beforePreProcessor      = String.Empty;
            string beforeAggregatePushdown = String.Empty;
            string beforeNormalization     = String.Empty;
            string beforeNTE = String.Empty;
            string beforeProjectionPruning1   = String.Empty;
            string beforeNestPullup           = String.Empty;
            string beforeProjectionPruning2   = String.Empty;
            string beforeTransformationRules1 = String.Empty;
            string beforeProjectionPruning3   = String.Empty;
            string beforeTransformationRules2 = String.Empty;
            string beforeJoinElimination1     = String.Empty;
            string beforeTransformationRules3 = String.Empty;
            string beforeJoinElimination2     = String.Empty;
            string beforeTransformationRules4 = String.Empty;
            string 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.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))
            {
                bool 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);
                bool 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);
                    }
                }
            }

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

#if DEBUG
            // GC.KeepAlive makes FxCop Grumpy.
            int 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 = beforeCodeGen.Length;
#endif
            // All done
            return;
        }
示例#2
0
        /// <summary>
        /// Runs through the given subtree, and eliminates all
        /// unreferenced expressions
        /// </summary>
        /// <param name="compilerState">current compiler state</param>
        /// <param name="node">The node to be processed</param>
        /// <returns>The processed, i.e. transformed node</returns>
        internal static Node Process(PlanCompiler compilerState, Node node)
        {
            ProjectionPruner pruner = new ProjectionPruner(compilerState);

            return(pruner.Process(node));
        }