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
- Debug.cs
- Win32Native.cs
- DesignerHierarchicalDataSourceView.cs
- UnsafeNativeMethodsCLR.cs
- Clock.cs
- CollectionChangeEventArgs.cs
- InputScopeNameConverter.cs
- ObjectListComponentEditor.cs
- BooleanAnimationUsingKeyFrames.cs
- Utils.cs
- EnumerableWrapperWeakToStrong.cs
- EncoderReplacementFallback.cs
- RangeValidator.cs
- StringDictionary.cs
- InstallerTypeAttribute.cs
- PropertyManager.cs
- ResourceDisplayNameAttribute.cs
- MinimizableAttributeTypeConverter.cs
- Calendar.cs
- SqlColumnizer.cs
- DataGridViewCellStateChangedEventArgs.cs
- ScriptHandlerFactory.cs
- ITreeGenerator.cs
- MsmqNonTransactedPoisonHandler.cs
- AttachedPropertyBrowsableAttribute.cs
- TextFormatter.cs
- TransactionProxy.cs
- CustomErrorsSection.cs
- ContextDataSource.cs
- NavigationWindow.cs
- DeleteCardRequest.cs
- SamlSubject.cs
- ContractDescription.cs
- HuffCodec.cs
- WorkflowFormatterBehavior.cs
- SqlErrorCollection.cs
- SafeHandle.cs
- XmlNavigatorStack.cs
- WindowsNonControl.cs
- SelectionRange.cs
- DataReaderContainer.cs
- RealizedColumnsBlock.cs
- SQLInt32.cs
- PropertyValue.cs
- externdll.cs
- TreeNodeStyleCollection.cs
- CqlGenerator.cs
- DbConnectionFactory.cs
- SymLanguageType.cs
- MultipartIdentifier.cs
- WeakEventTable.cs
- __FastResourceComparer.cs
- ConstantProjectedSlot.cs
- TriggerCollection.cs
- followingsibling.cs
- ReadOnlyCollectionBase.cs
- shaperfactoryquerycacheentry.cs
- CodeIndexerExpression.cs
- DesignerView.xaml.cs
- LinkedResource.cs
- CultureNotFoundException.cs
- ChildrenQuery.cs
- MenuBindingsEditor.cs
- LocationSectionRecord.cs
- IfJoinedCondition.cs
- AudienceUriMode.cs
- ChangeBlockUndoRecord.cs
- AttributeCollection.cs
- SmuggledIUnknown.cs
- AlignmentXValidation.cs
- UIElement.cs
- FormatConvertedBitmap.cs
- InkCollectionBehavior.cs
- EditorZoneBase.cs
- FrugalList.cs
- DesignerActionPanel.cs
- RunClient.cs
- Serializer.cs
- ReverseQueryOperator.cs
- ListViewPagedDataSource.cs
- CommandHelpers.cs
- TextRange.cs
- CommandConverter.cs
- TargetInvocationException.cs
- ColumnHeader.cs
- XmlNullResolver.cs
- BitmapData.cs
- SqlMethodTransformer.cs
- CollectionViewSource.cs
- DataRecordObjectView.cs
- Decoder.cs
- PagerStyle.cs
- SerializableAttribute.cs
- shaperfactoryquerycacheentry.cs
- PresentationAppDomainManager.cs
- RuleSetDialog.Designer.cs
- DBCommand.cs
- DesignerTransactionCloseEvent.cs
- OleDbParameterCollection.cs
- CompoundFileStorageReference.cs