SqlSelectStatement.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 / SqlClient / SqlGen / SqlSelectStatement.cs / 2 / SqlSelectStatement.cs

                            //---------------------------------------------------------------------- 
// 
//      Copyright (c) Microsoft Corporation.  All rights reserved.
// 
// 
// @owner  [....], [....]
//--------------------------------------------------------------------- 
 
using System;
using System.Collections.Generic; 
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Data.SqlClient; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees; 
 
namespace System.Data.SqlClient.SqlGen
{ 
    /// 
    /// A SqlSelectStatement represents a canonical SQL SELECT statement.
    /// It has fields for the 5 main clauses
    ///  
    /// SELECT
    /// FROM 
    /// WHERE 
    /// GROUP BY
    /// ORDER BY 
    /// 
    /// We do not have HAVING, since the CQT does not have such a node.
    /// Each of the fields is a SqlBuilder, so we can keep appending SQL strings
    /// or other fragments to build up the clause. 
    ///
    /// We have a IsDistinct property to indicate that we want distict columns. 
    /// This is given out of band, since the input expression to the select clause 
    /// may already have some columns projected out, and we use append-only SqlBuilders.
    /// The DISTINCT is inserted when we finally write the object into a string. 
    ///
    /// Also, we have a Top property, which is non-null if the number of results should
    /// be limited to certain number. It is given out of band for the same reasons as DISTINCT.
    /// 
    /// The FromExtents contains the list of inputs in use for the select statement.
    /// There is usually just one element in this - Select statements for joins may 
    /// temporarily have more than one. 
    ///
    /// If the select statement is created by a Join node, we maintain a list of 
    /// all the extents that have been flattened in the join in AllJoinExtents
    /// 
    /// in J(j1= J(a,b), c)
    /// FromExtents has 2 nodes JoinSymbol(name=j1, ...) and Symbol(name=c) 
    /// AllJoinExtents has 3 nodes Symbol(name=a), Symbol(name=b), Symbol(name=c)
    ///  
    /// 
    /// If any expression in the non-FROM clause refers to an extent in a higher scope,
    /// we add that extent to the OuterExtents list.  This list denotes the list 
    /// of extent aliases that may collide with the aliases used in this select statement.
    /// It is set by .
    /// An extent is an outer extent if it is not one of the FromExtents.
    /// 
    ///
    ///  
    internal sealed class SqlSelectStatement : ISqlFragment 
    {
        private bool outputColumnsRenamed; 

        /// 
        /// Whether the columns ouput by this sql statement were renamed from what given in the command tree.
        ///  
        internal bool OutputColumnsRenamed
        { 
            get { return outputColumnsRenamed; } 
            set { outputColumnsRenamed = value; }
        } 

        private Dictionary outputColumns;

        ///  
        /// A dictionary of output columns, relevant only if output columns are renamed.
        ///  
        internal Dictionary OutputColumns 
        {
            get { return outputColumns; } 
            set { outputColumns = value; }
        }

        private bool isDistinct; 

        ///  
        /// Do we need to add a DISTINCT at the beginning of the SELECT 
        /// 
        internal bool IsDistinct 
        {
            get { return isDistinct; }
            set { isDistinct = value; }
        } 

        private List allJoinExtents; 
        internal List AllJoinExtents 
        {
            get { return allJoinExtents; } 
            // We have a setter as well, even though this is a list,
            // since we use this field only in special cases.
            set { allJoinExtents = value; }
        } 

        private List fromExtents; 
        internal List FromExtents 
        {
            get 
            {
                if (null == fromExtents)
                {
                    fromExtents = new List(); 
                }
                return fromExtents; 
            } 
        }
 
        private Dictionary outerExtents;
        internal Dictionary OuterExtents
        {
            get 
            {
                if (null == outerExtents) 
                { 
                    outerExtents = new Dictionary();
                } 
                return outerExtents;
            }
        }
 
        private TopClause top;
        internal TopClause Top 
        { 
            get { return top; }
            set 
            {
                Debug.Assert(top == null, "SqlSelectStatement.Top has already been set");
                top = value;
            } 
        }
 
        private SqlBuilder select = new SqlBuilder(); 
        internal SqlBuilder Select
        { 
            get { return select; }
        }

        private SqlBuilder from = new SqlBuilder(); 
        internal SqlBuilder From
        { 
            get { return from; } 
        }
 

        private SqlBuilder where;
        internal SqlBuilder Where
        { 
            get
            { 
                if (null == where) 
                {
                    where = new SqlBuilder(); 
                }
                return where;
            }
        } 

        private SqlBuilder groupBy; 
        internal SqlBuilder GroupBy 
        {
            get 
            {
                if (null == groupBy)
                {
                    groupBy = new SqlBuilder(); 
                }
                return groupBy; 
            } 
        }
 
