Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlResolver.cs / 1 / SqlResolver.cs
using System; using System.Collections.Generic; using System.Data.Linq; namespace System.Data.Linq.SqlClient { // Resolves references to columns/expressions defined in other scopes internal class SqlResolver { Visitor visitor; internal SqlResolver() { this.visitor = new Visitor(); } internal SqlNode Resolve(SqlNode node) { return this.visitor.Visit(node); } private static string GetColumnName(SqlColumn c) { #if DEBUG return c.Text; #else return c.Name; #endif } class Visitor : SqlScopedVisitor { SqlBubbler bubbler; internal Visitor() { this.bubbler = new SqlBubbler(); } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumnRef result = this.BubbleUp(cref); if (result == null) { throw Error.ColumnReferencedIsNotInScope(GetColumnName(cref.Column)); } return result; } private SqlColumnRef BubbleUp(SqlColumnRef cref) { for (Scope s = this.CurrentScope; s != null; s = s.ContainingScope) { if (s.Source != null) { SqlColumn found = this.bubbler.BubbleUp(cref.Column, s.Source); if (found != null) { if (found != cref.Column) return new SqlColumnRef(found); return cref; } } } return null; } } internal class SqlScopedVisitor : SqlVisitor { internal Scope CurrentScope; internal class Scope { SqlNode source; Scope containing; internal Scope(SqlNode source, Scope containing) { this.source = source; this.containing = containing; } internal SqlNode Source { get { return this.source; } } internal Scope ContainingScope { get { return this.containing; } } } internal SqlScopedVisitor() { this.CurrentScope = new Scope(null, null); } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(null, this.CurrentScope); base.VisitSubSelect(ss); this.CurrentScope = save; return ss; } internal override SqlSelect VisitSelect(SqlSelect select) { select.From = (SqlSource)this.Visit(select.From); Scope save = this.CurrentScope; this.CurrentScope = new Scope(select.From, this.CurrentScope.ContainingScope); 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]); } 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); } select.Top = this.VisitExpression(select.Top); select.Row = (SqlRow)this.Visit(select.Row); // selection must be able to see its own projection this.CurrentScope = new Scope(select, this.CurrentScope.ContainingScope); select.Selection = this.VisitExpression(select.Selection); this.CurrentScope = save; return select; } internal override SqlStatement VisitInsert(SqlInsert sin) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sin, this.CurrentScope.ContainingScope); base.VisitInsert(sin); this.CurrentScope = save; return sin; } internal override SqlStatement VisitUpdate(SqlUpdate sup) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sup.Select, this.CurrentScope.ContainingScope); base.VisitUpdate(sup); this.CurrentScope = save; return sup; } internal override SqlStatement VisitDelete(SqlDelete sd) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sd, this.CurrentScope.ContainingScope); base.VisitDelete(sd); this.CurrentScope = save; return sd; } internal override SqlSource VisitJoin(SqlJoin join) { Scope save = this.CurrentScope; switch (join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); Scope tmp = new Scope(join.Left, this.CurrentScope.ContainingScope); this.CurrentScope = new Scope(null, tmp); this.Visit(join.Right); Scope tmp2 = new Scope(join.Right, tmp); this.CurrentScope = new Scope(null, tmp2); this.Visit(join.Condition); break; } default: { this.Visit(join.Left); this.Visit(join.Right); this.CurrentScope = new Scope(null, new Scope(join.Right, new Scope(join.Left, this.CurrentScope.ContainingScope))); this.Visit(join.Condition); break; } } this.CurrentScope = save; return join; } } // finds location of expression definition and re-projects that value all the // way to the outermost projection internal class SqlBubbler : SqlVisitor { SqlColumn match; SqlColumn found; internal SqlBubbler() { } internal SqlColumn BubbleUp(SqlColumn col, SqlNode source) { this.match = this.GetOriginatingColumn(col); this.found = null; this.Visit(source); return this.found; } internal SqlColumn GetOriginatingColumn(SqlColumn col) { SqlColumnRef cref = col.Expression as SqlColumnRef; if (cref != null) { return this.GetOriginatingColumn(cref.Column); } return col; } internal override SqlRow VisitRow(SqlRow row) { foreach (SqlColumn c in row.Columns) { if (this.RefersToColumn(c, this.match)) { if (this.found != null) { throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); } this.found = c; break; } } return row; } internal override SqlTable VisitTable(SqlTable tab) { foreach (SqlColumn c in tab.Columns) { if (c == this.match) { if (this.found != null) throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); this.found = c; break; } } return tab; } internal override SqlSource VisitJoin(SqlJoin join) { switch (join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); if (this.found == null) { this.Visit(join.Right); } break; } default: { this.Visit(join.Left); this.Visit(join.Right); break; } } return join; } internal override SqlExpression VisitTableValuedFunctionCall(SqlTableValuedFunctionCall fc) { foreach (SqlColumn c in fc.Columns) { if (c == this.match) { if (this.found != null) throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); this.found = c; break; } } return fc; } private void ForceLocal(SqlRow row, string name) { bool isLocal = false; // check to see if it already exists locally foreach (SqlColumn c in row.Columns) { if (this.RefersToColumn(c, this.found)) { this.found = c; isLocal = true; break; } } if (!isLocal) { // need to put this in the local projection list to bubble it up SqlColumn c = new SqlColumn(found.ClrType, found.SqlType, name, this.found.MetaMember, new SqlColumnRef(this.found), row.SourceExpression); row.Columns.Add(c); this.found = c; } } private bool IsFoundInGroup(SqlSelect select) { // does the column happen to be listed in the group-by clause? foreach (SqlExpression exp in select.GroupBy) { if (this.RefersToColumn(exp, this.found) || this.RefersToColumn(exp, this.match)) { return true; } } return false; } internal override SqlSelect VisitSelect(SqlSelect select) { // look in this projection this.Visit(select.Row); if (this.found == null) { // look in upstream projections this.Visit(select.From); // bubble it up if (this.found != null) { if (select.IsDistinct && !match.IsConstantColumn) { throw Error.ColumnIsNotAccessibleThroughDistinct(GetColumnName(this.match)); } if (select.GroupBy.Count == 0 || this.IsFoundInGroup(select)) { this.ForceLocal(select.Row, this.found.Name); } else { // found it, but its hidden behind the group-by throw Error.ColumnIsNotAccessibleThroughGroupBy(GetColumnName(this.match)); } } } return select; } } } } // 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.Data.Linq; namespace System.Data.Linq.SqlClient { // Resolves references to columns/expressions defined in other scopes internal class SqlResolver { Visitor visitor; internal SqlResolver() { this.visitor = new Visitor(); } internal SqlNode Resolve(SqlNode node) { return this.visitor.Visit(node); } private static string GetColumnName(SqlColumn c) { #if DEBUG return c.Text; #else return c.Name; #endif } class Visitor : SqlScopedVisitor { SqlBubbler bubbler; internal Visitor() { this.bubbler = new SqlBubbler(); } internal override SqlExpression VisitColumnRef(SqlColumnRef cref) { SqlColumnRef result = this.BubbleUp(cref); if (result == null) { throw Error.ColumnReferencedIsNotInScope(GetColumnName(cref.Column)); } return result; } private SqlColumnRef BubbleUp(SqlColumnRef cref) { for (Scope s = this.CurrentScope; s != null; s = s.ContainingScope) { if (s.Source != null) { SqlColumn found = this.bubbler.BubbleUp(cref.Column, s.Source); if (found != null) { if (found != cref.Column) return new SqlColumnRef(found); return cref; } } } return null; } } internal class SqlScopedVisitor : SqlVisitor { internal Scope CurrentScope; internal class Scope { SqlNode source; Scope containing; internal Scope(SqlNode source, Scope containing) { this.source = source; this.containing = containing; } internal SqlNode Source { get { return this.source; } } internal Scope ContainingScope { get { return this.containing; } } } internal SqlScopedVisitor() { this.CurrentScope = new Scope(null, null); } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(null, this.CurrentScope); base.VisitSubSelect(ss); this.CurrentScope = save; return ss; } internal override SqlSelect VisitSelect(SqlSelect select) { select.From = (SqlSource)this.Visit(select.From); Scope save = this.CurrentScope; this.CurrentScope = new Scope(select.From, this.CurrentScope.ContainingScope); 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]); } 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); } select.Top = this.VisitExpression(select.Top); select.Row = (SqlRow)this.Visit(select.Row); // selection must be able to see its own projection this.CurrentScope = new Scope(select, this.CurrentScope.ContainingScope); select.Selection = this.VisitExpression(select.Selection); this.CurrentScope = save; return select; } internal override SqlStatement VisitInsert(SqlInsert sin) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sin, this.CurrentScope.ContainingScope); base.VisitInsert(sin); this.CurrentScope = save; return sin; } internal override SqlStatement VisitUpdate(SqlUpdate sup) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sup.Select, this.CurrentScope.ContainingScope); base.VisitUpdate(sup); this.CurrentScope = save; return sup; } internal override SqlStatement VisitDelete(SqlDelete sd) { Scope save = this.CurrentScope; this.CurrentScope = new Scope(sd, this.CurrentScope.ContainingScope); base.VisitDelete(sd); this.CurrentScope = save; return sd; } internal override SqlSource VisitJoin(SqlJoin join) { Scope save = this.CurrentScope; switch (join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); Scope tmp = new Scope(join.Left, this.CurrentScope.ContainingScope); this.CurrentScope = new Scope(null, tmp); this.Visit(join.Right); Scope tmp2 = new Scope(join.Right, tmp); this.CurrentScope = new Scope(null, tmp2); this.Visit(join.Condition); break; } default: { this.Visit(join.Left); this.Visit(join.Right); this.CurrentScope = new Scope(null, new Scope(join.Right, new Scope(join.Left, this.CurrentScope.ContainingScope))); this.Visit(join.Condition); break; } } this.CurrentScope = save; return join; } } // finds location of expression definition and re-projects that value all the // way to the outermost projection internal class SqlBubbler : SqlVisitor { SqlColumn match; SqlColumn found; internal SqlBubbler() { } internal SqlColumn BubbleUp(SqlColumn col, SqlNode source) { this.match = this.GetOriginatingColumn(col); this.found = null; this.Visit(source); return this.found; } internal SqlColumn GetOriginatingColumn(SqlColumn col) { SqlColumnRef cref = col.Expression as SqlColumnRef; if (cref != null) { return this.GetOriginatingColumn(cref.Column); } return col; } internal override SqlRow VisitRow(SqlRow row) { foreach (SqlColumn c in row.Columns) { if (this.RefersToColumn(c, this.match)) { if (this.found != null) { throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); } this.found = c; break; } } return row; } internal override SqlTable VisitTable(SqlTable tab) { foreach (SqlColumn c in tab.Columns) { if (c == this.match) { if (this.found != null) throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); this.found = c; break; } } return tab; } internal override SqlSource VisitJoin(SqlJoin join) { switch (join.JoinType) { case SqlJoinType.CrossApply: case SqlJoinType.OuterApply: { this.Visit(join.Left); if (this.found == null) { this.Visit(join.Right); } break; } default: { this.Visit(join.Left); this.Visit(join.Right); break; } } return join; } internal override SqlExpression VisitTableValuedFunctionCall(SqlTableValuedFunctionCall fc) { foreach (SqlColumn c in fc.Columns) { if (c == this.match) { if (this.found != null) throw Error.ColumnIsDefinedInMultiplePlaces(GetColumnName(this.match)); this.found = c; break; } } return fc; } private void ForceLocal(SqlRow row, string name) { bool isLocal = false; // check to see if it already exists locally foreach (SqlColumn c in row.Columns) { if (this.RefersToColumn(c, this.found)) { this.found = c; isLocal = true; break; } } if (!isLocal) { // need to put this in the local projection list to bubble it up SqlColumn c = new SqlColumn(found.ClrType, found.SqlType, name, this.found.MetaMember, new SqlColumnRef(this.found), row.SourceExpression); row.Columns.Add(c); this.found = c; } } private bool IsFoundInGroup(SqlSelect select) { // does the column happen to be listed in the group-by clause? foreach (SqlExpression exp in select.GroupBy) { if (this.RefersToColumn(exp, this.found) || this.RefersToColumn(exp, this.match)) { return true; } } return false; } internal override SqlSelect VisitSelect(SqlSelect select) { // look in this projection this.Visit(select.Row); if (this.found == null) { // look in upstream projections this.Visit(select.From); // bubble it up if (this.found != null) { if (select.IsDistinct && !match.IsConstantColumn) { throw Error.ColumnIsNotAccessibleThroughDistinct(GetColumnName(this.match)); } if (select.GroupBy.Count == 0 || this.IsFoundInGroup(select)) { this.ForceLocal(select.Row, this.found.Name); } else { // found it, but its hidden behind the group-by throw Error.ColumnIsNotAccessibleThroughGroupBy(GetColumnName(this.match)); } } } return select; } } } } // 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
- BuilderPropertyEntry.cs
- ControlTemplate.cs
- bindurihelper.cs
- HierarchicalDataSourceControl.cs
- SafeProcessHandle.cs
- BitmapCodecInfo.cs
- SystemPens.cs
- JsonGlobals.cs
- CryptoKeySecurity.cs
- OutputScopeManager.cs
- ListViewItemSelectionChangedEvent.cs
- CopyAttributesAction.cs
- PaperSource.cs
- DataTableNameHandler.cs
- XmlDesignerDataSourceView.cs
- SchemaType.cs
- CursorConverter.cs
- XmlAttributeCollection.cs
- HwndSourceParameters.cs
- SqlComparer.cs
- webbrowsersite.cs
- Point.cs
- Rijndael.cs
- CodeIdentifiers.cs
- SqlUnionizer.cs
- AsyncContentLoadedEventArgs.cs
- SupportsPreviewControlAttribute.cs
- SymLanguageVendor.cs
- HierarchicalDataSourceControl.cs
- AnnotationResourceChangedEventArgs.cs
- CachingHintValidation.cs
- ContractMapping.cs
- DataGridViewComboBoxColumn.cs
- Rotation3D.cs
- UMPAttributes.cs
- NativeWindow.cs
- SQLGuidStorage.cs
- NavigatingCancelEventArgs.cs
- SqlDataSourceTableQuery.cs
- BuildProvider.cs
- TreeView.cs
- followingquery.cs
- ToolBar.cs
- EventDrivenDesigner.cs
- PeerTransportSecuritySettings.cs
- CharacterBufferReference.cs
- SqlProcedureAttribute.cs
- AssemblyHash.cs
- FixedSchema.cs
- RecipientInfo.cs
- SafeFindHandle.cs
- CssClassPropertyAttribute.cs
- Constants.cs
- HashHelper.cs
- SystemIPInterfaceProperties.cs
- dataobject.cs
- FrameworkReadOnlyPropertyMetadata.cs
- CommandID.cs
- EntityDataSource.cs
- TransactionFlowBindingElementImporter.cs
- RC2.cs
- NullableDecimalAverageAggregationOperator.cs
- XmlBindingWorker.cs
- ImageCodecInfo.cs
- PrimitiveXmlSerializers.cs
- XslAst.cs
- FormsAuthenticationCredentials.cs
- CodeNamespaceCollection.cs
- PrintController.cs
- CookielessHelper.cs
- UserValidatedEventArgs.cs
- PermissionSet.cs
- DialogResultConverter.cs
- AVElementHelper.cs
- LassoHelper.cs
- DataObjectMethodAttribute.cs
- ConfigurationException.cs
- JournalEntryListConverter.cs
- ApplicationInfo.cs
- Stylus.cs
- CompilationRelaxations.cs
- ExpressionVisitorHelpers.cs
- ThicknessAnimation.cs
- RuntimeHandles.cs
- MasterPageBuildProvider.cs
- ManagementObjectSearcher.cs
- FormClosedEvent.cs
- RectAnimation.cs
- DesignerPerfEventProvider.cs
- ApplicationManager.cs
- DataGridViewRowCancelEventArgs.cs
- ObjectSpanRewriter.cs
- AdCreatedEventArgs.cs
- CodeCompiler.cs
- XmlSerializableServices.cs
- SqlPersonalizationProvider.cs
- URLAttribute.cs
- TransportSecurityProtocolFactory.cs
- MemberAccessException.cs
- SqlDataSourceQueryConverter.cs