SqlColumnizer.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 / DLinq / Dlinq / SqlClient / Query / SqlColumnizer.cs / 1 / SqlColumnizer.cs

                            using System; 
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Data.Linq; 
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider; 
using System.Linq; 
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis; 

namespace System.Data.Linq.SqlClient {

    // partions select expressions and common subexpressions into scalar and non-scalar pieces by 
    // wrapping scalar pieces floating column nodes.
    internal class SqlColumnizer { 
        ColumnNominator nominator; 
        ColumnDeclarer declarer;
 
        internal SqlColumnizer(Func fnCanBeColumn) {
            this.nominator = new ColumnNominator(fnCanBeColumn);
            this.declarer = new ColumnDeclarer();
        } 

        internal SqlExpression ColumnizeSelection(SqlExpression selection) { 
            return this.declarer.Declare(selection, this.nominator.Nominate(selection)); 
        }
 
        class ColumnDeclarer : SqlVisitor {
            HashSet candidates;

            internal ColumnDeclarer() { 
            }
 
            internal SqlExpression Declare(SqlExpression expression, HashSet candidates) { 
                this.candidates = candidates;
                return (SqlExpression)this.Visit(expression); 
            }

            internal override SqlNode Visit(SqlNode node) {
                SqlExpression expr = node as SqlExpression; 
                if (expr != null) {
                    if (this.candidates.Contains(expr)) { 
                        if (expr.NodeType == SqlNodeType.Column || 
                            expr.NodeType == SqlNodeType.ColumnRef) {
                            return expr; 
                        }
                        else {
                            return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
                        } 
                    }
                } 
                return base.Visit(node); 
            }
        } 

        class ColumnNominator : SqlVisitor {
            bool isBlocked;
            HashSet candidates; 
            Func fnCanBeColumn;
 
            internal ColumnNominator(Func fnCanBeColumn) { 
                this.fnCanBeColumn = fnCanBeColumn;
            } 

            internal HashSet Nominate(SqlExpression expression) {
                this.candidates = new HashSet();
                this.isBlocked = false; 
                this.Visit(expression);
                return this.candidates; 
            } 

            internal override SqlNode Visit(SqlNode node) { 
                SqlExpression expression = node as SqlExpression;
                if (expression != null) {
                    bool saveIsBlocked = this.isBlocked;
                    this.isBlocked = false; 
                    if (CanRecurseColumnize(expression)) {
                        base.Visit(expression); 
                    } 
                    if (!this.isBlocked) {
                        if (!IsClientOnly(expression) 
                            && expression.NodeType != SqlNodeType.Column
                            && expression.SqlType.CanBeColumn
                            && (this.fnCanBeColumn == null || this.fnCanBeColumn(expression))
                            ) { 
                            this.candidates.Add(expression);
                        } 
                        else { 
                            this.isBlocked = true;
                        } 
                    }
                    this.isBlocked |= saveIsBlocked;
                }
                return node; 
            }
 
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { 
                c.Expression = this.VisitExpression(c.Expression);
                for (int i = 0, n = c.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
                }
                return c; 
            }
 
            internal override SqlExpression VisitTypeCase(SqlTypeCase tc) { 
                tc.Discriminator = this.VisitExpression(tc.Discriminator);
                for (int i = 0, n = tc.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
                }
                return tc; 
            }
 
            internal override SqlExpression VisitClientCase(SqlClientCase c) { 
                c.Expression = this.VisitExpression(c.Expression);
                for (int i = 0, n = c.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
                }
                return c; 
            }
 
            private static bool CanRecurseColumnize(SqlExpression expr) { 
                switch (expr.NodeType) {
                    case SqlNodeType.AliasRef: 
                    case SqlNodeType.ColumnRef:
                    case SqlNodeType.Column:
                    case SqlNodeType.Multiset:
                    case SqlNodeType.Element: 
                    case SqlNodeType.ScalarSubSelect:
                    case SqlNodeType.Exists: 
                    case SqlNodeType.ClientQuery: 
                    case SqlNodeType.SharedExpressionRef:
                    case SqlNodeType.Link: 
                    case SqlNodeType.Nop:
                    case SqlNodeType.Value:
                    case SqlNodeType.Select:
                        return false; 
                    default:
                        return true; 
                } 
            }
 
