JoinElimination.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / JoinElimination.cs / 4 / JoinElimination.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 System.Globalization;

using System.Data.Query.InternalTrees; 

namespace System.Data.Query.PlanCompiler 
{ 
    /// 
    /// The JoinElimination module is intended to do just that - eliminate unnecessary joins. 
    /// This module deals with the following kinds of joins
    ///    * Self-joins: The join can be eliminated, and either of the table instances can be
    ///                  used instead
    ///    * Implied self-joins: Same as above 
    ///    * PK-FK joins: (More generally, UK-FK joins): Eliminate the join, and use just the FK table, if no
    ///       column of the PK table is used (other than the join condition) 
    ///    * PK-PK joins: Eliminate the right side table, if we have a left-outer join 
    /// 
    internal class JoinElimination : BasicOpVisitorOfNode 
    {
        #region private state
        private PlanCompiler m_compilerState;
        private Command Command { get { return m_compilerState.Command; } } 
        private Dictionary m_joinGraphUnnecessaryMap;
        private VarRemapper m_varRemapper; 
        private ConstraintManager m_constraintManager = new ConstraintManager(); 
        private bool m_treeModified;
        private VarRefManager m_varRefManager; 
        #endregion

        #region constructors
        private JoinElimination(PlanCompiler compilerState) 
        {
            m_compilerState = compilerState; 
        } 
        #endregion
 
        #region public surface
        internal static void Process(PlanCompiler compilerState)
        {
            JoinElimination je = new JoinElimination(compilerState); 
            je.InitializeAndProcess();
 
            if (je.m_treeModified) 
            {
                compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.Transformations); 
                je.InitializeAndProcess();
            }
        }
        #endregion 

        #region private methods 
 
        /// 
        /// The main driver, initializes the state and invokes processing 
        /// 
        private void InitializeAndProcess()
        {
            Initialize(); 
            Process();
        } 
 
        /// 
        /// Ininitalizes the state of JoinElimination 
        /// 
        private void Initialize()
        {
            m_joinGraphUnnecessaryMap = new Dictionary(); 
            m_varRemapper = new VarRemapper(m_compilerState.Command);
            m_varRefManager = new VarRefManager(m_compilerState.Command); 
            m_treeModified = false; 
        }
 
        /// 
        /// Invokes the visitor
        /// 
        private void Process() 
        {
            this.Command.Root = VisitNode(this.Command.Root); 
        } 

        #region JoinHelpers 

        #region Building JoinGraphs
        /// 
        /// Do we need to build a join graph for this node - returns false, if we've already 
        /// processed this
        ///  
        ///  
        /// 
        private bool NeedsJoinGraph(Node joinNode) 
        {
            return !m_joinGraphUnnecessaryMap.ContainsKey(joinNode);
        }
 
        /// 
        /// Do the real processing of the join graph. 
        ///  
        /// current join node
        /// modified join node 
        private Node ProcessJoinGraph(Node joinNode)
        {
            // Build the join graph
            JoinGraph joinGraph = new JoinGraph(this.Command, this.m_constraintManager, this.m_varRefManager, joinNode); 

            // Get the transformed node tree 
            VarMap remappedVars; 
            Dictionary processedNodes;
            Node newNode = joinGraph.DoJoinElimination(out remappedVars, out processedNodes); 

            // Get the set of vars that need to be renamed
            foreach (KeyValuePair kv in remappedVars)
            { 
                m_varRemapper.AddMapping(kv.Key, kv.Value);
            } 
            // get the set of nodes that have already been processed 
            foreach (Node n in processedNodes.Keys)
            { 
                m_joinGraphUnnecessaryMap[n] = n;
            }

            return newNode; 
        }
 
        ///  
        /// Default handler for a node. Simply visits the children, then handles any var
        /// remapping, and then recomputes the node info 
        /// 
        /// 
        /// 
        private Node VisitDefaultForAllNodes(Node n) 
        {
            VisitChildren(n); 
            m_varRemapper.RemapNode(n); 
            this.Command.RecomputeNodeInfo(n);
            return n; 
        }

        #endregion
 
        #endregion
 
        #region Visitor overrides 

        ///  
        /// Invokes default handling for a node and adds the child-parent tracking info to the VarRefManager.
        /// 
        /// 
        ///  
        protected override Node VisitDefault(Node n)
        { 
            m_varRefManager.AddChildren(n); 
            return VisitDefaultForAllNodes(n);
        } 

        #region RelOps
        #region JoinOps
 
        /// 
        /// Build a join graph for this node for this node if necessary, and process it 
        ///  
        /// current join op
        /// current join node 
        /// 
        protected override Node VisitJoinOp(JoinBaseOp op, Node joinNode)
        {
            Node newNode; 

            // Build and process a join graph if necessary 
            if (NeedsJoinGraph(joinNode)) 
            {
                newNode = ProcessJoinGraph(joinNode); 
                if (newNode != joinNode)
                {
                    m_treeModified = true;
                } 
            }
            else 
            { 
                newNode = joinNode;
            } 

            // Now do the default processing (ie) visit the children, compute the nodeinfo etc.
            return VisitDefaultForAllNodes(newNode);
        } 

        #endregion 
 
        #endregion
        #endregion 

        #endregion

    } 
}