        private SqlBuilder orderBy;
        public SqlBuilder OrderBy
        {
            get 
            {
                if (null == orderBy) 
                { 
                    orderBy = new SqlBuilder();
                } 
                return orderBy;
            }
        }
 
        //indicates whether it is the top most select statement,
        // if not Order By should be omitted unless there is a corresponding TOP 
        private bool isTopMost; 
        internal bool IsTopMost
        { 
            get { return this.isTopMost; }
            set { this.isTopMost = value; }
        }
 
        #region ISqlFragment Members
 
        ///  
        /// Write out a SQL select statement as a string.
        /// We have to 
        /// 
        /// Check whether the aliases extents we use in this statement have
        /// to be renamed.
        /// We first create a list of all the aliases used by the outer extents. 
        /// For each of the FromExtents( or AllJoinExtents if it is non-null),
        /// rename it if it collides with the previous list. 
        ///  
        /// Write each of the clauses (if it exists) as a string
        ///  
        /// 
        /// 
        /// 
        public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator) 
        {
            #region Check if FROM aliases need to be renamed 
 
            // Create a list of the aliases used by the outer extents
            // JoinSymbols have to be treated specially. 
            List outerExtentAliases = null;
            if ((null != outerExtents) && (0 < outerExtents.Count))
            {
                foreach (Symbol outerExtent in outerExtents.Keys) 
                {
                    JoinSymbol joinSymbol = outerExtent as JoinSymbol; 
                    if (joinSymbol != null) 
                    {
                        foreach (Symbol symbol in joinSymbol.FlattenedExtentList) 
                        {
                            if (null == outerExtentAliases) { outerExtentAliases = new List(); }
                            outerExtentAliases.Add(symbol.NewName);
                        } 
                    }
                    else 
                    { 
                        if (null == outerExtentAliases) { outerExtentAliases = new List(); }
                        outerExtentAliases.Add(outerExtent.NewName); 
                    }
                }
            }
 
            // An then rename each of the FromExtents we have
            // If AllJoinExtents is non-null - it has precedence. 
            // The new name is derived from the old name - we append an increasing int. 
            List extentList = this.AllJoinExtents ?? this.fromExtents;
            if (null != extentList) 
            {
                foreach (Symbol fromAlias in extentList)
                {
                    if ((null != outerExtentAliases) && outerExtentAliases.Contains(fromAlias.Name)) 
                    {
                        int i = sqlGenerator.AllExtentNames[fromAlias.Name]; 
                        string newName; 
                        do
                        { 
                            ++i;
                            newName = fromAlias.Name + i.ToString(System.Globalization.CultureInfo.InvariantCulture);
                        }
                        while (sqlGenerator.AllExtentNames.ContainsKey(newName)); 
                        sqlGenerator.AllExtentNames[fromAlias.Name] = i;
                        fromAlias.NewName = newName; 
 
                        // Add extent to list of known names (although i is always incrementing, "prefix11" can
                        // eventually collide with "prefix1" when it is extended) 
                        sqlGenerator.AllExtentNames[newName] = 0;
                    }

                    // Add the current alias to the list, so that the extents 
                    // that follow do not collide with me.
                    if (null == outerExtentAliases) { outerExtentAliases = new List(); } 
                    outerExtentAliases.Add(fromAlias.NewName); 
                }
            } 
            #endregion

            // Increase the indent, so that the Sql statement is nested by one tab.
            writer.Indent += 1; // ++ can be confusing in this context 

            writer.Write("SELECT "); 
            if (IsDistinct) 
            {
                writer.Write("DISTINCT "); 
            }

            if (this.Top != null)
            { 
                this.Top.WriteSql(writer, sqlGenerator);
            } 
 
            if ((null == this.select) || this.Select.IsEmpty)
            { 
                Debug.Assert(false);  // we have removed all possibilities of SELECT *.
                writer.Write("*");
            }
            else 
            {
                this.Select.WriteSql(writer, sqlGenerator); 
            } 

            writer.WriteLine(); 
            writer.Write("FROM ");
            this.From.WriteSql(writer, sqlGenerator);

            if ((null != this.where) && !this.Where.IsEmpty) 
            {
                writer.WriteLine(); 
                writer.Write("WHERE "); 
                this.Where.WriteSql(writer, sqlGenerator);
            } 

            if ((null != this.groupBy) && !this.GroupBy.IsEmpty)
            {
                writer.WriteLine(); 
                writer.Write("GROUP BY ");
                this.GroupBy.WriteSql(writer, sqlGenerator); 
            } 

            if ((null != this.orderBy) && !this.OrderBy.IsEmpty && (this.IsTopMost || this.Top != null)) 
            {
                writer.WriteLine();
                writer.Write("ORDER BY ");
                this.OrderBy.WriteSql(writer, sqlGenerator); 
            }
 
            --writer.Indent; 
        }
 
