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
- _CookieModule.cs
- PeerNameRecord.cs
- DoubleCollectionConverter.cs
- SQLGuidStorage.cs
- PropertyDescriptorGridEntry.cs
- ByteRangeDownloader.cs
- SecurityVerifiedMessage.cs
- SystemWebSectionGroup.cs
- DataGridViewCellValueEventArgs.cs
- BitmapEffectRenderDataResource.cs
- RayHitTestParameters.cs
- ValuePattern.cs
- BitArray.cs
- connectionpool.cs
- TextServicesCompartmentContext.cs
- DataSpaceManager.cs
- TextEditorSpelling.cs
- ListManagerBindingsCollection.cs
- RemotingConfigParser.cs
- MobileControl.cs
- ParserStreamGeometryContext.cs
- ListChangedEventArgs.cs
- DataFormats.cs
- Focus.cs
- ListDataHelper.cs
- StrongNameMembershipCondition.cs
- CacheChildrenQuery.cs
- ToolStripManager.cs
- Brush.cs
- IssuanceLicense.cs
- RetrieveVirtualItemEventArgs.cs
- DeclaredTypeValidatorAttribute.cs
- ReaderWriterLockSlim.cs
- DiscoveryDocumentReference.cs
- ArrowControl.xaml.cs
- SystemMulticastIPAddressInformation.cs
- RemotingSurrogateSelector.cs
- WsrmTraceRecord.cs
- Validator.cs
- CssClassPropertyAttribute.cs
- ViewGenerator.cs
- SqlConnectionFactory.cs
- ToolboxBitmapAttribute.cs
- PanelStyle.cs
- Int32CollectionConverter.cs
- EventsTab.cs
- VideoDrawing.cs
- Environment.cs
- NetworkInformationPermission.cs
- SrgsToken.cs
- SqlTypeSystemProvider.cs
- ElementAction.cs
- AVElementHelper.cs
- LoginName.cs
- ComboBoxItem.cs
- DateTimeOffset.cs
- PageCatalogPart.cs
- SerializableAttribute.cs
- TreeView.cs
- AutomationPattern.cs
- DiscoveryVersionConverter.cs
- EventLog.cs
- CodeSubDirectoriesCollection.cs
- TimeManager.cs
- SecurityUtils.cs
- CopyAttributesAction.cs
- DesignBindingEditor.cs
- Random.cs
- ActivityInstanceReference.cs
- SerializationInfo.cs
- TemplateBindingExpressionConverter.cs
- Keyboard.cs
- DataGridViewCheckBoxCell.cs
- ListenerSingletonConnectionReader.cs
- Base64Encoder.cs
- SymbolDocumentGenerator.cs
- ObjectViewEntityCollectionData.cs
- StrokeNodeOperations.cs
- DatasetMethodGenerator.cs
- ExpressionVisitor.cs
- DBAsyncResult.cs
- CookieProtection.cs
- ImagingCache.cs
- SiteMapNodeItem.cs
- DefaultMemberAttribute.cs
- WebPartHeaderCloseVerb.cs
- NamespaceList.cs
- ResourcesChangeInfo.cs
- SapiInterop.cs
- SecureUICommand.cs
- X509ChainElement.cs
- DataGridPagerStyle.cs
- WorkflowMessageEventArgs.cs
- CodeNamespaceImportCollection.cs
- XmlSchemaGroup.cs
- ParallelQuery.cs
- TransformGroup.cs
- ConfigurationStrings.cs
- Cursors.cs
- XamlTypeWithExplicitNamespace.cs