Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / PlanCompiler.cs / 1 / 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
- ValidationResults.cs
- SoapSchemaExporter.cs
- ProtectedProviderSettings.cs
- UnsafeNativeMethods.cs
- Function.cs
- MessageBox.cs
- UncommonField.cs
- SettingsPropertyIsReadOnlyException.cs
- MutableAssemblyCacheEntry.cs
- PageSetupDialog.cs
- RectKeyFrameCollection.cs
- EncoderNLS.cs
- SecuritySessionServerSettings.cs
- IDReferencePropertyAttribute.cs
- ScrollChangedEventArgs.cs
- ToolStripArrowRenderEventArgs.cs
- TextDecoration.cs
- TriggerCollection.cs
- MetadataItemEmitter.cs
- UInt16Converter.cs
- TrackBar.cs
- AutomationPeer.cs
- CultureSpecificStringDictionary.cs
- TextElementEnumerator.cs
- Track.cs
- ReferencedCollectionType.cs
- Subtree.cs
- ThreadExceptionDialog.cs
- SmtpReplyReader.cs
- LicenseProviderAttribute.cs
- DataBoundControl.cs
- SimpleHandlerFactory.cs
- RepeatInfo.cs
- IdnElement.cs
- Context.cs
- TreeNodeConverter.cs
- TreeNode.cs
- CLRBindingWorker.cs
- DisplayMemberTemplateSelector.cs
- QueryOutputWriter.cs
- TabControlDesigner.cs
- XmlLinkedNode.cs
- Visitors.cs
- path.cs
- UIElement.cs
- RegisteredDisposeScript.cs
- TrustManagerPromptUI.cs
- LineServicesRun.cs
- GenericNameHandler.cs
- HtmlInputImage.cs
- GridViewUpdateEventArgs.cs
- ObjectStorage.cs
- ElementUtil.cs
- MergePropertyDescriptor.cs
- WebPartMinimizeVerb.cs
- ImpersonateTokenRef.cs
- XmlNodeList.cs
- X509CertificateInitiatorServiceCredential.cs
- Header.cs
- UntypedNullExpression.cs
- SmtpAuthenticationManager.cs
- SafeNativeMethods.cs
- HtmlInputImage.cs
- CodeCatchClause.cs
- KoreanCalendar.cs
- OracleBinary.cs
- GuidConverter.cs
- PipeStream.cs
- RtType.cs
- DataBoundControl.cs
- HealthMonitoringSection.cs
- AdornerDecorator.cs
- AssemblyUtil.cs
- ComplusEndpointConfigContainer.cs
- ObservableCollectionDefaultValueFactory.cs
- DataSourceHelper.cs
- RequiredFieldValidator.cs
- FlowDocumentScrollViewer.cs
- ClientOptions.cs
- FormCollection.cs
- LocalizationComments.cs
- ExceptionTranslationTable.cs
- ViewStateException.cs
- DispatcherEventArgs.cs
- BufferedGraphics.cs
- MediaSystem.cs
- _OverlappedAsyncResult.cs
- XmlSchemaAnnotated.cs
- HotSpot.cs
- RectAnimationClockResource.cs
- DataGridViewColumn.cs
- PaperSize.cs
- SqlLiftWhereClauses.cs
- CompositeDataBoundControl.cs
- ScriptComponentDescriptor.cs
- ActiveXHost.cs
- QuaternionRotation3D.cs
- ModuleBuilder.cs
- PersistChildrenAttribute.cs
- TimeStampChecker.cs