Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- ControlDesignerState.cs
- ConditionalBranch.cs
- RestHandler.cs
- XsltFunctions.cs
- HostSecurityManager.cs
- DbConnectionPoolCounters.cs
- GridViewHeaderRowPresenter.cs
- SqlNode.cs
- ListView.cs
- SQLBytesStorage.cs
- WeakRefEnumerator.cs
- TemplateControl.cs
- RadioButton.cs
- SQLBytesStorage.cs
- FindCriteria11.cs
- DodSequenceMerge.cs
- SmtpFailedRecipientException.cs
- ResourceExpressionEditorSheet.cs
- SqlWriter.cs
- WebResponse.cs
- UnsafeNativeMethods.cs
- XmlValidatingReaderImpl.cs
- Stylus.cs
- GeneralTransform3DTo2D.cs
- TabItem.cs
- CodeConstructor.cs
- FrameworkElementAutomationPeer.cs
- DataTableCollection.cs
- EntitySetBase.cs
- ProfilePropertyMetadata.cs
- RangeEnumerable.cs
- NewArrayExpression.cs
- ImageMap.cs
- SwitchElementsCollection.cs
- ThreadAbortException.cs
- WebFaultException.cs
- PrintEvent.cs
- SQLBytesStorage.cs
- ApplicationFileParser.cs
- TextRangeEditTables.cs
- TransformPatternIdentifiers.cs
- ListItemParagraph.cs
- SafeProcessHandle.cs
- EncryptedXml.cs
- InteropBitmapSource.cs
- AtomicFile.cs
- ClientRolePrincipal.cs
- AccessibleObject.cs
- Roles.cs
- TypeConverterHelper.cs
- DownloadProgressEventArgs.cs
- MemberDomainMap.cs
- XmlCharCheckingWriter.cs
- InternalCache.cs
- ToolBarPanel.cs
- Matrix3DConverter.cs
- WindowsIdentity.cs
- XmlChoiceIdentifierAttribute.cs
- InvalidOperationException.cs
- BamlWriter.cs
- Psha1DerivedKeyGenerator.cs
- SchemaTableOptionalColumn.cs
- VisualStateManager.cs
- ContentFileHelper.cs
- ApplicationDirectoryMembershipCondition.cs
- ReadOnlyDataSource.cs
- ButtonPopupAdapter.cs
- TreeViewBindingsEditor.cs
- UseLicense.cs
- HttpHandler.cs
- SettingsPropertyValueCollection.cs
- SafeArrayTypeMismatchException.cs
- InstanceDataCollectionCollection.cs
- XPathDocumentNavigator.cs
- HandlerBase.cs
- EntityDescriptor.cs
- StylusButtonCollection.cs
- SecureUICommand.cs
- TypeInfo.cs
- SiteIdentityPermission.cs
- ExtenderControl.cs
- WebPartConnectionCollection.cs
- CodeValidator.cs
- ZipPackage.cs
- UITypeEditors.cs
- PassportIdentity.cs
- JsonUriDataContract.cs
- DataTableNewRowEvent.cs
- DetailsViewRow.cs
- Hash.cs
- NavigationProperty.cs
- ImageCollectionEditor.cs
- DBBindings.cs
- LinqDataSourceContextData.cs
- EntityContainerEmitter.cs
- LinkedResource.cs
- Rect.cs
- Point3DAnimation.cs
- CustomUserNameSecurityTokenAuthenticator.cs
- QualifiedId.cs