        #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;
using System.IO;
using System.Text;
using System.Data.SqlClient; 
using System.Data.Metadata.Edm;
using System.Data.Common.CommandTrees; 
 
namespace System.Data.SqlClient.SqlGen
{ 
    /// 
    /// A SqlSelectStatement represents a canonical SQL SELECT statement.
    /// It has fields for the 5 main clauses
    ///  
    /// SELECT
    /// FROM 
    /// WHERE 
    /// GROUP BY
    /// ORDER BY 
    /// 
    /// We do not have HAVING, since the CQT does not have such a node.
    /// Each of the fields is a SqlBuilder, so we can keep appending SQL strings
    /// or other fragments to build up the clause. 
    ///
    /// We have a IsDistinct property to indicate that we want distict columns. 
    /// This is given out of band, since the input expression to the select clause 
    /// may already have some columns projected out, and we use append-only SqlBuilders.
    /// The DISTINCT is inserted when we finally write the object into a string. 
    ///
    /// Also, we have a Top property, which is non-null if the number of results should
    /// be limited to certain number. It is given out of band for the same reasons as DISTINCT.
    /// 
    /// The FromExtents contains the list of inputs in use for the select statement.
    /// There is usually just one element in this - Select statements for joins may 
    /// temporarily have more than one. 
    ///
    /// If the select statement is created by a Join node, we maintain a list of 
    /// all the extents that have been flattened in the join in AllJoinExtents
    /// 
    /// in J(j1= J(a,b), c)
    /// FromExtents has 2 nodes JoinSymbol(name=j1, ...) and Symbol(name=c) 
    /// AllJoinExtents has 3 nodes Symbol(name=a), Symbol(name=b), Symbol(name=c)
    ///  
    /// 
    /// If any expression in the non-FROM clause refers to an extent in a higher scope,
    /// we add that extent to the OuterExtents list.  This list denotes the list 
    /// of extent aliases that may collide with the aliases used in this select statement.
    /// It is set by .
    /// An extent is an outer extent if it is not one of the FromExtents.
    /// 
    ///
    ///  
    internal sealed class SqlSelectStatement : ISqlFragment 
    {
        private bool outputColumnsRenamed; 

        /// 
        /// Whether the columns ouput by this sql statement were renamed from what given in the command tree.
        ///  
        internal bool OutputColumnsRenamed
        { 
            get { return outputColumnsRenamed; } 
            set { outputColumnsRenamed = value; }
        } 

        private Dictionary outputColumns;

        ///  
        /// A dictionary of output columns, relevant only if output columns are renamed.
        ///  
        internal Dictionary OutputColumns 
        {
            get { return outputColumns; } 
            set { outputColumns = value; }
        }

        private bool isDistinct; 

        ///  
        /// Do we need to add a DISTINCT at the beginning of the SELECT 
        /// 
        internal bool IsDistinct 
        {
            get { return isDistinct; }
            set { isDistinct = value; }
        } 

        private List allJoinExtents; 
        internal List AllJoinExtents 
        {
            get { return allJoinExtents; } 
            // We have a setter as well, even though this is a list,
            // since we use this field only in special cases.
            set { allJoinExtents = value; }
        } 

        private List fromExtents; 
        internal List FromExtents 
        {
            get 
            {
                if (null == fromExtents)
                {
                    fromExtents = new List(); 
                }
                return fromExtents; 
            } 
        }
 
        private Dictionary outerExtents;
        internal Dictionary OuterExtents
        {
            get 
            {
                if (null == outerExtents) 
                { 
                    outerExtents = new Dictionary();
                } 
                return outerExtents;
            }
        }
 
        private TopClause top;
        internal TopClause Top 
        { 
            get { return top; }
            set 
            {
                Debug.Assert(top == null, "SqlSelectStatement.Top has already been set");
                top = value;
            } 
        }
 
        private SqlBuilder select = new SqlBuilder(); 
        internal SqlBuilder Select
        { 
            get { return select; }
        }

        private SqlBuilder from = new SqlBuilder(); 
        internal SqlBuilder From
        { 
            get { return from; } 
        }
 

        private SqlBuilder where;
        internal SqlBuilder Where
        { 
            get
            { 
                if (null == where) 
                {
                    where = new SqlBuilder(); 
                }
                return where;
            }
        } 

        private SqlBuilder groupBy; 
        internal SqlBuilder GroupBy 
        {
            get 
            {
                if (null == groupBy)
                {
                    groupBy = new SqlBuilder(); 
                }
                return groupBy; 
            } 
        }
 
        private SqlBuilder orderBy;
        public SqlBuilder OrderBy
        {
            get 
            {
                if (null == orderBy) 
                { 
                    orderBy = new SqlBuilder();
                } 
                return orderBy;
            }
        }
 