// 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 System.Globalization;

using System.Data.Query.InternalTrees; 

namespace System.Data.Query.PlanCompiler 
{ 
    /// 
    /// The JoinElimination module is intended to do just that - eliminate unnecessary joins. 
    /// This module deals with the following kinds of joins
    ///    * Self-joins: The join can be eliminated, and either of the table instances can be
    ///                  used instead
    ///    * Implied self-joins: Same as above 
    ///    * PK-FK joins: (More generally, UK-FK joins): Eliminate the join, and use just the FK table, if no
    ///       column of the PK table is used (other than the join condition) 
    ///    * PK-PK joins: Eliminate the right side table, if we have a left-outer join 
    /// 
    internal class JoinElimination : BasicOpVisitorOfNode 
    {
        #region private state
        private PlanCompiler m_compilerState;
        private Command Command { get { return m_compilerState.Command; } } 
        private Dictionary m_joinGraphUnnecessaryMap;
        private VarRemapper m_varRemapper; 
        private ConstraintManager m_constraintManager = new ConstraintManager(); 
        private bool m_treeModified;
        private VarRefManager m_varRefManager; 
        #endregion

        #region constructors
        private JoinElimination(PlanCompiler compilerState) 
        {
            m_compilerState = compilerState; 
        } 
        #endregion
 
        #region public surface
        internal static void Process(PlanCompiler compilerState)
        {
            JoinElimination je = new JoinElimination(compilerState); 
            je.InitializeAndProcess();
 
            if (je.m_treeModified) 
            {
                compilerState.MarkPhaseAsNeeded(PlanCompilerPhase.Transformations); 
                je.InitializeAndProcess();
            }
        }
        #endregion 

        #region private methods 
 
        /// 
        /// The main driver, initializes the state and invokes processing 
        /// 
        private void InitializeAndProcess()
        {
            Initialize(); 
            Process();
        } 
 
        /// 
        /// Ininitalizes the state of JoinElimination 
        /// 
        private void Initialize()
        {
            m_joinGraphUnnecessaryMap = new Dictionary(); 
            m_varRemapper = new VarRemapper(m_compilerState.Command);
            m_varRefManager = new VarRefManager(m_compilerState.Command); 
            m_treeModified = false; 
        }
 
        /// 
        /// Invokes the visitor
        /// 
        private void Process() 
        {
            this.Command.Root = VisitNode(this.Command.Root); 
        } 

        #region JoinHelpers 

        #region Building JoinGraphs
        /// 
        /// Do we need to build a join graph for this node - returns false, if we've already 
        /// processed this
        ///  
        ///  
        /// 
        private bool NeedsJoinGraph(Node joinNode) 
        {
            return !m_joinGraphUnnecessaryMap.ContainsKey(joinNode);
        }
 
        /// 
        /// Do the real processing of the join graph. 
        ///  
        /// current join node
        /// modified join node 
        private Node ProcessJoinGraph(Node joinNode)
        {
            // Build the join graph
            JoinGraph joinGraph = new JoinGraph(this.Command, this.m_constraintManager, this.m_varRefManager, joinNode); 

            // Get the transformed node tree 
            VarMap remappedVars; 
            Dictionary processedNodes;
            Node newNode = joinGraph.DoJoinElimination(out remappedVars, out processedNodes); 

            // Get the set of vars that need to be renamed
            foreach (KeyValuePair kv in remappedVars)
            { 
                m_varRemapper.AddMapping(kv.Key, kv.Value);
            } 
            // get the set of nodes that have already been processed 
            foreach (Node n in processedNodes.Keys)
            { 
                m_joinGraphUnnecessaryMap[n] = n;
            }

            return newNode; 
        }
 
        ///  
        /// Default handler for a node. Simply visits the children, then handles any var
        /// remapping, and then recomputes the node info 
        /// 
        /// 
        /// 
        private Node VisitDefaultForAllNodes(Node n) 
        {
            VisitChildren(n); 
            m_varRemapper.RemapNode(n); 
            this.Command.RecomputeNodeInfo(n);
            return n; 
        }

        #endregion
 
        #endregion
 
        #region Visitor overrides 

        ///  
        /// Invokes default handling for a node and adds the child-parent tracking info to the VarRefManager.
        /// 
        /// 
        ///  
        protected override Node VisitDefault(Node n)
        { 
            m_varRefManager.AddChildren(n); 
            return VisitDefaultForAllNodes(n);
        } 

        #region RelOps
        #region JoinOps
 
        /// 
        /// Build a join graph for this node for this node if necessary, and process it 
        ///  
        /// current join op
        /// current join node 
        /// 
        protected override Node VisitJoinOp(JoinBaseOp op, Node joinNode)
        {
            Node newNode; 

            // Build and process a join graph if necessary 
            if (NeedsJoinGraph(joinNode)) 
            {
                newNode = ProcessJoinGraph(joinNode); 
                if (newNode != joinNode)
                {
                    m_treeModified = true;
                } 
            }
            else 
            { 
                newNode = joinNode;
            } 

            // Now do the default processing (ie) visit the children, compute the nodeinfo etc.
            return VisitDefaultForAllNodes(newNode);
        } 

        #endregion 
 
        #endregion
        #endregion 

        #endregion

    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK