Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / PlanCompiler.cs / 3 / PlanCompiler.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... using cqt = System.Data.Common.CommandTrees; using md = System.Data.Metadata.Edm; using System.Data.Query.InternalTrees; using System.Data.Query.PlanCompiler; namespace System.Data.Query.PlanCompiler { ////// The PlanCompiler class is used by the BridgeCommand to produce an /// execution plan - this execution plan is the plan object. The plan compilation /// process takes as input a command tree (in C space), and then runs through a /// set of changes before the final plan is produced. The final plan contains /// one or more command trees (commands?) (in S space), with a set of assembly /// instructions. /// The compiler phases include /// * Convert the command tree (CTree) into an internal tree (an ITree) /// * Run initializations on the ITree. /// * Eliminate structured types from the tree /// * Eliminating named type references, refs and records from the tree /// At the end of this phase, we still may have collections (and record /// arguments to collections) in the tree. /// * Projection pruning (ie) eliminating unused references /// * Tree transformations. Various transformations are run on the ITree to /// (ostensibly) optimize the tree. These transformations are represented as /// rules, and a rule processor is invoked. /// * Nest elimination. At this point, we try to get pull up nest operations /// as high up the tree as possible /// * Code Generation. This phase produces a plan object with various subpieces /// of the ITree represented as commands (in S space). /// * The subtrees of the ITree are then converted into the corresponding CTrees /// and converted into S space as part of the CTree creation. /// * A plan object is created and returned. /// internal class PlanCompiler { #region private state ////// Bid Counter object /// private static int _objectTypeCount; ////// The object Id of this instance, for BID tracing. /// internal readonly int ObjectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); ////// A boolean switch indicating whether we should apply transformation rules regardless of the size of the Iqt. /// By default, the Enabled property of a boolean switch is set using the value specified in the configuration file. /// Configuring the switch with a value of 0 sets the Enabled property to false; configuring the switch with a nonzero /// value to set the Enabled property to true. If the BooleanSwitch constructor cannot find initial switch settings /// in the configuration file, the Enabled property of the new switch is set to false by default. /// private static BooleanSwitch _applyTransformationsRegardlessOfSize = new BooleanSwitch("System.Data.EntityClient.IgnoreOptimizationLimit", "The Entity Framework should try to optimize the query regardless of its size"); ////// Determines the maximum size of the query in terms of Iqt nodes for which we attempt to do transformation rules. /// This number is ignored if applyTransformationsRegardlessOfSize is enabled. /// private const int MaxNodeCountForTransformations = 100000; ////// The CTree we're compiling a plan for. /// private cqt.DbCommandTree m_ctree; ////// The ITree we're working on. /// private Command m_command; ////// The phase of the process we're currently in. /// private PlanCompilerPhase m_phase; ////// Set of phases we need to go through /// private int m_neededPhases; #endregion #region constructors ////// private constructor /// /// the input cqt private PlanCompiler(cqt.DbCommandTree ctree) { m_ctree = ctree; // the input command tree } #endregion #region public interfaces internal const Bid.ApiGroup PlanCompilerTracePoints = (Bid.ApiGroup)0x8000; // That's Bit_15 for those counting at home :) ////// Retail Assertion code. /// /// Provides the ability to have retail asserts. /// /// /// internal static void Assert(bool condition, string message) { if (!condition) { System.Diagnostics.Debug.Fail(message); // NOTE: I considered, at great length, whether to have the assertion message text // included in the exception we throw; in the end, there really isn't a reliable // equivalent to the C++ __LINE__ and __FILE__ macros in C# (at least not without // using the C++ PreProcessor...ick) The StackTrace object comes close but // doesn't handle inlined callers properly for our needs (MethodA() calls MethodB() // calls us, but MethodB() is inlined, so we'll get MethodA() info instead), and // since these are retail "Asserts" (as in: we're not supposed to get them in our // shipping code, and we're doing this to avoid a null-ref which is even worse) I // elected to simplify this by just including them as the additional info. throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.AssertionFailed, 0, message); } } ////// Compile a query, and produce a plan /// /// the input CQT /// list of provider commands /// column map for result assembly /// the entity sets referenced in this query ///a compiled plan object internal static void Compile(cqt.DbCommandTree ctree, out ListproviderCommands, out ColumnMap resultColumnMap, out int columnCount, out Common.Utils.Set entitySets) { PlanCompiler.Assert(ctree != null, "Expected a valid, non-null Command Tree input"); PlanCompiler pc = new PlanCompiler(ctree); pc.Compile(out providerCommands, out resultColumnMap, out columnCount, out entitySets); } /// /// Get the current command /// internal Command Command { get { return m_command; } } #if DEBUG ////// Get the current plan compiler phase /// internal PlanCompilerPhase Phase { get { return m_phase; } } #endif ////// The MetadataWorkspace /// internal md.MetadataWorkspace MetadataWorkspace { get { return m_ctree.MetadataWorkspace; } } ////// Is the specified phase needed for this query? /// /// the phase in question ///internal bool IsPhaseNeeded(PlanCompilerPhase phase) { return ((m_neededPhases & (1 << (int)phase)) != 0); } /// /// Mark the specified phase as needed /// /// plan compiler phase internal void MarkPhaseAsNeeded(PlanCompilerPhase phase) { m_neededPhases = m_neededPhases | (1 << (int)phase); } ////// Mark the specified phase as not needed /// /// plan compiler phase internal void MarkPhaseAsNotNeeded(PlanCompilerPhase phase) { m_neededPhases = m_neededPhases & (~0 ^ (1 << (int)phase)); } #endregion #region private methods ////// The real driver. /// /// list of provider commands /// column map for the result /// the entity sets exposed in this query private void Compile(out ListproviderCommands, out ColumnMap resultColumnMap, out int columnCount, out Common.Utils.Set entitySets) { EntityBid.Trace(" %d# Compiling Plan for DbCommandTree=%d#\n", ObjectID, m_ctree.ObjectId); Initialize(); // initialize the ITree string beforePreProcessor = String.Empty; string beforeNTE = String.Empty; string beforeProjectionPruning1 = String.Empty; string beforeNestPullup = String.Empty; string beforeProjectionPruning2 = String.Empty; string beforeTransformationRules = String.Empty; string beforeProjectionPruning3 = String.Empty; string beforeJoinElimination = 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 NTE, NestPullup and JoinElimination // m_neededPhases = (1 << (int)PlanCompilerPhase.PreProcessor) | // (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 = null; beforePreProcessor = SwitchToPhase(PlanCompilerPhase.PreProcessor); PreProcessor.Process(this, out typeInfo); entitySets = typeInfo.GetEntitySets(); // Eliminate "structured" types. if (IsPhaseNeeded(PlanCompilerPhase.NTE)) { beforeNTE = SwitchToPhase(PlanCompilerPhase.NTE); NominalTypeEliminator.Process(this, typeInfo); } // 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) && MayApplyTransformationRules()) { //Clear the projection pruning phase, transformation rules will set it again if needed. MarkPhaseAsNotNeeded(PlanCompilerPhase.ProjectionPruning); beforeTransformationRules = SwitchToPhase(PlanCompilerPhase.Transformations); TransformationRules.ApplyAllRules(this); if (IsPhaseNeeded(PlanCompilerPhase.ProjectionPruning)) { beforeProjectionPruning3 = SwitchToPhase(PlanCompilerPhase.ProjectionPruning); ProjectionPruner.Process(this); TransformationRules.ApplyProjectRules(this); } } // Join elimination if (IsPhaseNeeded(PlanCompilerPhase.JoinElimination)) { //Clear the transformation rules phase, join elimination will set it again if needed. MarkPhaseAsNotNeeded(PlanCompilerPhase.Transformations); beforeJoinElimination = SwitchToPhase(PlanCompilerPhase.JoinElimination); JoinElimination.Process(this); if (IsPhaseNeeded(PlanCompilerPhase.Transformations) && MayApplyTransformationRules()) { TransformationRules.ApplyKeyInfoDependentRules(this); } } // 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 = beforeNTE.Length; size = beforeProjectionPruning1.Length; size = beforeNestPullup.Length; size = beforeProjectionPruning2.Length; size = beforeTransformationRules.Length; size = beforeProjectionPruning3.Length; size = beforeJoinElimination.Length; size = beforeCodeGen.Length; #endif if (EntityBid.TraceOn) { int i = 0; foreach (ProviderCommandInfo pi in providerCommands) { EntityBid.Trace(" %d# resulting command %d with DbCommandTree=%d#\n", ObjectID, i++, pi.CommandTree.ObjectId); } } // All done return; } /// /// Logic to perform between each compile phase /// /// ///private string SwitchToPhase(PlanCompilerPhase newPhase) { string iqtDumpResult = string.Empty; m_phase = newPhase; if (EntityBid.PlanCompilerOn) { iqtDumpResult = Dump.ToXml(m_command); EntityBid.PlanCompilerTrace(" %d# phase=%d\n", ObjectID, (int)newPhase); EntityBid.PlanCompilerPutStr(iqtDumpResult); } #if DEBUG else { iqtDumpResult = Dump.ToXml(m_command); } Validator.Validate(this); #endif return iqtDumpResult; } /// /// Transformation rules may be applied if the number of nodes is less then MaxNodeCountForTransformations /// or it is specified that they may be applied regardless of the size of the query. /// We approximate the number of nodes by looking at the nextNodeId. /// ///private bool MayApplyTransformationRules() { return (_applyTransformationsRegardlessOfSize.Enabled || (this.m_command.NextNodeId < MaxNodeCountForTransformations)); } /// /// Converts the CTree into an ITree, and initializes the plan /// private void Initialize() { // Only support queries for now cqt.DbQueryCommandTree cqtree = m_ctree as cqt.DbQueryCommandTree; PlanCompiler.Assert(cqtree != null, "Unexpected command tree kind. Only query command tree is supported."); // Generate the ITree m_command = ITreeGenerator.Generate(cqtree); PlanCompiler.Assert(m_command != null, "Unable to generate internal tree from Command Tree"); } #endregion } ////// Enum describing which phase of plan compilation we're currently in /// internal enum PlanCompilerPhase { ////// Just entering the PreProcessor phase /// PreProcessor = 0, ////// Just entering the NTE (Nominal Type Eliminator) phase /// NTE = 1, ////// Entering the Projection pruning phase /// ProjectionPruning = 2, ////// Entering the Nest Pullup phase /// NestPullup = 3, ////// Entering the Transformations phase /// Transformations = 4, ////// Entering the JoinElimination phase /// JoinElimination = 5, ////// Entering the codegen phase /// CodeGen = 6, ////// We're almost done /// PostCodeGen = 7, ////// Marker /// MaxMarker = 8 } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....], [....] //--------------------------------------------------------------------- using System; using System.Collections.Generic; using System.Diagnostics; // Please use PlanCompiler.Assert instead of Debug.Assert in this class... using cqt = System.Data.Common.CommandTrees; using md = System.Data.Metadata.Edm; using System.Data.Query.InternalTrees; using System.Data.Query.PlanCompiler; namespace System.Data.Query.PlanCompiler { ////// The PlanCompiler class is used by the BridgeCommand to produce an /// execution plan - this execution plan is the plan object. The plan compilation /// process takes as input a command tree (in C space), and then runs through a /// set of changes before the final plan is produced. The final plan contains /// one or more command trees (commands?) (in S space), with a set of assembly /// instructions. /// The compiler phases include /// * Convert the command tree (CTree) into an internal tree (an ITree) /// * Run initializations on the ITree. /// * Eliminate structured types from the tree /// * Eliminating named type references, refs and records from the tree /// At the end of this phase, we still may have collections (and record /// arguments to collections) in the tree. /// * Projection pruning (ie) eliminating unused references /// * Tree transformations. Various transformations are run on the ITree to /// (ostensibly) optimize the tree. These transformations are represented as /// rules, and a rule processor is invoked. /// * Nest elimination. At this point, we try to get pull up nest operations /// as high up the tree as possible /// * Code Generation. This phase produces a plan object with various subpieces /// of the ITree represented as commands (in S space). /// * The subtrees of the ITree are then converted into the corresponding CTrees /// and converted into S space as part of the CTree creation. /// * A plan object is created and returned. /// internal class PlanCompiler { #region private state ////// Bid Counter object /// private static int _objectTypeCount; ////// The object Id of this instance, for BID tracing. /// internal readonly int ObjectID = System.Threading.Interlocked.Increment(ref _objectTypeCount); ////// A boolean switch indicating whether we should apply transformation rules regardless of the size of the Iqt. /// By default, the Enabled property of a boolean switch is set using the value specified in the configuration file. /// Configuring the switch with a value of 0 sets the Enabled property to false; configuring the switch with a nonzero /// value to set the Enabled property to true. If the BooleanSwitch constructor cannot find initial switch settings /// in the configuration file, the Enabled property of the new switch is set to false by default. /// private static BooleanSwitch _applyTransformationsRegardlessOfSize = new BooleanSwitch("System.Data.EntityClient.IgnoreOptimizationLimit", "The Entity Framework should try to optimize the query regardless of its size"); ////// Determines the maximum size of the query in terms of Iqt nodes for which we attempt to do transformation rules. /// This number is ignored if applyTransformationsRegardlessOfSize is enabled. /// private const int MaxNodeCountForTransformations = 100000; ////// The CTree we're compiling a plan for. /// private cqt.DbCommandTree m_ctree; ////// The ITree we're working on. /// private Command m_command; ////// The phase of the process we're currently in. /// private PlanCompilerPhase m_phase; ////// Set of phases we need to go through /// private int m_neededPhases; #endregion #region constructors ////// private constructor /// /// the input cqt private PlanCompiler(cqt.DbCommandTree ctree) { m_ctree = ctree; // the input command tree } #endregion #region public interfaces internal const Bid.ApiGroup PlanCompilerTracePoints = (Bid.ApiGroup)0x8000; // That's Bit_15 for those counting at home :) ////// Retail Assertion code. /// /// Provides the ability to have retail asserts. /// /// /// internal static void Assert(bool condition, string message) { if (!condition) { System.Diagnostics.Debug.Fail(message); // NOTE: I considered, at great length, whether to have the assertion message text // included in the exception we throw; in the end, there really isn't a reliable // equivalent to the C++ __LINE__ and __FILE__ macros in C# (at least not without // using the C++ PreProcessor...ick) The StackTrace object comes close but // doesn't handle inlined callers properly for our needs (MethodA() calls MethodB() // calls us, but MethodB() is inlined, so we'll get MethodA() info instead), and // since these are retail "Asserts" (as in: we're not supposed to get them in our // shipping code, and we're doing this to avoid a null-ref which is even worse) I // elected to simplify this by just including them as the additional info. throw EntityUtil.InternalError(EntityUtil.InternalErrorCode.AssertionFailed, 0, message); } } ////// Compile a query, and produce a plan /// /// the input CQT /// list of provider commands /// column map for result assembly /// the entity sets referenced in this query ///a compiled plan object internal static void Compile(cqt.DbCommandTree ctree, out ListproviderCommands, out ColumnMap resultColumnMap, out int columnCount, out Common.Utils.Set entitySets) { PlanCompiler.Assert(ctree != null, "Expected a valid, non-null Command Tree input"); PlanCompiler pc = new PlanCompiler(ctree); pc.Compile(out providerCommands, out resultColumnMap, out columnCount, out entitySets); } /// /// Get the current command /// internal Command Command { get { return m_command; } } #if DEBUG ////// Get the current plan compiler phase /// internal PlanCompilerPhase Phase { get { return m_phase; } } #endif ////// The MetadataWorkspace /// internal md.MetadataWorkspace MetadataWorkspace { get { return m_ctree.MetadataWorkspace; } } ////// Is the specified phase needed for this query? /// /// the phase in question ///internal bool IsPhaseNeeded(PlanCompilerPhase phase) { return ((m_neededPhases & (1 << (int)phase)) != 0); } /// /// Mark the specified phase as needed /// /// plan compiler phase internal void MarkPhaseAsNeeded(PlanCompilerPhase phase) { m_neededPhases = m_neededPhases | (1 << (int)phase); } ////// Mark the specified phase as not needed /// /// plan compiler phase internal void MarkPhaseAsNotNeeded(PlanCompilerPhase phase) { m_neededPhases = m_neededPhases & (~0 ^ (1 << (int)phase)); } #endregion #region private methods ////// The real driver. /// /// list of provider commands /// column map for the result /// the entity sets exposed in this query private void Compile(out ListproviderCommands, out ColumnMap resultColumnMap, out int columnCount, out Common.Utils.Set entitySets) { EntityBid.Trace(" %d# Compiling Plan for DbCommandTree=%d#\n", ObjectID, m_ctree.ObjectId); Initialize(); // initialize the ITree string beforePreProcessor = String.Empty; string beforeNTE = String.Empty; string beforeProjectionPruning1 = String.Empty; string beforeNestPullup = String.Empty; string beforeProjectionPruning2 = String.Empty; string beforeTransformationRules = String.Empty; string beforeProjectionPruning3 = String.Empty; string beforeJoinElimination = 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 NTE, NestPullup and JoinElimination // m_neededPhases = (1 << (int)PlanCompilerPhase.PreProcessor) | // (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 = null; beforePreProcessor = SwitchToPhase(PlanCompilerPhase.PreProcessor); PreProcessor.Process(this, out typeInfo); entitySets = typeInfo.GetEntitySets(); // Eliminate "structured" types. if (IsPhaseNeeded(PlanCompilerPhase.NTE)) { beforeNTE = SwitchToPhase(PlanCompilerPhase.NTE); NominalTypeEliminator.Process(this, typeInfo); } // 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) && MayApplyTransformationRules()) { //Clear the projection pruning phase, transformation rules will set it again if needed. MarkPhaseAsNotNeeded(PlanCompilerPhase.ProjectionPruning); beforeTransformationRules = SwitchToPhase(PlanCompilerPhase.Transformations); TransformationRules.ApplyAllRules(this); if (IsPhaseNeeded(PlanCompilerPhase.ProjectionPruning)) { beforeProjectionPruning3 = SwitchToPhase(PlanCompilerPhase.ProjectionPruning); ProjectionPruner.Process(this); TransformationRules.ApplyProjectRules(this); } } // Join elimination if (IsPhaseNeeded(PlanCompilerPhase.JoinElimination)) { //Clear the transformation rules phase, join elimination will set it again if needed. MarkPhaseAsNotNeeded(PlanCompilerPhase.Transformations); beforeJoinElimination = SwitchToPhase(PlanCompilerPhase.JoinElimination); JoinElimination.Process(this); if (IsPhaseNeeded(PlanCompilerPhase.Transformations) && MayApplyTransformationRules()) { TransformationRules.ApplyKeyInfoDependentRules(this); } } // 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 = beforeNTE.Length; size = beforeProjectionPruning1.Length; size = beforeNestPullup.Length; size = beforeProjectionPruning2.Length; size = beforeTransformationRules.Length; size = beforeProjectionPruning3.Length; size = beforeJoinElimination.Length; size = beforeCodeGen.Length; #endif if (EntityBid.TraceOn) { int i = 0; foreach (ProviderCommandInfo pi in providerCommands) { EntityBid.Trace(" %d# resulting command %d with DbCommandTree=%d#\n", ObjectID, i++, pi.CommandTree.ObjectId); } } // All done return; } /// /// Logic to perform between each compile phase /// /// ///private string SwitchToPhase(PlanCompilerPhase newPhase) { string iqtDumpResult = string.Empty; m_phase = newPhase; if (EntityBid.PlanCompilerOn) { iqtDumpResult = Dump.ToXml(m_command); EntityBid.PlanCompilerTrace(" %d# phase=%d\n", ObjectID, (int)newPhase); EntityBid.PlanCompilerPutStr(iqtDumpResult); } #if DEBUG else { iqtDumpResult = Dump.ToXml(m_command); } Validator.Validate(this); #endif return iqtDumpResult; } /// /// Transformation rules may be applied if the number of nodes is less then MaxNodeCountForTransformations /// or it is specified that they may be applied regardless of the size of the query. /// We approximate the number of nodes by looking at the nextNodeId. /// ///private bool MayApplyTransformationRules() { return (_applyTransformationsRegardlessOfSize.Enabled || (this.m_command.NextNodeId < MaxNodeCountForTransformations)); } /// /// Converts the CTree into an ITree, and initializes the plan /// private void Initialize() { // Only support queries for now cqt.DbQueryCommandTree cqtree = m_ctree as cqt.DbQueryCommandTree; PlanCompiler.Assert(cqtree != null, "Unexpected command tree kind. Only query command tree is supported."); // Generate the ITree m_command = ITreeGenerator.Generate(cqtree); PlanCompiler.Assert(m_command != null, "Unable to generate internal tree from Command Tree"); } #endregion } ////// Enum describing which phase of plan compilation we're currently in /// internal enum PlanCompilerPhase { ////// Just entering the PreProcessor phase /// PreProcessor = 0, ////// Just entering the NTE (Nominal Type Eliminator) phase /// NTE = 1, ////// Entering the Projection pruning phase /// ProjectionPruning = 2, ////// Entering the Nest Pullup phase /// NestPullup = 3, ////// Entering the Transformations phase /// Transformations = 4, ////// Entering the JoinElimination phase /// JoinElimination = 5, ////// Entering the codegen phase /// CodeGen = 6, ////// We're almost done /// PostCodeGen = 7, ////// Marker /// MaxMarker = 8 } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Convert.cs
- CodeSubDirectory.cs
- CategoryAttribute.cs
- XmlSchemaResource.cs
- RewritingValidator.cs
- Style.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- ResourceCategoryAttribute.cs
- WebPartConnectionCollection.cs
- DataBindingHandlerAttribute.cs
- SingleSelectRootGridEntry.cs
- FileSystemInfo.cs
- SamlSecurityToken.cs
- UrlMappingsModule.cs
- RequiredAttributeAttribute.cs
- MasterPageBuildProvider.cs
- BitmapMetadataBlob.cs
- PrefixQName.cs
- MultiDataTrigger.cs
- X509CertificateChain.cs
- StateManagedCollection.cs
- CodeExpressionCollection.cs
- MemberHolder.cs
- FixedSOMLineRanges.cs
- StateRuntime.cs
- Odbc32.cs
- XmlUrlEditor.cs
- HttpVersion.cs
- DataGridCell.cs
- SymbolMethod.cs
- LinkArea.cs
- EmptyWithCancelationCheckWorkItem.cs
- ProxyAttribute.cs
- FirewallWrapper.cs
- assertwrapper.cs
- ImageBrush.cs
- SessionPageStateSection.cs
- _AutoWebProxyScriptEngine.cs
- UTF32Encoding.cs
- InvalidContentTypeException.cs
- WindowsListViewGroup.cs
- DataGridViewColumnCollection.cs
- PeerCustomResolverElement.cs
- TransformPattern.cs
- PrintDialog.cs
- HandleRef.cs
- DrawingVisual.cs
- ObjectSet.cs
- MatrixConverter.cs
- ConnectionPoint.cs
- DataBoundControlHelper.cs
- XmlException.cs
- PermissionSetEnumerator.cs
- PaperSize.cs
- PnrpPeerResolverBindingElement.cs
- SizeConverter.cs
- Int32Rect.cs
- EnterpriseServicesHelper.cs
- UnaryExpression.cs
- AspNetSynchronizationContext.cs
- ExpressionTextBoxAutomationPeer.cs
- HMACSHA256.cs
- ToolStripSplitStackLayout.cs
- ImageFormatConverter.cs
- DataObjectPastingEventArgs.cs
- Monitor.cs
- Polygon.cs
- StdValidatorsAndConverters.cs
- MetricEntry.cs
- WeakRefEnumerator.cs
- ErrorWebPart.cs
- SocketElement.cs
- PersonalizationStateInfo.cs
- SpeechRecognizer.cs
- RectAnimation.cs
- ImageMetadata.cs
- ConnectionConsumerAttribute.cs
- OleDbError.cs
- HelpKeywordAttribute.cs
- StringDictionaryWithComparer.cs
- XmlIlTypeHelper.cs
- AQNBuilder.cs
- CodeIterationStatement.cs
- ThreadExceptionEvent.cs
- UTF7Encoding.cs
- ObjectPersistData.cs
- SegmentInfo.cs
- CompositeControl.cs
- ByteStreamMessageEncodingElement.cs
- RuntimeEnvironment.cs
- SoapReflectionImporter.cs
- SimpleColumnProvider.cs
- DeferredElementTreeState.cs
- LayoutTableCell.cs
- QuerySettings.cs
- HttpProfileBase.cs
- CodeTypeReferenceExpression.cs
- CodeStatementCollection.cs
- CreateDataSourceDialog.cs
- NativeActivityFaultContext.cs