Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / PlanCompiler.cs / 2 / 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 List providerCommands, 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 List providerCommands, 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 List providerCommands, 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 List providerCommands, 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
- WebPartManager.cs
- PerformanceCounterPermissionAttribute.cs
- OleDbMetaDataFactory.cs
- DropShadowEffect.cs
- EntryIndex.cs
- ClientType.cs
- HttpCookiesSection.cs
- AQNBuilder.cs
- ServerReliableChannelBinder.cs
- CodeIdentifier.cs
- __Error.cs
- PathFigureCollection.cs
- SecurityManager.cs
- PanelContainerDesigner.cs
- NavigationProperty.cs
- StorageMappingItemLoader.cs
- FactoryMaker.cs
- WorkflowInstanceSuspendedRecord.cs
- EntityDataSourceValidationException.cs
- StandardCommands.cs
- ArrayElementGridEntry.cs
- SimpleWebHandlerParser.cs
- Bits.cs
- TrustLevel.cs
- FileDialog.cs
- BitmapDecoder.cs
- ExtensibleClassFactory.cs
- XmlDataProvider.cs
- FolderBrowserDialog.cs
- OracleRowUpdatedEventArgs.cs
- Vertex.cs
- PrimaryKeyTypeConverter.cs
- GeometryModel3D.cs
- PartitionResolver.cs
- CompilerWrapper.cs
- MatrixUtil.cs
- HierarchicalDataSourceControl.cs
- ResourceReferenceKeyNotFoundException.cs
- AstTree.cs
- ComponentDispatcher.cs
- SoapProtocolImporter.cs
- XmlSchemaAnyAttribute.cs
- XmlValueConverter.cs
- basecomparevalidator.cs
- XmlnsDictionary.cs
- BaseDataBoundControl.cs
- WmlLiteralTextAdapter.cs
- AddInStore.cs
- StringStorage.cs
- InfoCardRSAPKCS1KeyExchangeDeformatter.cs
- ShapeTypeface.cs
- PlatformCulture.cs
- CookieProtection.cs
- Authorization.cs
- CacheMemory.cs
- ScrollableControl.cs
- xmlfixedPageInfo.cs
- EventLogConfiguration.cs
- LicFileLicenseProvider.cs
- ProfileSection.cs
- AuthenticationServiceManager.cs
- BitVector32.cs
- RegexInterpreter.cs
- CmsUtils.cs
- FontFamilyValueSerializer.cs
- ContextMenu.cs
- EditorPart.cs
- DataContractSerializerFaultFormatter.cs
- CompoundFileDeflateTransform.cs
- ConnectionInterfaceCollection.cs
- MetadataArtifactLoaderResource.cs
- DiscreteKeyFrames.cs
- ActivityMarkupSerializationProvider.cs
- FtpWebResponse.cs
- XsltConvert.cs
- HyperLink.cs
- XsltException.cs
- ProviderConnectionPoint.cs
- UncommonField.cs
- FullTrustAssemblyCollection.cs
- SystemParameters.cs
- Subtree.cs
- XhtmlBasicTextViewAdapter.cs
- WinEventQueueItem.cs
- _NativeSSPI.cs
- CacheChildrenQuery.cs
- AvTrace.cs
- DiagnosticsConfiguration.cs
- EncryptedPackageFilter.cs
- Hyperlink.cs
- SystemFonts.cs
- BufferModeSettings.cs
- WebUtil.cs
- SessionStateContainer.cs
- ControlParameter.cs
- RemoteHelper.cs
- DbUpdateCommandTree.cs
- CompilerScope.cs
- XamlGridLengthSerializer.cs
- FocusTracker.cs