Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlColumnizer.cs / 1305376 / SqlColumnizer.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Linq;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
namespace System.Data.Linq.SqlClient {
// partions select expressions and common subexpressions into scalar and non-scalar pieces by
// wrapping scalar pieces floating column nodes.
internal class SqlColumnizer {
ColumnNominator nominator;
ColumnDeclarer declarer;
internal SqlColumnizer() {
this.nominator = new ColumnNominator();
this.declarer = new ColumnDeclarer();
}
internal SqlExpression ColumnizeSelection(SqlExpression selection) {
return this.declarer.Declare(selection, this.nominator.Nominate(selection));
}
internal static bool CanBeColumn(SqlExpression expression) {
return ColumnNominator.CanBeColumn(expression);
}
class ColumnDeclarer : SqlVisitor {
HashSet candidates;
internal ColumnDeclarer() {
}
internal SqlExpression Declare(SqlExpression expression, HashSet candidates) {
this.candidates = candidates;
return (SqlExpression)this.Visit(expression);
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expr = node as SqlExpression;
if (expr != null) {
if (this.candidates.Contains(expr)) {
if (expr.NodeType == SqlNodeType.Column ||
expr.NodeType == SqlNodeType.ColumnRef) {
return expr;
}
else {
return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
}
}
}
return base.Visit(node);
}
}
class ColumnNominator : SqlVisitor {
bool isBlocked;
HashSet candidates;
internal HashSet Nominate(SqlExpression expression) {
this.candidates = new HashSet();
this.isBlocked = false;
this.Visit(expression);
return this.candidates;
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expression = node as SqlExpression;
if (expression != null) {
bool saveIsBlocked = this.isBlocked;
this.isBlocked = false;
if (CanRecurseColumnize(expression)) {
base.Visit(expression);
}
if (!this.isBlocked) {
if (CanBeColumn(expression)) {
this.candidates.Add(expression);
}
else {
this.isBlocked = true;
}
}
this.isBlocked |= saveIsBlocked;
}
return node;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
internal override SqlExpression VisitTypeCase(SqlTypeCase tc) {
tc.Discriminator = this.VisitExpression(tc.Discriminator);
for (int i = 0, n = tc.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
}
return tc;
}
internal override SqlExpression VisitClientCase(SqlClientCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
private static bool CanRecurseColumnize(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.AliasRef:
case SqlNodeType.ColumnRef:
case SqlNodeType.Column:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Exists:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
case SqlNodeType.Value:
case SqlNodeType.Select:
return false;
default:
return true;
}
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
private static bool IsClientOnly(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.ClientCase:
case SqlNodeType.TypeCase:
case SqlNodeType.ClientArray:
case SqlNodeType.Grouping:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.SharedExpression:
case SqlNodeType.SimpleExpression:
case SqlNodeType.AliasRef:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
return true;
case SqlNodeType.OuterJoinedValue:
return IsClientOnly(((SqlUnary)expr).Operand);
default:
return false;
}
}
internal static bool CanBeColumn(SqlExpression expression) {
if (!IsClientOnly(expression)
&& expression.NodeType != SqlNodeType.Column
&& expression.SqlType.CanBeColumn) {
switch (expression.NodeType) {
case SqlNodeType.MethodCall:
case SqlNodeType.Member:
case SqlNodeType.New:
return PostBindDotNetConverter.CanConvert(expression);
default:
return true;
}
}
return false;
}
}
}
}
// 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.Linq.Expressions;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Linq;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics;
namespace System.Data.Linq.SqlClient {
// partions select expressions and common subexpressions into scalar and non-scalar pieces by
// wrapping scalar pieces floating column nodes.
internal class SqlColumnizer {
ColumnNominator nominator;
ColumnDeclarer declarer;
internal SqlColumnizer() {
this.nominator = new ColumnNominator();
this.declarer = new ColumnDeclarer();
}
internal SqlExpression ColumnizeSelection(SqlExpression selection) {
return this.declarer.Declare(selection, this.nominator.Nominate(selection));
}
internal static bool CanBeColumn(SqlExpression expression) {
return ColumnNominator.CanBeColumn(expression);
}
class ColumnDeclarer : SqlVisitor {
HashSet candidates;
internal ColumnDeclarer() {
}
internal SqlExpression Declare(SqlExpression expression, HashSet candidates) {
this.candidates = candidates;
return (SqlExpression)this.Visit(expression);
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expr = node as SqlExpression;
if (expr != null) {
if (this.candidates.Contains(expr)) {
if (expr.NodeType == SqlNodeType.Column ||
expr.NodeType == SqlNodeType.ColumnRef) {
return expr;
}
else {
return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
}
}
}
return base.Visit(node);
}
}
class ColumnNominator : SqlVisitor {
bool isBlocked;
HashSet candidates;
internal HashSet Nominate(SqlExpression expression) {
this.candidates = new HashSet();
this.isBlocked = false;
this.Visit(expression);
return this.candidates;
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expression = node as SqlExpression;
if (expression != null) {
bool saveIsBlocked = this.isBlocked;
this.isBlocked = false;
if (CanRecurseColumnize(expression)) {
base.Visit(expression);
}
if (!this.isBlocked) {
if (CanBeColumn(expression)) {
this.candidates.Add(expression);
}
else {
this.isBlocked = true;
}
}
this.isBlocked |= saveIsBlocked;
}
return node;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
internal override SqlExpression VisitTypeCase(SqlTypeCase tc) {
tc.Discriminator = this.VisitExpression(tc.Discriminator);
for (int i = 0, n = tc.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
}
return tc;
}
internal override SqlExpression VisitClientCase(SqlClientCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
private static bool CanRecurseColumnize(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.AliasRef:
case SqlNodeType.ColumnRef:
case SqlNodeType.Column:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Exists:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
case SqlNodeType.Value:
case SqlNodeType.Select:
return false;
default:
return true;
}
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
private static bool IsClientOnly(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.ClientCase:
case SqlNodeType.TypeCase:
case SqlNodeType.ClientArray:
case SqlNodeType.Grouping:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.SharedExpression:
case SqlNodeType.SimpleExpression:
case SqlNodeType.AliasRef:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
return true;
case SqlNodeType.OuterJoinedValue:
return IsClientOnly(((SqlUnary)expr).Operand);
default:
return false;
}
}
internal static bool CanBeColumn(SqlExpression expression) {
if (!IsClientOnly(expression)
&& expression.NodeType != SqlNodeType.Column
&& expression.SqlType.CanBeColumn) {
switch (expression.NodeType) {
case SqlNodeType.MethodCall:
case SqlNodeType.Member:
case SqlNodeType.New:
return PostBindDotNetConverter.CanConvert(expression);
default:
return true;
}
}
return false;
}
}
}
}
// 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
- PictureBox.cs
- UrlMapping.cs
- GrowingArray.cs
- CodeGenerator.cs
- PeerCollaborationPermission.cs
- HtmlHead.cs
- RawAppCommandInputReport.cs
- EmbossBitmapEffect.cs
- DeclarationUpdate.cs
- ContentOnlyMessage.cs
- BinaryReader.cs
- TableLayoutRowStyleCollection.cs
- AddToCollection.cs
- AddDataControlFieldDialog.cs
- SID.cs
- BaseResourcesBuildProvider.cs
- DesignerEventService.cs
- TrackingMemoryStreamFactory.cs
- OdbcConnectionFactory.cs
- TextServicesDisplayAttributePropertyRanges.cs
- TextParagraph.cs
- Animatable.cs
- ScrollItemPatternIdentifiers.cs
- EmulateRecognizeCompletedEventArgs.cs
- DataRowCollection.cs
- Vector3D.cs
- Zone.cs
- DecimalKeyFrameCollection.cs
- DiscoveryEndpointValidator.cs
- WindowsRegion.cs
- Zone.cs
- BamlLocalizabilityResolver.cs
- ipaddressinformationcollection.cs
- Gdiplus.cs
- ButtonPopupAdapter.cs
- _WebProxyDataBuilder.cs
- Tile.cs
- AnnotationHighlightLayer.cs
- CaseCqlBlock.cs
- SuppressMessageAttribute.cs
- MenuAdapter.cs
- BoolExpression.cs
- LinkConverter.cs
- PropertySegmentSerializationProvider.cs
- RegisteredDisposeScript.cs
- DbCommandTree.cs
- _FixedSizeReader.cs
- InternalCache.cs
- CultureTableRecord.cs
- AssemblyBuilder.cs
- MailMessage.cs
- CopyNodeSetAction.cs
- DateTimeUtil.cs
- ProviderSettingsCollection.cs
- ContextBase.cs
- MenuStrip.cs
- ListViewInsertedEventArgs.cs
- RelationshipFixer.cs
- ThemeableAttribute.cs
- ZipIOEndOfCentralDirectoryBlock.cs
- TimeoutConverter.cs
- PrivilegeNotHeldException.cs
- QueryExpression.cs
- BasicExpandProvider.cs
- RightsManagementEncryptedStream.cs
- TableParagraph.cs
- HostedHttpTransportManager.cs
- SelectingProviderEventArgs.cs
- PartitionResolver.cs
- SizeLimitedCache.cs
- Pen.cs
- CheckBox.cs
- Border.cs
- webclient.cs
- AssociationSetEnd.cs
- ProfileService.cs
- ADMembershipUser.cs
- CommandField.cs
- FileDetails.cs
- StateItem.cs
- FrameworkElementAutomationPeer.cs
- CustomAttributeFormatException.cs
- WebCategoryAttribute.cs
- CommandID.cs
- TablePatternIdentifiers.cs
- BoundField.cs
- DynamicValidatorEventArgs.cs
- VarRefManager.cs
- CultureInfoConverter.cs
- ByteRangeDownloader.cs
- CachedTypeface.cs
- DecoderNLS.cs
- CornerRadiusConverter.cs
- TablePatternIdentifiers.cs
- InkCanvas.cs
- SettingsContext.cs
- XmlNodeList.cs
- QueryNode.cs
- CodeTypeReferenceExpression.cs
- DataTableTypeConverter.cs