Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlFlattener.cs / 1305376 / SqlFlattener.cs
using System; using System.Collections.Generic; namespace System.Data.Linq.SqlClient { using System.Data.Linq.Mapping; using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; // flatten object expressions into rows internal class SqlFlattener { Visitor visitor; internal SqlFlattener(SqlFactory sql, SqlColumnizer columnizer) { this.visitor = new Visitor(sql, columnizer); } internal SqlNode Flatten(SqlNode node) { node = this.visitor.Visit(node); return node; } class Visitor : SqlVisitor { [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "[....]: part of our standard visitor pattern")] SqlFactory sql; SqlColumnizer columnizer; bool isTopLevel; Dictionarymap = new Dictionary (); [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification="Unknown reason.")] internal Visitor(SqlFactory sql, SqlColumnizer columnizer) { this.sql = sql; this.columnizer = columnizer; this.isTopLevel = true; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumn mapped; if (this.map.TryGetValue(cref.Column, out mapped)) { return new SqlColumnRef(mapped); } return cref; } internal override SqlSelect VisitSelectCore(SqlSelect select) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; try { return base.VisitSelectCore(select); } finally { this.isTopLevel = saveIsTopLevel; } } internal override SqlSelect VisitSelect(SqlSelect select) { select = base.VisitSelect(select); select.Selection = this.FlattenSelection(select.Row, false, select.Selection); if (select.GroupBy.Count > 0) { this.FlattenGroupBy(select.GroupBy); } if (select.OrderBy.Count > 0) { this.FlattenOrderBy(select.OrderBy); } if (!this.isTopLevel) { select.Selection = new SqlNop(select.Selection.ClrType, select.Selection.SqlType, select.SourceExpression); } return select; } internal override SqlStatement VisitInsert(SqlInsert sin) { base.VisitInsert(sin); sin.Expression = this.FlattenSelection(sin.Row, true, sin.Expression); return sin; } private SqlExpression FlattenSelection(SqlRow row, bool isInput, SqlExpression selection) { selection = this.columnizer.ColumnizeSelection(selection); return new SelectionFlattener(row, this.map, isInput).VisitExpression(selection); } class SelectionFlattener : SqlVisitor { SqlRow row; Dictionary map; bool isInput; bool isNew; internal SelectionFlattener(SqlRow row, Dictionary map, bool isInput) { this.row = row; this.map = map; this.isInput = isInput; } internal override SqlExpression VisitNew(SqlNew sox) { this.isNew = true; return base.VisitNew(sox); } internal override SqlExpression VisitColumn(SqlColumn col) { SqlColumn c = this.FindColumn(this.row.Columns, col); if (c == null && col.Expression != null && !this.isInput && (!this.isNew || (this.isNew && !col.Expression.IsConstantColumn))) { c = this.FindColumnWithExpression(this.row.Columns, col.Expression); } if (c == null) { this.row.Columns.Add(col); c = col; } else if (c != col) { // preserve expr-sets when folding expressions together if (col.Expression.NodeType == SqlNodeType.ExprSet && c.Expression.NodeType != SqlNodeType.ExprSet) { c.Expression = col.Expression; } this.map[col] = c; } return new SqlColumnRef(c); } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumn c = this.FindColumn(this.row.Columns, cref.Column); if (c == null) { return MakeFlattenedColumn(cref, null); } else { return new SqlColumnRef(c); } } // ignore subquery in selection internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return ss; } internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { return cq; } private SqlColumnRef MakeFlattenedColumn(SqlExpression expr, string name) { SqlColumn c = (!this.isInput) ? this.FindColumnWithExpression(this.row.Columns, expr) : null; if (c == null) { c = new SqlColumn(expr.ClrType, expr.SqlType, name, null, expr, expr.SourceExpression); this.row.Columns.Add(c); } return new SqlColumnRef(c); } private SqlColumn FindColumn(IEnumerable columns, SqlColumn col) { foreach (SqlColumn c in columns) { if (this.RefersToColumn(c, col)) { return c; } } return null; } private SqlColumn FindColumnWithExpression(IEnumerable columns, SqlExpression expr) { foreach (SqlColumn c in columns) { if (c == expr) { return c; } if (SqlComparer.AreEqual(c.Expression, expr)) { return c; } } return null; } } private void FlattenGroupBy(List exprs) { List list = new List (exprs.Count); foreach (SqlExpression gex in exprs) { if (TypeSystem.IsSequenceType(gex.ClrType)) { throw Error.InvalidGroupByExpressionType(gex.ClrType.Name); } this.FlattenGroupByExpression(list, gex); } exprs.Clear(); exprs.AddRange(list); } private void FlattenGroupByExpression(List exprs, SqlExpression expr) { SqlNew sn = expr as SqlNew; if (sn != null) { foreach (SqlMemberAssign ma in sn.Members) { this.FlattenGroupByExpression(exprs, ma.Expression); } foreach (SqlExpression arg in sn.Args) { this.FlattenGroupByExpression(exprs, arg); } } else if (expr.NodeType == SqlNodeType.TypeCase) { SqlTypeCase tc = (SqlTypeCase)expr; this.FlattenGroupByExpression(exprs, tc.Discriminator); foreach (SqlTypeCaseWhen when in tc.Whens) { this.FlattenGroupByExpression(exprs, when.TypeBinding); } } else if (expr.NodeType == SqlNodeType.Link) { SqlLink link = (SqlLink)expr; if (link.Expansion != null) { this.FlattenGroupByExpression(exprs, link.Expansion); } else { foreach (SqlExpression key in link.KeyExpressions) { this.FlattenGroupByExpression(exprs, key); } } } else if (expr.NodeType == SqlNodeType.OptionalValue) { SqlOptionalValue sop = (SqlOptionalValue)expr; this.FlattenGroupByExpression(exprs, sop.HasValue); this.FlattenGroupByExpression(exprs, sop.Value); } else if (expr.NodeType == SqlNodeType.OuterJoinedValue) { this.FlattenGroupByExpression(exprs, ((SqlUnary)expr).Operand); } else if (expr.NodeType == SqlNodeType.DiscriminatedType) { SqlDiscriminatedType dt = (SqlDiscriminatedType)expr; this.FlattenGroupByExpression(exprs, dt.Discriminator); } else { // this expression should have been 'pushed-down' in SqlBinder, so we // should only find column-references & expr-sets unless the expression could not // be columnized (in which case it was a bad group-by expression.) if (expr.NodeType != SqlNodeType.ColumnRef && expr.NodeType != SqlNodeType.ExprSet) { if (!expr.SqlType.CanBeColumn) { throw Error.InvalidGroupByExpressionType(expr.SqlType.ToQueryString()); } throw Error.InvalidGroupByExpression(); } exprs.Add(expr); } } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private void FlattenOrderBy(List exprs) { foreach (SqlOrderExpression obex in exprs) { if (!obex.Expression.SqlType.IsOrderable) { if (obex.Expression.SqlType.CanBeColumn) { throw Error.InvalidOrderByExpression(obex.Expression.SqlType.ToQueryString()); } else { throw Error.InvalidOrderByExpression(obex.Expression.ClrType.Name); } } } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; namespace System.Data.Linq.SqlClient { using System.Data.Linq.Mapping; using System.Data.Linq.Provider; using System.Diagnostics.CodeAnalysis; // flatten object expressions into rows internal class SqlFlattener { Visitor visitor; internal SqlFlattener(SqlFactory sql, SqlColumnizer columnizer) { this.visitor = new Visitor(sql, columnizer); } internal SqlNode Flatten(SqlNode node) { node = this.visitor.Visit(node); return node; } class Visitor : SqlVisitor { [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields", Justification = "[....]: part of our standard visitor pattern")] SqlFactory sql; SqlColumnizer columnizer; bool isTopLevel; Dictionary map = new Dictionary (); [SuppressMessage("Microsoft.Performance", "CA1805:DoNotInitializeUnnecessarily", Justification="Unknown reason.")] internal Visitor(SqlFactory sql, SqlColumnizer columnizer) { this.sql = sql; this.columnizer = columnizer; this.isTopLevel = true; } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumn mapped; if (this.map.TryGetValue(cref.Column, out mapped)) { return new SqlColumnRef(mapped); } return cref; } internal override SqlSelect VisitSelectCore(SqlSelect select) { bool saveIsTopLevel = this.isTopLevel; this.isTopLevel = false; try { return base.VisitSelectCore(select); } finally { this.isTopLevel = saveIsTopLevel; } } internal override SqlSelect VisitSelect(SqlSelect select) { select = base.VisitSelect(select); select.Selection = this.FlattenSelection(select.Row, false, select.Selection); if (select.GroupBy.Count > 0) { this.FlattenGroupBy(select.GroupBy); } if (select.OrderBy.Count > 0) { this.FlattenOrderBy(select.OrderBy); } if (!this.isTopLevel) { select.Selection = new SqlNop(select.Selection.ClrType, select.Selection.SqlType, select.SourceExpression); } return select; } internal override SqlStatement VisitInsert(SqlInsert sin) { base.VisitInsert(sin); sin.Expression = this.FlattenSelection(sin.Row, true, sin.Expression); return sin; } private SqlExpression FlattenSelection(SqlRow row, bool isInput, SqlExpression selection) { selection = this.columnizer.ColumnizeSelection(selection); return new SelectionFlattener(row, this.map, isInput).VisitExpression(selection); } class SelectionFlattener : SqlVisitor { SqlRow row; Dictionary map; bool isInput; bool isNew; internal SelectionFlattener(SqlRow row, Dictionary map, bool isInput) { this.row = row; this.map = map; this.isInput = isInput; } internal override SqlExpression VisitNew(SqlNew sox) { this.isNew = true; return base.VisitNew(sox); } internal override SqlExpression VisitColumn(SqlColumn col) { SqlColumn c = this.FindColumn(this.row.Columns, col); if (c == null && col.Expression != null && !this.isInput && (!this.isNew || (this.isNew && !col.Expression.IsConstantColumn))) { c = this.FindColumnWithExpression(this.row.Columns, col.Expression); } if (c == null) { this.row.Columns.Add(col); c = col; } else if (c != col) { // preserve expr-sets when folding expressions together if (col.Expression.NodeType == SqlNodeType.ExprSet && c.Expression.NodeType != SqlNodeType.ExprSet) { c.Expression = col.Expression; } this.map[col] = c; } return new SqlColumnRef(c); } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumn c = this.FindColumn(this.row.Columns, cref.Column); if (c == null) { return MakeFlattenedColumn(cref, null); } else { return new SqlColumnRef(c); } } // ignore subquery in selection internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { return ss; } internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { return cq; } private SqlColumnRef MakeFlattenedColumn(SqlExpression expr, string name) { SqlColumn c = (!this.isInput) ? this.FindColumnWithExpression(this.row.Columns, expr) : null; if (c == null) { c = new SqlColumn(expr.ClrType, expr.SqlType, name, null, expr, expr.SourceExpression); this.row.Columns.Add(c); } return new SqlColumnRef(c); } private SqlColumn FindColumn(IEnumerable columns, SqlColumn col) { foreach (SqlColumn c in columns) { if (this.RefersToColumn(c, col)) { return c; } } return null; } private SqlColumn FindColumnWithExpression(IEnumerable columns, SqlExpression expr) { foreach (SqlColumn c in columns) { if (c == expr) { return c; } if (SqlComparer.AreEqual(c.Expression, expr)) { return c; } } return null; } } private void FlattenGroupBy(List exprs) { List list = new List (exprs.Count); foreach (SqlExpression gex in exprs) { if (TypeSystem.IsSequenceType(gex.ClrType)) { throw Error.InvalidGroupByExpressionType(gex.ClrType.Name); } this.FlattenGroupByExpression(list, gex); } exprs.Clear(); exprs.AddRange(list); } private void FlattenGroupByExpression(List exprs, SqlExpression expr) { SqlNew sn = expr as SqlNew; if (sn != null) { foreach (SqlMemberAssign ma in sn.Members) { this.FlattenGroupByExpression(exprs, ma.Expression); } foreach (SqlExpression arg in sn.Args) { this.FlattenGroupByExpression(exprs, arg); } } else if (expr.NodeType == SqlNodeType.TypeCase) { SqlTypeCase tc = (SqlTypeCase)expr; this.FlattenGroupByExpression(exprs, tc.Discriminator); foreach (SqlTypeCaseWhen when in tc.Whens) { this.FlattenGroupByExpression(exprs, when.TypeBinding); } } else if (expr.NodeType == SqlNodeType.Link) { SqlLink link = (SqlLink)expr; if (link.Expansion != null) { this.FlattenGroupByExpression(exprs, link.Expansion); } else { foreach (SqlExpression key in link.KeyExpressions) { this.FlattenGroupByExpression(exprs, key); } } } else if (expr.NodeType == SqlNodeType.OptionalValue) { SqlOptionalValue sop = (SqlOptionalValue)expr; this.FlattenGroupByExpression(exprs, sop.HasValue); this.FlattenGroupByExpression(exprs, sop.Value); } else if (expr.NodeType == SqlNodeType.OuterJoinedValue) { this.FlattenGroupByExpression(exprs, ((SqlUnary)expr).Operand); } else if (expr.NodeType == SqlNodeType.DiscriminatedType) { SqlDiscriminatedType dt = (SqlDiscriminatedType)expr; this.FlattenGroupByExpression(exprs, dt.Discriminator); } else { // this expression should have been 'pushed-down' in SqlBinder, so we // should only find column-references & expr-sets unless the expression could not // be columnized (in which case it was a bad group-by expression.) if (expr.NodeType != SqlNodeType.ColumnRef && expr.NodeType != SqlNodeType.ExprSet) { if (!expr.SqlType.CanBeColumn) { throw Error.InvalidGroupByExpressionType(expr.SqlType.ToQueryString()); } throw Error.InvalidGroupByExpression(); } exprs.Add(expr); } } [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification="Unknown reason.")] private void FlattenOrderBy(List exprs) { foreach (SqlOrderExpression obex in exprs) { if (!obex.Expression.SqlType.IsOrderable) { if (obex.Expression.SqlType.CanBeColumn) { throw Error.InvalidOrderByExpression(obex.Expression.SqlType.ToQueryString()); } else { throw Error.InvalidOrderByExpression(obex.Expression.ClrType.Name); } } } } } } } // 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](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PageCatalogPartDesigner.cs
- ErrorHandler.cs
- JsonCollectionDataContract.cs
- ExpressionLexer.cs
- PassportPrincipal.cs
- CompilationUnit.cs
- RewritingValidator.cs
- Vector.cs
- SqlFlattener.cs
- RegexParser.cs
- XmlNullResolver.cs
- JoinTreeSlot.cs
- PersonalizationProvider.cs
- PropertyEmitterBase.cs
- TableHeaderCell.cs
- KeyTime.cs
- VerticalAlignConverter.cs
- HttpBufferlessInputStream.cs
- ReferentialConstraint.cs
- AutoResetEvent.cs
- RTLAwareMessageBox.cs
- OracleRowUpdatingEventArgs.cs
- Encoder.cs
- InternalControlCollection.cs
- WebPartDescription.cs
- ArgumentException.cs
- UnsafeNativeMethods.cs
- CodeExpressionCollection.cs
- WebServiceMethodData.cs
- DateRangeEvent.cs
- BuildProvidersCompiler.cs
- SortFieldComparer.cs
- EnumType.cs
- StatusBarPanel.cs
- DefaultParameterValueAttribute.cs
- ZipIOExtraFieldPaddingElement.cs
- FormatterConverter.cs
- D3DImage.cs
- ApplicationFileParser.cs
- KoreanLunisolarCalendar.cs
- BinaryExpression.cs
- ArgumentReference.cs
- FontStretches.cs
- SizeKeyFrameCollection.cs
- CompoundFileIOPermission.cs
- XmlCountingReader.cs
- XamlToRtfWriter.cs
- CroppedBitmap.cs
- CheckPair.cs
- JoinCqlBlock.cs
- EventLogPermissionEntry.cs
- EntityContainerEmitter.cs
- WinOEToolBoxItem.cs
- DataExpression.cs
- Region.cs
- CallbackValidator.cs
- __ComObject.cs
- XmlArrayAttribute.cs
- ColorContext.cs
- Token.cs
- BackStopAuthenticationModule.cs
- ObjectToken.cs
- UrlMappingsModule.cs
- BooleanExpr.cs
- ProcessModelInfo.cs
- ParallelRangeManager.cs
- IsolationInterop.cs
- MembershipSection.cs
- xmlfixedPageInfo.cs
- SqlClientWrapperSmiStream.cs
- X509Utils.cs
- CharKeyFrameCollection.cs
- ReflectionServiceProvider.cs
- connectionpool.cs
- XmlReaderSettings.cs
- GridErrorDlg.cs
- PopupRootAutomationPeer.cs
- HostExecutionContextManager.cs
- DefaultTraceListener.cs
- EventLogPermission.cs
- FixedSOMTextRun.cs
- DataGridViewRowEventArgs.cs
- SystemTcpStatistics.cs
- CompensationDesigner.cs
- WebPartsSection.cs
- ProfileSettingsCollection.cs
- ToolStripMenuItem.cs
- storepermissionattribute.cs
- Missing.cs
- Graph.cs
- ScriptHandlerFactory.cs
- Accessible.cs
- xml.cs
- columnmapfactory.cs
- CommandEventArgs.cs
- MappingItemCollection.cs
- xmlfixedPageInfo.cs
- CalendarKeyboardHelper.cs
- PolyQuadraticBezierSegmentFigureLogic.cs
- GB18030Encoding.cs