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
- XmlAttributeOverrides.cs
- CrossContextChannel.cs
- ClientScriptItem.cs
- Deflater.cs
- ViewPort3D.cs
- XmlReaderSettings.cs
- Msec.cs
- HwndTarget.cs
- ExtenderControl.cs
- NotifyIcon.cs
- SqlProfileProvider.cs
- InternalConfigConfigurationFactory.cs
- InputLanguageManager.cs
- StorageRoot.cs
- StrokeCollection.cs
- BamlBinaryReader.cs
- XmlBoundElement.cs
- ScrollChrome.cs
- CalloutQueueItem.cs
- CriticalExceptions.cs
- QueryOutputWriterV1.cs
- MapPathBasedVirtualPathProvider.cs
- NamespaceInfo.cs
- StackSpiller.Generated.cs
- PenThreadPool.cs
- AppSettings.cs
- ControlCachePolicy.cs
- SqlProviderManifest.cs
- PointLight.cs
- Enum.cs
- SiteMapNodeItemEventArgs.cs
- ListViewItemSelectionChangedEvent.cs
- System.Data_BID.cs
- GrammarBuilderRuleRef.cs
- SizeKeyFrameCollection.cs
- WindowsImpersonationContext.cs
- CodeTypeMember.cs
- TreeNodeEventArgs.cs
- JsonReader.cs
- CalendarKeyboardHelper.cs
- ServiceModelExtensionCollectionElement.cs
- XmlNotation.cs
- PageClientProxyGenerator.cs
- SendMailErrorEventArgs.cs
- OleDbException.cs
- HtmlListAdapter.cs
- ReverseQueryOperator.cs
- ParserStack.cs
- SerializationSectionGroup.cs
- Tablet.cs
- SettingsBindableAttribute.cs
- LinqDataSourceInsertEventArgs.cs
- ValueQuery.cs
- FieldNameLookup.cs
- NamedPipeTransportSecurityElement.cs
- EventWaitHandleSecurity.cs
- ApplicationInfo.cs
- FileFormatException.cs
- StreamWithDictionary.cs
- AnnouncementDispatcherAsyncResult.cs
- Size3DConverter.cs
- Decoder.cs
- PageParserFilter.cs
- HebrewCalendar.cs
- TogglePatternIdentifiers.cs
- ScrollChrome.cs
- TimelineClockCollection.cs
- BinarySecretSecurityToken.cs
- UrlAuthorizationModule.cs
- configsystem.cs
- DynamicUpdateCommand.cs
- ControlLocalizer.cs
- LinearGradientBrush.cs
- HttpProfileGroupBase.cs
- WebServiceClientProxyGenerator.cs
- BaseDataList.cs
- ItemDragEvent.cs
- XmlMembersMapping.cs
- EncoderBestFitFallback.cs
- DocumentViewerBaseAutomationPeer.cs
- MultipleViewProviderWrapper.cs
- NonParentingControl.cs
- BlobPersonalizationState.cs
- ExportOptions.cs
- WindowsProgressbar.cs
- HostedHttpTransportManager.cs
- Point3DAnimationBase.cs
- ActivityXamlServices.cs
- XsltException.cs
- WorkflowTransactionOptions.cs
- AppSettingsExpressionEditor.cs
- StorageConditionPropertyMapping.cs
- RawAppCommandInputReport.cs
- CompilerResults.cs
- SQLGuidStorage.cs
- SectionRecord.cs
- Suspend.cs
- UInt16Storage.cs
- DataTableClearEvent.cs
- Config.cs