        //indicates whether it is the top most select statement,
        // if not Order By should be omitted unless there is a corresponding TOP 
        private bool isTopMost; 
        internal bool IsTopMost
        { 
            get { return this.isTopMost; }
            set { this.isTopMost = value; }
        }
 
        #region ISqlFragment Members
 
        ///  
        /// Write out a SQL select statement as a string.
        /// We have to 
        /// 
        /// Check whether the aliases extents we use in this statement have
        /// to be renamed.
        /// We first create a list of all the aliases used by the outer extents. 
        /// For each of the FromExtents( or AllJoinExtents if it is non-null),
        /// rename it if it collides with the previous list. 
        ///  
        /// Write each of the clauses (if it exists) as a string
        ///  
        /// 
        /// 
        /// 
        public void WriteSql(SqlWriter writer, SqlGenerator sqlGenerator) 
        {
            #region Check if FROM aliases need to be renamed 
 
            // Create a list of the aliases used by the outer extents
            // JoinSymbols have to be treated specially. 
            List outerExtentAliases = null;
            if ((null != outerExtents) && (0 < outerExtents.Count))
            {
                foreach (Symbol outerExtent in outerExtents.Keys) 
                {
                    JoinSymbol joinSymbol = outerExtent as JoinSymbol; 
                    if (joinSymbol != null) 
                    {
                        foreach (Symbol symbol in joinSymbol.FlattenedExtentList) 
                        {
                            if (null == outerExtentAliases) { outerExtentAliases = new List(); }
                            outerExtentAliases.Add(symbol.NewName);
                        } 
                    }
                    else 
                    { 
                        if (null == outerExtentAliases) { outerExtentAliases = new List(); }
                        outerExtentAliases.Add(outerExtent.NewName); 
                    }
                }
            }
 
            // An then rename each of the FromExtents we have
            // If AllJoinExtents is non-null - it has precedence. 
            // The new name is derived from the old name - we append an increasing int. 
            List extentList = this.AllJoinExtents ?? this.fromExtents;
            if (null != extentList) 
            {
                foreach (Symbol fromAlias in extentList)
                {
                    if ((null != outerExtentAliases) && outerExtentAliases.Contains(fromAlias.Name)) 
                    {
                        int i = sqlGenerator.AllExtentNames[fromAlias.Name]; 
                        string newName; 
                        do
                        { 
                            ++i;
                            newName = fromAlias.Name + i.ToString(System.Globalization.CultureInfo.InvariantCulture);
                        }
                        while (sqlGenerator.AllExtentNames.ContainsKey(newName)); 
                        sqlGenerator.AllExtentNames[fromAlias.Name] = i;
                        fromAlias.NewName = newName; 
 
                        // Add extent to list of known names (although i is always incrementing, "prefix11" can
                        // eventually collide with "prefix1" when it is extended) 
                        sqlGenerator.AllExtentNames[newName] = 0;
                    }

                    // Add the current alias to the list, so that the extents 
                    // that follow do not collide with me.
                    if (null == outerExtentAliases) { outerExtentAliases = new List(); } 
                    outerExtentAliases.Add(fromAlias.NewName); 
                }
            } 
            #endregion

            // Increase the indent, so that the Sql statement is nested by one tab.
            writer.Indent += 1; // ++ can be confusing in this context 

            writer.Write("SELECT "); 
            if (IsDistinct) 
            {
                writer.Write("DISTINCT "); 
            }

            if (this.Top != null)
            { 
                this.Top.WriteSql(writer, sqlGenerator);
            } 
 
            if ((null == this.select) || this.Select.IsEmpty)
            { 
                Debug.Assert(false);  // we have removed all possibilities of SELECT *.
                writer.Write("*");
            }
            else 
            {
                this.Select.WriteSql(writer, sqlGenerator); 
            } 

            writer.WriteLine(); 
            writer.Write("FROM ");
            this.From.WriteSql(writer, sqlGenerator);

            if ((null != this.where) && !this.Where.IsEmpty) 
            {
                writer.WriteLine(); 
                writer.Write("WHERE "); 
                this.Where.WriteSql(writer, sqlGenerator);
            } 

            if ((null != this.groupBy) && !this.GroupBy.IsEmpty)
            {
                writer.WriteLine(); 
                writer.Write("GROUP BY ");
                this.GroupBy.WriteSql(writer, sqlGenerator); 
            } 

            if ((null != this.orderBy) && !this.OrderBy.IsEmpty && (this.IsTopMost || this.Top != null)) 
            {
                writer.WriteLine();
                writer.Write("ORDER BY ");
                this.OrderBy.WriteSql(writer, sqlGenerator); 
            }
 
            --writer.Indent; 
        }
 
        #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