JoinElimination.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntity / System / Data / Query / PlanCompiler / JoinElimination.cs / 1305376 / JoinElimination.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

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 ConstraintManager ConstraintManager { get { return m_compilerState.ConstraintManager;  } } 
        private Dictionary m_joinGraphUnnecessaryMap = new Dictionary(); 
        private VarRemapper m_varRemapper;
        private bool m_treeModified = false; 
        private VarRefManager m_varRefManager;
        #endregion

        #region constructors 
        private JoinElimination(PlanCompiler compilerState)
        { 
            m_compilerState = compilerState; 
            m_varRemapper = new VarRemapper(m_compilerState.Command);
            m_varRefManager = new VarRefManager(m_compilerState.Command); 
        }
        #endregion

        #region public surface 
        internal static bool Process(PlanCompiler compilerState)
        { 
            JoinElimination je = new JoinElimination(compilerState); 
            je.Process();
            return je.m_treeModified; 
        }
        #endregion

        #region private methods 

        ///  
        /// 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.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  [....]
// @backupOwner [....] 
//--------------------------------------------------------------------- 

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 ConstraintManager ConstraintManager { get { return m_compilerState.ConstraintManager;  } } 
        private Dictionary m_joinGraphUnnecessaryMap = new Dictionary(); 
        private VarRemapper m_varRemapper;
        private bool m_treeModified = false; 
        private VarRefManager m_varRefManager;
        #endregion

        #region constructors 
        private JoinElimination(PlanCompiler compilerState)
        { 
            m_compilerState = compilerState; 
            m_varRemapper = new VarRemapper(m_compilerState.Command);
            m_varRefManager = new VarRefManager(m_compilerState.Command); 
        }
        #endregion

        #region public surface 
        internal static bool Process(PlanCompiler compilerState)
        { 
            JoinElimination je = new JoinElimination(compilerState); 
            je.Process();
            return je.m_treeModified; 
        }
        #endregion

        #region private methods 

        ///  
        /// 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.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