Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlDeflator.cs / 1305376 / SqlDeflator.cs
using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace System.Data.Linq.SqlClient { internal class SqlDeflator { SqlValueDeflator vDeflator; SqlColumnDeflator cDeflator; SqlAliasDeflator aDeflator; SqlTopSelectDeflator tsDeflator; SqlDuplicateColumnDeflator dupColumnDeflator; internal SqlDeflator() { this.vDeflator = new SqlValueDeflator(); this.cDeflator = new SqlColumnDeflator(); this.aDeflator = new SqlAliasDeflator(); this.tsDeflator = new SqlTopSelectDeflator(); this.dupColumnDeflator = new SqlDuplicateColumnDeflator(); } internal SqlNode Deflate(SqlNode node) { node = this.vDeflator.Visit(node); node = this.cDeflator.Visit(node); node = this.aDeflator.Visit(node); node = this.tsDeflator.Visit(node); node = this.dupColumnDeflator.Visit(node); return node; } // remove references to literal values class SqlValueDeflator : SqlVisitor { SelectionDeflator sDeflator; bool isTopLevel = true; internal SqlValueDeflator() { this.sDeflator = new SelectionDeflator(); } internal override SqlSelect VisitSelect(SqlSelect select) { if (this.isTopLevel) { select.Selection = sDeflator.VisitExpression(select.Selection); } return select; } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; try { return base.VisitSubSelect(ss); } finally { this.isTopLevel = saveIsTopLevel; } } class SelectionDeflator : SqlVisitor { internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlExpression literal = this.GetLiteralValue(cref); if (literal != null) { return literal; } return cref; } private SqlValue GetLiteralValue(SqlExpression expr) { while (expr != null && expr.NodeType == SqlNodeType.ColumnRef) { expr = ((SqlColumnRef)expr).Column.Expression; } return expr as SqlValue; } } } // remove unreferenced items in projection list class SqlColumnDeflator : SqlVisitor { DictionaryreferenceMap; bool isTopLevel; bool forceReferenceAll; SqlAggregateChecker aggregateChecker; internal SqlColumnDeflator() { this.referenceMap = new Dictionary (); this.aggregateChecker = new SqlAggregateChecker(); this.isTopLevel = true; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { this.referenceMap[cref.Column] = cref.Column; return cref; } internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = true; try { return base.VisitScalarSubSelect(ss); } finally { this.isTopLevel = saveIsTopLevel; this.forceReferenceAll = saveForceReferenceAll; } } internal override SqlExpression VisitExists(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; try { return base.VisitExists(ss); } finally { this.isTopLevel = saveIsTopLevel; } } internal override SqlNode VisitUnion(SqlUnion su) { bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = true; su.Left = this.Visit(su.Left); su.Right = this.Visit(su.Right); this.forceReferenceAll = saveForceReferenceAll; return su; } internal override SqlSelect VisitSelect(SqlSelect select) { bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = false; bool saveIsTopLevel = this.isTopLevel; try { if (this.isTopLevel) { // top-level projection references columns! select.Selection = this.VisitExpression(select.Selection); } this.isTopLevel = false; for (int i = select.Row.Columns.Count - 1; i >= 0; i--) { SqlColumn c = select.Row.Columns[i]; bool safeToRemove = !saveForceReferenceAll && !this.referenceMap.ContainsKey(c) // don't remove anything from a distinct select (except maybe a literal value) since it would change the meaning of the comparison && !select.IsDistinct // don't remove an aggregate expression that may be the only expression that forces the grouping (since it would change the cardinality of the results) && !(select.GroupBy.Count == 0 && this.aggregateChecker.HasAggregates(c.Expression)); if (safeToRemove) { select.Row.Columns.RemoveAt(i); } else { this.VisitExpression(c.Expression); } } select.Top = this.VisitExpression(select.Top); for (int i = select.OrderBy.Count - 1; i >= 0; i--) { select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression); } select.Having = this.VisitExpression(select.Having); for (int i = select.GroupBy.Count - 1; i >= 0; i--) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } select.Where = this.VisitExpression(select.Where); select.From = this.VisitSource(select.From); } finally { this.isTopLevel = saveIsTopLevel; this.forceReferenceAll = saveForceReferenceAll; } return select; } internal override SqlSource VisitJoin(SqlJoin join) { join.Condition = this.VisitExpression(join.Condition); join.Right = this.VisitSource(join.Right); join.Left = this.VisitSource(join.Left); return join; } internal override SqlNode VisitLink(SqlLink link) { // don't visit expansion... for (int i = 0, n = link.KeyExpressions.Count; i < n; i++) { link.KeyExpressions[i] = this.VisitExpression(link.KeyExpressions[i]); } return link; } } class SqlColumnEqualizer : SqlVisitor { Dictionary map; internal SqlColumnEqualizer() { } internal void BuildEqivalenceMap(SqlSource scope) { this.map = new Dictionary (); this.Visit(scope); } internal bool AreEquivalent(SqlExpression e1, SqlExpression e2) { if (SqlComparer.AreEqual(e1, e2)) return true; SqlColumnRef cr1 = e1 as SqlColumnRef; SqlColumnRef cr2 = e2 as SqlColumnRef; if (cr1 != null && cr2 != null) { SqlColumn c1 = cr1.GetRootColumn(); SqlColumn c2 = cr2.GetRootColumn(); SqlColumn r; return this.map.TryGetValue(c1, out r) && r == c2; } return false; } internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(join); if (join.Condition != null) { this.CheckJoinCondition(join.Condition); } return join; } internal override SqlSelect VisitSelect(SqlSelect select) { base.VisitSelect(select); if (select.Where != null) { this.CheckJoinCondition(select.Where); } return select; } [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] private void CheckJoinCondition(SqlExpression expr) { switch (expr.NodeType) { case SqlNodeType.And: { SqlBinary b = (SqlBinary)expr; CheckJoinCondition(b.Left); CheckJoinCondition(b.Right); break; } case SqlNodeType.EQ: case SqlNodeType.EQ2V: { SqlBinary b = (SqlBinary)expr; SqlColumnRef crLeft = b.Left as SqlColumnRef; SqlColumnRef crRight = b.Right as SqlColumnRef; if (crLeft != null && crRight != null) { SqlColumn cLeft = crLeft.GetRootColumn(); SqlColumn cRight = crRight.GetRootColumn(); this.map[cLeft] = cRight; this.map[cRight] = cLeft; } break; } } } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return ss; } } // remove redundant/trivial aliases class SqlAliasDeflator : SqlVisitor { Dictionary removedMap; internal SqlAliasDeflator() { this.removedMap = new Dictionary (); } internal override SqlExpression VisitAliasRef(SqlAliasRef aref) { SqlAlias alias = aref.Alias; SqlAlias value; if (this.removedMap.TryGetValue(alias, out value)) { throw Error.InvalidReferenceToRemovedAliasDuringDeflation(); } return aref; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { if (cref.Column.Alias != null && this.removedMap.ContainsKey(cref.Column.Alias)) { SqlColumnRef c = cref.Column.Expression as SqlColumnRef; if (c != null) { //The following code checks for cases where there are differences between the type returned //by a ColumnRef and the column that refers to it. This situation can occur when conversions //are optimized out of the SQL node tree. As mentioned in the SetClrType comments this is not //an operation that can have adverse effects and should only be used in limited cases, such as //this one. if (c.ClrType != cref.ClrType) { c.SetClrType(cref.ClrType); return this.VisitColumnRef(c); } } return c; } return cref; } internal override SqlSource VisitSource(SqlSource node) { node = (SqlSource)this.Visit(node); SqlAlias alias = node as SqlAlias; if (alias != null) { SqlSelect sel = alias.Node as SqlSelect; if (sel != null && this.IsTrivialSelect(sel)) { this.removedMap[alias] = alias; node = sel.From; } } return node; } internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(join); switch (join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.Inner: // reducing either side would effect cardinality of results break; case SqlJoinType.LeftOuter: case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: // may reduce to left if no references to the right if (this.HasEmptySource(join.Right)) { SqlAlias a = (SqlAlias)join.Right; this.removedMap[a] = a; return join.Left; } break; } return join; } private bool IsTrivialSelect(SqlSelect select) { if (select.OrderBy.Count != 0 || select.GroupBy.Count != 0 || select.Having != null || select.Top != null || select.IsDistinct || select.Where != null) return false; return this.HasTrivialSource(select.From) && this.HasTrivialProjection(select); } private bool HasTrivialSource(SqlSource node) { SqlJoin join = node as SqlJoin; if (join != null) { return this.HasTrivialSource(join.Left) && this.HasTrivialSource(join.Right); } return node is SqlAlias; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialProjection(SqlSelect select) { foreach (SqlColumn c in select.Row.Columns) { if (c.Expression != null && c.Expression.NodeType != SqlNodeType.ColumnRef) { return false; } } return true; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasEmptySource(SqlSource node) { SqlAlias alias = node as SqlAlias; if (alias == null) return false; SqlSelect sel = alias.Node as SqlSelect; if (sel == null) return false; return sel.Row.Columns.Count == 0 && sel.From == null && sel.Where == null && sel.GroupBy.Count == 0 && sel.Having == null && sel.OrderBy.Count == 0; } } // remove duplicate columns from order by and group by lists class SqlDuplicateColumnDeflator : SqlVisitor { SqlColumnEqualizer equalizer = new SqlColumnEqualizer(); internal override SqlSelect VisitSelect(SqlSelect select) { select.From = this.VisitSource(select.From); select.Where = this.VisitExpression(select.Where); for (int i = 0, n = select.GroupBy.Count; i < n; i++) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } // remove duplicate group expressions for (int i = select.GroupBy.Count - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { if (SqlComparer.AreEqual(select.GroupBy[i], select.GroupBy[j])) { select.GroupBy.RemoveAt(i); break; } } } select.Having = this.VisitExpression(select.Having); for (int i = 0, n = select.OrderBy.Count; i < n; i++) { select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression); } // remove duplicate order expressions if (select.OrderBy.Count > 0) { this.equalizer.BuildEqivalenceMap(select.From); for (int i = select.OrderBy.Count - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { if (this.equalizer.AreEquivalent(select.OrderBy[i].Expression, select.OrderBy[j].Expression)) { select.OrderBy.RemoveAt(i); break; } } } } select.Top = this.VisitExpression(select.Top); select.Row = (SqlRow)this.Visit(select.Row); select.Selection = this.VisitExpression(select.Selection); return select; } } // if the top level select is simply a reprojection of the subquery, then remove it, // pushing any distinct names down class SqlTopSelectDeflator : SqlVisitor { internal override SqlSelect VisitSelect(SqlSelect select) { if (IsTrivialSelect(select)) { SqlSelect aselect = (SqlSelect)((SqlAlias)select.From).Node; // build up a column map, so we can rewrite the top-level selection expression Dictionary map = new Dictionary (); foreach (SqlColumn c in select.Row.Columns) { SqlColumnRef cref = (SqlColumnRef)c.Expression; map.Add(c, cref); // push the interesting column names down (non null) if (!string.IsNullOrEmpty(c.Name)) { cref.Column.Name = c.Name; } } aselect.Selection = new ColumnMapper(map).VisitExpression(select.Selection); return aselect; } return select; } private bool IsTrivialSelect(SqlSelect select) { if (select.OrderBy.Count != 0 || select.GroupBy.Count != 0 || select.Having != null || select.Top != null || select.IsDistinct || select.Where != null) return false; return this.HasTrivialSource(select.From) && this.HasTrivialProjection(select); } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialSource(SqlSource node) { SqlAlias alias = node as SqlAlias; if (alias == null) return false; return alias.Node is SqlSelect; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialProjection(SqlSelect select) { foreach (SqlColumn c in select.Row.Columns) { if (c.Expression != null && c.Expression.NodeType != SqlNodeType.ColumnRef) { return false; } } return true; } class ColumnMapper : SqlVisitor { Dictionary map; internal ColumnMapper(Dictionary map) { this.map = map; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumnRef mapped; if (this.map.TryGetValue(cref.Column, out mapped)) { return mapped; } return cref; } } } } } // 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.Diagnostics.CodeAnalysis; namespace System.Data.Linq.SqlClient { internal class SqlDeflator { SqlValueDeflator vDeflator; SqlColumnDeflator cDeflator; SqlAliasDeflator aDeflator; SqlTopSelectDeflator tsDeflator; SqlDuplicateColumnDeflator dupColumnDeflator; internal SqlDeflator() { this.vDeflator = new SqlValueDeflator(); this.cDeflator = new SqlColumnDeflator(); this.aDeflator = new SqlAliasDeflator(); this.tsDeflator = new SqlTopSelectDeflator(); this.dupColumnDeflator = new SqlDuplicateColumnDeflator(); } internal SqlNode Deflate(SqlNode node) { node = this.vDeflator.Visit(node); node = this.cDeflator.Visit(node); node = this.aDeflator.Visit(node); node = this.tsDeflator.Visit(node); node = this.dupColumnDeflator.Visit(node); return node; } // remove references to literal values class SqlValueDeflator : SqlVisitor { SelectionDeflator sDeflator; bool isTopLevel = true; internal SqlValueDeflator() { this.sDeflator = new SelectionDeflator(); } internal override SqlSelect VisitSelect(SqlSelect select) { if (this.isTopLevel) { select.Selection = sDeflator.VisitExpression(select.Selection); } return select; } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; try { return base.VisitSubSelect(ss); } finally { this.isTopLevel = saveIsTopLevel; } } class SelectionDeflator : SqlVisitor { internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlExpression literal = this.GetLiteralValue(cref); if (literal != null) { return literal; } return cref; } private SqlValue GetLiteralValue(SqlExpression expr) { while (expr != null && expr.NodeType == SqlNodeType.ColumnRef) { expr = ((SqlColumnRef)expr).Column.Expression; } return expr as SqlValue; } } } // remove unreferenced items in projection list class SqlColumnDeflator : SqlVisitor { Dictionary referenceMap; bool isTopLevel; bool forceReferenceAll; SqlAggregateChecker aggregateChecker; internal SqlColumnDeflator() { this.referenceMap = new Dictionary (); this.aggregateChecker = new SqlAggregateChecker(); this.isTopLevel = true; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { this.referenceMap[cref.Column] = cref.Column; return cref; } internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = true; try { return base.VisitScalarSubSelect(ss); } finally { this.isTopLevel = saveIsTopLevel; this.forceReferenceAll = saveForceReferenceAll; } } internal override SqlExpression VisitExists(SqlSubSelect ss) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; try { return base.VisitExists(ss); } finally { this.isTopLevel = saveIsTopLevel; } } internal override SqlNode VisitUnion(SqlUnion su) { bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = true; su.Left = this.Visit(su.Left); su.Right = this.Visit(su.Right); this.forceReferenceAll = saveForceReferenceAll; return su; } internal override SqlSelect VisitSelect(SqlSelect select) { bool saveForceReferenceAll = this.forceReferenceAll; this.forceReferenceAll = false; bool saveIsTopLevel = this.isTopLevel; try { if (this.isTopLevel) { // top-level projection references columns! select.Selection = this.VisitExpression(select.Selection); } this.isTopLevel = false; for (int i = select.Row.Columns.Count - 1; i >= 0; i--) { SqlColumn c = select.Row.Columns[i]; bool safeToRemove = !saveForceReferenceAll && !this.referenceMap.ContainsKey(c) // don't remove anything from a distinct select (except maybe a literal value) since it would change the meaning of the comparison && !select.IsDistinct // don't remove an aggregate expression that may be the only expression that forces the grouping (since it would change the cardinality of the results) && !(select.GroupBy.Count == 0 && this.aggregateChecker.HasAggregates(c.Expression)); if (safeToRemove) { select.Row.Columns.RemoveAt(i); } else { this.VisitExpression(c.Expression); } } select.Top = this.VisitExpression(select.Top); for (int i = select.OrderBy.Count - 1; i >= 0; i--) { select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression); } select.Having = this.VisitExpression(select.Having); for (int i = select.GroupBy.Count - 1; i >= 0; i--) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } select.Where = this.VisitExpression(select.Where); select.From = this.VisitSource(select.From); } finally { this.isTopLevel = saveIsTopLevel; this.forceReferenceAll = saveForceReferenceAll; } return select; } internal override SqlSource VisitJoin(SqlJoin join) { join.Condition = this.VisitExpression(join.Condition); join.Right = this.VisitSource(join.Right); join.Left = this.VisitSource(join.Left); return join; } internal override SqlNode VisitLink(SqlLink link) { // don't visit expansion... for (int i = 0, n = link.KeyExpressions.Count; i < n; i++) { link.KeyExpressions[i] = this.VisitExpression(link.KeyExpressions[i]); } return link; } } class SqlColumnEqualizer : SqlVisitor { Dictionary map; internal SqlColumnEqualizer() { } internal void BuildEqivalenceMap(SqlSource scope) { this.map = new Dictionary (); this.Visit(scope); } internal bool AreEquivalent(SqlExpression e1, SqlExpression e2) { if (SqlComparer.AreEqual(e1, e2)) return true; SqlColumnRef cr1 = e1 as SqlColumnRef; SqlColumnRef cr2 = e2 as SqlColumnRef; if (cr1 != null && cr2 != null) { SqlColumn c1 = cr1.GetRootColumn(); SqlColumn c2 = cr2.GetRootColumn(); SqlColumn r; return this.map.TryGetValue(c1, out r) && r == c2; } return false; } internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(join); if (join.Condition != null) { this.CheckJoinCondition(join.Condition); } return join; } internal override SqlSelect VisitSelect(SqlSelect select) { base.VisitSelect(select); if (select.Where != null) { this.CheckJoinCondition(select.Where); } return select; } [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification="[....]: Cast is dependent on node type and casts do not happen unecessarily in a single code path.")] private void CheckJoinCondition(SqlExpression expr) { switch (expr.NodeType) { case SqlNodeType.And: { SqlBinary b = (SqlBinary)expr; CheckJoinCondition(b.Left); CheckJoinCondition(b.Right); break; } case SqlNodeType.EQ: case SqlNodeType.EQ2V: { SqlBinary b = (SqlBinary)expr; SqlColumnRef crLeft = b.Left as SqlColumnRef; SqlColumnRef crRight = b.Right as SqlColumnRef; if (crLeft != null && crRight != null) { SqlColumn cLeft = crLeft.GetRootColumn(); SqlColumn cRight = crRight.GetRootColumn(); this.map[cLeft] = cRight; this.map[cRight] = cLeft; } break; } } } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return ss; } } // remove redundant/trivial aliases class SqlAliasDeflator : SqlVisitor { Dictionary removedMap; internal SqlAliasDeflator() { this.removedMap = new Dictionary (); } internal override SqlExpression VisitAliasRef(SqlAliasRef aref) { SqlAlias alias = aref.Alias; SqlAlias value; if (this.removedMap.TryGetValue(alias, out value)) { throw Error.InvalidReferenceToRemovedAliasDuringDeflation(); } return aref; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { if (cref.Column.Alias != null && this.removedMap.ContainsKey(cref.Column.Alias)) { SqlColumnRef c = cref.Column.Expression as SqlColumnRef; if (c != null) { //The following code checks for cases where there are differences between the type returned //by a ColumnRef and the column that refers to it. This situation can occur when conversions //are optimized out of the SQL node tree. As mentioned in the SetClrType comments this is not //an operation that can have adverse effects and should only be used in limited cases, such as //this one. if (c.ClrType != cref.ClrType) { c.SetClrType(cref.ClrType); return this.VisitColumnRef(c); } } return c; } return cref; } internal override SqlSource VisitSource(SqlSource node) { node = (SqlSource)this.Visit(node); SqlAlias alias = node as SqlAlias; if (alias != null) { SqlSelect sel = alias.Node as SqlSelect; if (sel != null && this.IsTrivialSelect(sel)) { this.removedMap[alias] = alias; node = sel.From; } } return node; } internal override SqlSource VisitJoin(SqlJoin join) { base.VisitJoin(join); switch (join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.Inner: // reducing either side would effect cardinality of results break; case SqlJoinType.LeftOuter: case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: // may reduce to left if no references to the right if (this.HasEmptySource(join.Right)) { SqlAlias a = (SqlAlias)join.Right; this.removedMap[a] = a; return join.Left; } break; } return join; } private bool IsTrivialSelect(SqlSelect select) { if (select.OrderBy.Count != 0 || select.GroupBy.Count != 0 || select.Having != null || select.Top != null || select.IsDistinct || select.Where != null) return false; return this.HasTrivialSource(select.From) && this.HasTrivialProjection(select); } private bool HasTrivialSource(SqlSource node) { SqlJoin join = node as SqlJoin; if (join != null) { return this.HasTrivialSource(join.Left) && this.HasTrivialSource(join.Right); } return node is SqlAlias; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialProjection(SqlSelect select) { foreach (SqlColumn c in select.Row.Columns) { if (c.Expression != null && c.Expression.NodeType != SqlNodeType.ColumnRef) { return false; } } return true; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasEmptySource(SqlSource node) { SqlAlias alias = node as SqlAlias; if (alias == null) return false; SqlSelect sel = alias.Node as SqlSelect; if (sel == null) return false; return sel.Row.Columns.Count == 0 && sel.From == null && sel.Where == null && sel.GroupBy.Count == 0 && sel.Having == null && sel.OrderBy.Count == 0; } } // remove duplicate columns from order by and group by lists class SqlDuplicateColumnDeflator : SqlVisitor { SqlColumnEqualizer equalizer = new SqlColumnEqualizer(); internal override SqlSelect VisitSelect(SqlSelect select) { select.From = this.VisitSource(select.From); select.Where = this.VisitExpression(select.Where); for (int i = 0, n = select.GroupBy.Count; i < n; i++) { select.GroupBy[i] = this.VisitExpression(select.GroupBy[i]); } // remove duplicate group expressions for (int i = select.GroupBy.Count - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { if (SqlComparer.AreEqual(select.GroupBy[i], select.GroupBy[j])) { select.GroupBy.RemoveAt(i); break; } } } select.Having = this.VisitExpression(select.Having); for (int i = 0, n = select.OrderBy.Count; i < n; i++) { select.OrderBy[i].Expression = this.VisitExpression(select.OrderBy[i].Expression); } // remove duplicate order expressions if (select.OrderBy.Count > 0) { this.equalizer.BuildEqivalenceMap(select.From); for (int i = select.OrderBy.Count - 1; i >= 0; i--) { for (int j = i - 1; j >= 0; j--) { if (this.equalizer.AreEquivalent(select.OrderBy[i].Expression, select.OrderBy[j].Expression)) { select.OrderBy.RemoveAt(i); break; } } } } select.Top = this.VisitExpression(select.Top); select.Row = (SqlRow)this.Visit(select.Row); select.Selection = this.VisitExpression(select.Selection); return select; } } // if the top level select is simply a reprojection of the subquery, then remove it, // pushing any distinct names down class SqlTopSelectDeflator : SqlVisitor { internal override SqlSelect VisitSelect(SqlSelect select) { if (IsTrivialSelect(select)) { SqlSelect aselect = (SqlSelect)((SqlAlias)select.From).Node; // build up a column map, so we can rewrite the top-level selection expression Dictionary map = new Dictionary (); foreach (SqlColumn c in select.Row.Columns) { SqlColumnRef cref = (SqlColumnRef)c.Expression; map.Add(c, cref); // push the interesting column names down (non null) if (!string.IsNullOrEmpty(c.Name)) { cref.Column.Name = c.Name; } } aselect.Selection = new ColumnMapper(map).VisitExpression(select.Selection); return aselect; } return select; } private bool IsTrivialSelect(SqlSelect select) { if (select.OrderBy.Count != 0 || select.GroupBy.Count != 0 || select.Having != null || select.Top != null || select.IsDistinct || select.Where != null) return false; return this.HasTrivialSource(select.From) && this.HasTrivialProjection(select); } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialSource(SqlSource node) { SqlAlias alias = node as SqlAlias; if (alias == null) return false; return alias.Node is SqlSelect; } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private bool HasTrivialProjection(SqlSelect select) { foreach (SqlColumn c in select.Row.Columns) { if (c.Expression != null && c.Expression.NodeType != SqlNodeType.ColumnRef) { return false; } } return true; } class ColumnMapper : SqlVisitor { Dictionary map; internal ColumnMapper(Dictionary map) { this.map = map; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumnRef mapped; if (this.map.TryGetValue(cref.Column, out mapped)) { return mapped; } return cref; } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- DiscoveryClientProtocol.cs
- WindowsGrip.cs
- Char.cs
- NamespaceCollection.cs
- DataSysAttribute.cs
- RenderData.cs
- SessionStateSection.cs
- _NegoStream.cs
- UInt16.cs
- BitmapCodecInfo.cs
- HtmlValidatorAdapter.cs
- StateInitialization.cs
- CodeIndexerExpression.cs
- WhitespaceSignificantCollectionAttribute.cs
- ResourcesGenerator.cs
- KeyNotFoundException.cs
- _ServiceNameStore.cs
- DataGridViewImageColumn.cs
- NCryptSafeHandles.cs
- MetadataItemEmitter.cs
- PrintingPermissionAttribute.cs
- RegexBoyerMoore.cs
- TemplateBindingExtension.cs
- WebPartConnectionsCloseVerb.cs
- Int32.cs
- SafeLocalMemHandle.cs
- DataGridViewRowStateChangedEventArgs.cs
- DelayedRegex.cs
- ProxyWebPartManagerDesigner.cs
- HtmlEncodedRawTextWriter.cs
- BrowserDefinitionCollection.cs
- ComponentResourceKeyConverter.cs
- ConditionedDesigner.cs
- _LocalDataStoreMgr.cs
- AspProxy.cs
- DataColumn.cs
- PartitionerQueryOperator.cs
- JsonClassDataContract.cs
- SatelliteContractVersionAttribute.cs
- GrammarBuilderRuleRef.cs
- SoapReflector.cs
- HttpDebugHandler.cs
- SafeBuffer.cs
- WebPartManagerDesigner.cs
- CompletionBookmark.cs
- ClientProxyGenerator.cs
- PrintPreviewControl.cs
- DesignerTransactionCloseEvent.cs
- HitTestParameters3D.cs
- DataGridCheckBoxColumn.cs
- EmptyEnumerator.cs
- _DigestClient.cs
- ToolTip.cs
- Int32Converter.cs
- AttachedPropertiesService.cs
- PageTheme.cs
- SymmetricKey.cs
- MulticastDelegate.cs
- CodeGenerator.cs
- newinstructionaction.cs
- Point3DKeyFrameCollection.cs
- WindowsSolidBrush.cs
- TrackBar.cs
- _DigestClient.cs
- FixedPage.cs
- CleanUpVirtualizedItemEventArgs.cs
- WebOperationContext.cs
- HotSpot.cs
- UnrecognizedAssertionsBindingElement.cs
- NamespaceEmitter.cs
- EncodingNLS.cs
- CodeParameterDeclarationExpressionCollection.cs
- SamlDelegatingWriter.cs
- ConfigurationManagerInternal.cs
- MarkupObject.cs
- MediaContextNotificationWindow.cs
- BitmapEffectRenderDataResource.cs
- XmlQueryContext.cs
- MenuDesigner.cs
- TokenizerHelper.cs
- MediaEntryAttribute.cs
- Cursors.cs
- handlecollector.cs
- ItemDragEvent.cs
- TabControl.cs
- MatrixValueSerializer.cs
- SqlTypesSchemaImporter.cs
- IntranetCredentialPolicy.cs
- StateElement.cs
- BroadcastEventHelper.cs
- ClientConfigurationSystem.cs
- CapabilitiesPattern.cs
- AuthenticateEventArgs.cs
- ListItemCollection.cs
- HealthMonitoringSection.cs
- PassportIdentity.cs
- NativeCppClassAttribute.cs
- UserUseLicenseDictionaryLoader.cs
- WindowsAuthenticationModule.cs
- DeviceSpecificDialogCachedState.cs