            [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
            private static bool IsClientOnly(SqlExpression expr) {
                switch (expr.NodeType) {
                    case SqlNodeType.ClientCase: 
                    case SqlNodeType.TypeCase:
                    case SqlNodeType.ClientArray: 
                    case SqlNodeType.Grouping: 
                    case SqlNodeType.DiscriminatedType:
                    case SqlNodeType.SharedExpression: 
                    case SqlNodeType.SimpleExpression:
                    case SqlNodeType.AliasRef:
                    case SqlNodeType.Multiset:
                    case SqlNodeType.Element: 
                    case SqlNodeType.ClientQuery:
                    case SqlNodeType.SharedExpressionRef: 
                    case SqlNodeType.Link: 
                    case SqlNodeType.Nop:
                        return true; 
                    case SqlNodeType.OuterJoinedValue:
                        return IsClientOnly(((SqlUnary)expr).Operand);
                    default:
                        return false; 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System; 
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Data.Linq; 
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider; 
using System.Linq; 
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis; 

namespace System.Data.Linq.SqlClient {

    // partions select expressions and common subexpressions into scalar and non-scalar pieces by 
    // wrapping scalar pieces floating column nodes.
    internal class SqlColumnizer { 
        ColumnNominator nominator; 
        ColumnDeclarer declarer;
 
        internal SqlColumnizer(Func fnCanBeColumn) {
            this.nominator = new ColumnNominator(fnCanBeColumn);
            this.declarer = new ColumnDeclarer();
        } 

        internal SqlExpression ColumnizeSelection(SqlExpression selection) { 
            return this.declarer.Declare(selection, this.nominator.Nominate(selection)); 
        }
 
        class ColumnDeclarer : SqlVisitor {
            HashSet candidates;

            internal ColumnDeclarer() { 
            }
 
            internal SqlExpression Declare(SqlExpression expression, HashSet candidates) { 
                this.candidates = candidates;
                return (SqlExpression)this.Visit(expression); 
            }

            internal override SqlNode Visit(SqlNode node) {
                SqlExpression expr = node as SqlExpression; 
                if (expr != null) {
                    if (this.candidates.Contains(expr)) { 
                        if (expr.NodeType == SqlNodeType.Column || 
                            expr.NodeType == SqlNodeType.ColumnRef) {
                            return expr; 
                        }
                        else {
                            return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
                        } 
                    }
                } 
                return base.Visit(node); 
            }
        } 

        class ColumnNominator : SqlVisitor {
            bool isBlocked;
            HashSet candidates; 
            Func fnCanBeColumn;
 
            internal ColumnNominator(Func fnCanBeColumn) { 
                this.fnCanBeColumn = fnCanBeColumn;
            } 

            internal HashSet Nominate(SqlExpression expression) {
                this.candidates = new HashSet();
                this.isBlocked = false; 
                this.Visit(expression);
                return this.candidates; 
            } 

            internal override SqlNode Visit(SqlNode node) { 
                SqlExpression expression = node as SqlExpression;
                if (expression != null) {
                    bool saveIsBlocked = this.isBlocked;
                    this.isBlocked = false; 
                    if (CanRecurseColumnize(expression)) {
                        base.Visit(expression); 
                    } 
                    if (!this.isBlocked) {
                        if (!IsClientOnly(expression) 
                            && expression.NodeType != SqlNodeType.Column
                            && expression.SqlType.CanBeColumn
                            && (this.fnCanBeColumn == null || this.fnCanBeColumn(expression))
                            ) { 
                            this.candidates.Add(expression);
                        } 
                        else { 
                            this.isBlocked = true;
                        } 
                    }
                    this.isBlocked |= saveIsBlocked;
                }
                return node; 
            }
 
            internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) { 
                c.Expression = this.VisitExpression(c.Expression);
                for (int i = 0, n = c.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
                }
                return c; 
            }
 
            internal override SqlExpression VisitTypeCase(SqlTypeCase tc) { 
                tc.Discriminator = this.VisitExpression(tc.Discriminator);
                for (int i = 0, n = tc.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
                }
                return tc; 
            }
 
            internal override SqlExpression VisitClientCase(SqlClientCase c) { 
                c.Expression = this.VisitExpression(c.Expression);
                for (int i = 0, n = c.Whens.Count; i < n; i++) { 
                    // Don't walk down the match side. This can't be a column.
                    c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
                }
                return c; 
            }
 
            private static bool CanRecurseColumnize(SqlExpression expr) { 
                switch (expr.NodeType) {
                    case SqlNodeType.AliasRef: 
                    case SqlNodeType.ColumnRef:
                    case SqlNodeType.Column:
                    case SqlNodeType.Multiset:
                    case SqlNodeType.Element: 
                    case SqlNodeType.ScalarSubSelect:
                    case SqlNodeType.Exists: 
                    case SqlNodeType.ClientQuery: 
                    case SqlNodeType.SharedExpressionRef:
                    case SqlNodeType.Link: 
                    case SqlNodeType.Nop:
                    case SqlNodeType.Value:
                    case SqlNodeType.Select:
                        return false; 
                    default:
                        return true; 
                } 
            }
 
            [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
            private static bool IsClientOnly(SqlExpression expr) {
                switch (expr.NodeType) {
                    case SqlNodeType.ClientCase: 
                    case SqlNodeType.TypeCase:
                    case SqlNodeType.ClientArray: 
                    case SqlNodeType.Grouping: 
                    case SqlNodeType.DiscriminatedType:
                    case SqlNodeType.SharedExpression: 
                    case SqlNodeType.SimpleExpression:
                    case SqlNodeType.AliasRef:
                    case SqlNodeType.Multiset:
                    case SqlNodeType.Element: 
                    case SqlNodeType.ClientQuery:
                    case SqlNodeType.SharedExpressionRef: 
                    case SqlNodeType.Link: 
                    case SqlNodeType.Nop:
                        return true; 
                    case SqlNodeType.OuterJoinedValue:
                        return IsClientOnly(((SqlUnary)expr).Operand);
                    default:
                        return false; 
                }
            } 
        } 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

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