/// <summary>
 ///     The driver routine.
 /// </summary>
 /// <param name="planCompilerState"> plan compiler state </param>
 internal static void Process(PlanCompiler planCompilerState)
 {
     var normalizer = new Normalizer(planCompilerState);
     normalizer.Process();
 }
Exemple #2
0
        /// <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 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))
            {
                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);
                    }
                }
            }

            // 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 = beforeCodeGen.Length;
#endif
            // All done
            return;
        }