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
- StdValidatorsAndConverters.cs
- RequestQueue.cs
- HttpWebResponse.cs
- D3DImage.cs
- StandardCommands.cs
- GridViewRowPresenter.cs
- XmlSignatureManifest.cs
- DbgCompiler.cs
- Error.cs
- TableDetailsRow.cs
- EngineSiteSapi.cs
- TextMetrics.cs
- CoTaskMemHandle.cs
- FontInfo.cs
- xsdvalidator.cs
- SpotLight.cs
- Transactions.cs
- PrefixHandle.cs
- errorpatternmatcher.cs
- IssuanceLicense.cs
- NumberFormatInfo.cs
- WebChannelFactory.cs
- ObjectItemCollection.cs
- GridEntryCollection.cs
- DeclarationUpdate.cs
- SerializationInfo.cs
- connectionpool.cs
- CodeTypeMember.cs
- WebPartMenu.cs
- EncryptedPackageFilter.cs
- Size3D.cs
- baseshape.cs
- AddInAdapter.cs
- LeafCellTreeNode.cs
- MissingSatelliteAssemblyException.cs
- CellRelation.cs
- FormatException.cs
- DesignerAutoFormat.cs
- WinInetCache.cs
- DictionaryEntry.cs
- StringComparer.cs
- SchemaNames.cs
- MarkerProperties.cs
- ActiveXContainer.cs
- DataTemplate.cs
- SafeRightsManagementSessionHandle.cs
- IPEndPointCollection.cs
- XamlWriter.cs
- MethodSignatureGenerator.cs
- HttpConfigurationSystem.cs
- BindingList.cs
- HelpEvent.cs
- MultitargetingHelpers.cs
- ConstantSlot.cs
- EmptyReadOnlyDictionaryInternal.cs
- CapabilitiesSection.cs
- Pair.cs
- dsa.cs
- InternalConfigRoot.cs
- TreeViewEvent.cs
- EncoderParameter.cs
- Icon.cs
- UnsafeNativeMethodsTablet.cs
- HttpCacheVary.cs
- ReflectPropertyDescriptor.cs
- ToolStripDropTargetManager.cs
- EntitySqlQueryState.cs
- UniformGrid.cs
- SolidColorBrush.cs
- SBCSCodePageEncoding.cs
- MarkupCompilePass1.cs
- DispatchWrapper.cs
- TableLayoutCellPaintEventArgs.cs
- SectionXmlInfo.cs
- UrlPath.cs
- ServiceContractViewControl.Designer.cs
- XNodeValidator.cs
- WebPartCatalogAddVerb.cs
- FrameworkPropertyMetadata.cs
- ModelTreeEnumerator.cs
- Or.cs
- XpsSerializationException.cs
- GeneralTransform3DTo2DTo3D.cs
- RawStylusInputCustomData.cs
- BoolExpression.cs
- ResolvedKeyFrameEntry.cs
- GridItemProviderWrapper.cs
- ListViewItem.cs
- TriState.cs
- DefaultSection.cs
- BindingMAnagerBase.cs
- StackOverflowException.cs
- WebHttpEndpoint.cs
- HostProtectionPermission.cs
- HyperLinkStyle.cs
- TreeNodeBinding.cs
- IncomingWebResponseContext.cs
- RegularExpressionValidator.cs
- XmlQueryRuntime.cs
- CodeBinaryOperatorExpression.cs