Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlRetyper.cs / 1 / SqlRetyper.cs
using System.Linq;
namespace System.Data.Linq.SqlClient {
using System.Data.Linq.Mapping;
internal class SqlRetyper {
Visitor visitor;
internal SqlRetyper(TypeSystemProvider typeProvider, MetaModel model) {
this.visitor = new Visitor(typeProvider, model);
}
internal SqlNode Retype(SqlNode node) {
return this.visitor.Visit(node);
}
class Visitor : SqlVisitor {
private TypeSystemProvider typeProvider;
private SqlFactory sql;
internal Visitor(TypeSystemProvider typeProvider, MetaModel model) {
this.sql = new SqlFactory(typeProvider, model);
this.typeProvider = typeProvider;
}
internal override SqlExpression VisitColumn(SqlColumn col) {
return base.VisitColumn(col);
}
internal override SqlExpression VisitUnaryOperator(SqlUnary uo) {
base.VisitUnaryOperator(uo);
if (uo.NodeType != SqlNodeType.Convert && uo.Operand != null && uo.Operand.SqlType != null) {
uo.SetSqlType(this.typeProvider.PredictTypeForUnary(uo.NodeType, uo.Operand.SqlType));
}
return uo;
}
private static bool CanDbConvert(Type from, Type to) {
from = System.Data.Linq.SqlClient.TypeSystem.GetNonNullableType(from);
to = System.Data.Linq.SqlClient.TypeSystem.GetNonNullableType(to);
if (from == to)
return true;
if (to.IsAssignableFrom(from))
return true;
var tcTo = Type.GetTypeCode(to);
var tcFrom = Type.GetTypeCode(from);
switch (tcTo) {
case TypeCode.Int16: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte;
case TypeCode.Int32: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16;
case TypeCode.Int64: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16 || tcFrom == TypeCode.Int32 || tcFrom==TypeCode.UInt32;
case TypeCode.UInt16: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte;
case TypeCode.UInt32: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16;
case TypeCode.UInt64: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16 || tcFrom == TypeCode.Int32 || tcFrom == TypeCode.UInt32;
case TypeCode.Double: return tcFrom == TypeCode.Single;
case TypeCode.Decimal: return tcFrom == TypeCode.Single || tcFrom == TypeCode.Double;
}
return false;
}
internal override SqlExpression VisitBinaryOperator(SqlBinary bo) {
base.VisitBinaryOperator(bo);
if (bo.NodeType.IsComparisonOperator()
&& bo.Left.ClrType!=typeof(bool) && bo.Right.ClrType!=typeof(bool)) {
// Strip unnecessary CONVERT calls.
if (bo.Left.NodeType == SqlNodeType.Convert) {
var conv = (SqlUnary)bo.Left;
if (CanDbConvert(conv.Operand.ClrType, bo.Right.ClrType)
&& conv.Operand.SqlType.ComparePrecedenceTo(bo.Right.SqlType) != 1) {
return VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, conv.Operand, bo.Right));
}
}
if (bo.Right.NodeType == SqlNodeType.Convert) {
var conv = (SqlUnary)bo.Right;
if (CanDbConvert(conv.Operand.ClrType, bo.Left.ClrType)
&& conv.Operand.SqlType.ComparePrecedenceTo(bo.Left.SqlType) != 1) {
return VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, bo.Left, conv.Operand));
}
}
}
if (bo.Right != null && bo.NodeType != SqlNodeType.Concat) {
SqlExpression left = bo.Left;
SqlExpression right = bo.Right;
this.CoerceBinaryArgs(ref left, ref right);
if (bo.Left != left || bo.Right != right) {
bo = sql.Binary(bo.NodeType, left, right);
}
bo.SetSqlType(typeProvider.PredictTypeForBinary(bo.NodeType, left.SqlType, right.SqlType));
}
if (bo.NodeType.IsComparisonOperator()) {
// When comparing a unicode value against a non-unicode column,
// we want retype the parameter as non-unicode.
Func needsRetype =
(expr, val) => (val.NodeType == SqlNodeType.Value || val.NodeType == SqlNodeType.ClientParameter) &&
!(expr.NodeType == SqlNodeType.Value || expr.NodeType == SqlNodeType.ClientParameter) &&
val.SqlType.IsUnicodeType && !expr.SqlType.IsUnicodeType;
SqlSimpleTypeExpression valueToRetype = null;
if (needsRetype(bo.Left, bo.Right)) {
valueToRetype = (SqlSimpleTypeExpression)bo.Right;
} else if (needsRetype(bo.Right, bo.Left)) {
valueToRetype = (SqlSimpleTypeExpression)bo.Left;
}
if(valueToRetype != null) {
valueToRetype.SetSqlType(valueToRetype.SqlType.GetNonUnicodeEquivalent());
}
}
return bo;
}
internal override SqlExpression VisitLike(SqlLike like) {
base.VisitLike(like);
// When comparing a unicode pattern against a non-unicode expression,
// we want retype the pattern as non-unicode.
if (!like.Expression.SqlType.IsUnicodeType && like.Pattern.SqlType.IsUnicodeType &&
(like.Pattern.NodeType == SqlNodeType.Value || like.Pattern.NodeType == SqlNodeType.ClientParameter)) {
SqlSimpleTypeExpression pattern = (SqlSimpleTypeExpression)like.Pattern;
pattern.SetSqlType(pattern.SqlType.GetNonUnicodeEquivalent());
}
return like;
}
internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) {
base.VisitScalarSubSelect(ss);
ss.SetSqlType(ss.Select.Selection.SqlType);
return ss;
}
internal override SqlExpression VisitSearchedCase(SqlSearchedCase c) {
base.VisitSearchedCase(c);
// determine the best common type for all the when and else values
ProviderType type = c.Whens[0].Value.SqlType;
for (int i = 1; i < c.Whens.Count; i++) {
ProviderType whenType = c.Whens[i].Value.SqlType;
type = typeProvider.GetBestType(type, whenType);
}
if (c.Else != null) {
ProviderType elseType = c.Else.SqlType;
type = typeProvider.GetBestType(type, elseType);
}
// coerce each one
foreach (SqlWhen when in c.Whens.Where(w => w.Value.SqlType != type && !w.Value.SqlType.IsRuntimeOnlyType)) {
when.Value = sql.UnaryConvert(when.Value.ClrType, type, when.Value, when.Value.SourceExpression);
}
if (c.Else != null && c.Else.SqlType != type && !c.Else.SqlType.IsRuntimeOnlyType) {
c.Else = sql.UnaryConvert(c.Else.ClrType, type, c.Else, c.Else.SourceExpression);
}
return c;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
base.VisitSimpleCase(c);
// determine the best common type for all the when values
ProviderType type = c.Whens[0].Value.SqlType;
for (int i = 1; i < c.Whens.Count; i++) {
ProviderType whenType = c.Whens[i].Value.SqlType;
type = typeProvider.GetBestType(type, whenType);
}
// coerce each one
foreach (SqlWhen when in c.Whens.Where(w => w.Value.SqlType != type && !w.Value.SqlType.IsRuntimeOnlyType)) {
when.Value = sql.UnaryConvert(when.Value.ClrType, type, when.Value, when.Value.SourceExpression);
}
return c;
}
internal override SqlStatement VisitAssign(SqlAssign sa) {
base.VisitAssign(sa);
SqlExpression right = sa.RValue;
this.CoerceToFirst(sa.LValue, ref right);
sa.RValue = right;
return sa;
}
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
for (int i = 0, n = fc.Arguments.Count; i < n; i++) {
fc.Arguments[i] = this.VisitExpression(fc.Arguments[i]);
}
if (fc.Arguments.Count > 0) {
ProviderType oldType = fc.Arguments[0].SqlType;
// if this has a real argument (not e.g. the symbol "DAY" in DATEDIFF(DAY,...))
if (oldType != null) {
ProviderType newType = this.typeProvider.ReturnTypeOfFunction(fc);
if (newType != null) {
fc.SetSqlType(newType);
}
}
}
return fc;
}
private void CoerceToFirst(SqlExpression arg1, ref SqlExpression arg2) {
if (arg1.SqlType != null && arg2.SqlType != null) {
if (arg2.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg2;
arg2 = sql.Value(
arg1.ClrType, arg1.SqlType,
DBConvert.ChangeType(val.Value, arg1.ClrType),
val.IsClientSpecified, arg2.SourceExpression
);
} else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg2;
cp.SetSqlType(arg1.SqlType);
} else {
arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression);
}
}
}
private void CoerceBinaryArgs(ref SqlExpression arg1, ref SqlExpression arg2) {
if (arg1.SqlType != null && arg2.SqlType != null) {
if (!arg1.SqlType.IsSameTypeFamily(arg2.SqlType)) {
if (arg1.ClrType == typeof(bool) || arg2.ClrType == typeof(bool)) {
// Don't coerce bools because predicates and bits have not been resolved yet.
// Leave this for booleanizer.
return;
} else if (arg2.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg2;
object clrValue = val.Value;
if (!val.ClrType.IsAssignableFrom(arg1.ClrType)) {
clrValue = DBConvert.ChangeType(clrValue, arg1.ClrType);
}
ProviderType newSqlType1 = typeProvider.ChangeTypeFamilyTo(arg2.SqlType, arg1.SqlType);
arg2 = sql.Value(arg1.ClrType, newSqlType1, clrValue, val.IsClientSpecified, arg2.SourceExpression);
} else if (arg1.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg1;
object clrValue = val.Value;
if (!val.ClrType.IsAssignableFrom(arg2.ClrType)) {
clrValue = DBConvert.ChangeType(clrValue, arg2.ClrType);
}
ProviderType newSqlType2 = typeProvider.ChangeTypeFamilyTo(arg1.SqlType, arg2.SqlType);
arg1 = sql.Value(arg2.ClrType, newSqlType2, clrValue, val.IsClientSpecified, arg1.SourceExpression);
} else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg2;
cp.SetSqlType(arg1.SqlType);
} else if (arg1.NodeType == SqlNodeType.ClientParameter && arg1.SqlType != arg2.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg1;
cp.SetSqlType(arg2.SqlType);
} else {
int coercionPrecedence = arg1.SqlType.ComparePrecedenceTo(arg2.SqlType);
if (coercionPrecedence > 0) {
arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression);
} else if (coercionPrecedence < 0) {
arg1 = sql.UnaryConvert(arg2.ClrType, arg2.SqlType, arg1, arg1.SourceExpression);
}
}
} else if ((arg1.SqlType.HasPrecisionAndScale && arg2.SqlType.HasPrecisionAndScale && arg1.SqlType!=arg2.SqlType) ||
sql.IsSqlHighPrecisionDateTimeType(arg1) || sql.IsSqlHighPrecisionDateTimeType(arg2)) {
var best = typeProvider.GetBestType(arg1.SqlType, arg2.SqlType);
var te1 = arg1 as SqlSimpleTypeExpression;
if (te1 != null) {
te1.SetSqlType(best);
}
var te2 = arg2 as SqlSimpleTypeExpression;
if (te2 != null) {
te2.SetSqlType(best);
}
//
// The SQL data type DATE is special, in that it has a higher range but lower
// precedence, so we need to account for that here (DevDiv 175229)
//
} else if (sql.IsSqlDateType(arg1) && !sql.IsSqlHighPrecisionDateTimeType(arg2)) {
var te2 = arg2 as SqlSimpleTypeExpression;
if (te2 != null) {
te2.SetSqlType(arg1.SqlType);
}
} else if (sql.IsSqlDateType(arg2) && !sql.IsSqlHighPrecisionDateTimeType(arg1)) {
var te1 = arg1 as SqlSimpleTypeExpression;
if (te1 != null) {
te1.SetSqlType(arg2.SqlType);
}
}
}
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.Linq;
namespace System.Data.Linq.SqlClient {
using System.Data.Linq.Mapping;
internal class SqlRetyper {
Visitor visitor;
internal SqlRetyper(TypeSystemProvider typeProvider, MetaModel model) {
this.visitor = new Visitor(typeProvider, model);
}
internal SqlNode Retype(SqlNode node) {
return this.visitor.Visit(node);
}
class Visitor : SqlVisitor {
private TypeSystemProvider typeProvider;
private SqlFactory sql;
internal Visitor(TypeSystemProvider typeProvider, MetaModel model) {
this.sql = new SqlFactory(typeProvider, model);
this.typeProvider = typeProvider;
}
internal override SqlExpression VisitColumn(SqlColumn col) {
return base.VisitColumn(col);
}
internal override SqlExpression VisitUnaryOperator(SqlUnary uo) {
base.VisitUnaryOperator(uo);
if (uo.NodeType != SqlNodeType.Convert && uo.Operand != null && uo.Operand.SqlType != null) {
uo.SetSqlType(this.typeProvider.PredictTypeForUnary(uo.NodeType, uo.Operand.SqlType));
}
return uo;
}
private static bool CanDbConvert(Type from, Type to) {
from = System.Data.Linq.SqlClient.TypeSystem.GetNonNullableType(from);
to = System.Data.Linq.SqlClient.TypeSystem.GetNonNullableType(to);
if (from == to)
return true;
if (to.IsAssignableFrom(from))
return true;
var tcTo = Type.GetTypeCode(to);
var tcFrom = Type.GetTypeCode(from);
switch (tcTo) {
case TypeCode.Int16: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte;
case TypeCode.Int32: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16;
case TypeCode.Int64: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16 || tcFrom == TypeCode.Int32 || tcFrom==TypeCode.UInt32;
case TypeCode.UInt16: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte;
case TypeCode.UInt32: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16;
case TypeCode.UInt64: return tcFrom == TypeCode.Byte || tcFrom == TypeCode.SByte || tcFrom == TypeCode.Int16 || tcFrom == TypeCode.UInt16 || tcFrom == TypeCode.Int32 || tcFrom == TypeCode.UInt32;
case TypeCode.Double: return tcFrom == TypeCode.Single;
case TypeCode.Decimal: return tcFrom == TypeCode.Single || tcFrom == TypeCode.Double;
}
return false;
}
internal override SqlExpression VisitBinaryOperator(SqlBinary bo) {
base.VisitBinaryOperator(bo);
if (bo.NodeType.IsComparisonOperator()
&& bo.Left.ClrType!=typeof(bool) && bo.Right.ClrType!=typeof(bool)) {
// Strip unnecessary CONVERT calls.
if (bo.Left.NodeType == SqlNodeType.Convert) {
var conv = (SqlUnary)bo.Left;
if (CanDbConvert(conv.Operand.ClrType, bo.Right.ClrType)
&& conv.Operand.SqlType.ComparePrecedenceTo(bo.Right.SqlType) != 1) {
return VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, conv.Operand, bo.Right));
}
}
if (bo.Right.NodeType == SqlNodeType.Convert) {
var conv = (SqlUnary)bo.Right;
if (CanDbConvert(conv.Operand.ClrType, bo.Left.ClrType)
&& conv.Operand.SqlType.ComparePrecedenceTo(bo.Left.SqlType) != 1) {
return VisitBinaryOperator(new SqlBinary(bo.NodeType, bo.ClrType, bo.SqlType, bo.Left, conv.Operand));
}
}
}
if (bo.Right != null && bo.NodeType != SqlNodeType.Concat) {
SqlExpression left = bo.Left;
SqlExpression right = bo.Right;
this.CoerceBinaryArgs(ref left, ref right);
if (bo.Left != left || bo.Right != right) {
bo = sql.Binary(bo.NodeType, left, right);
}
bo.SetSqlType(typeProvider.PredictTypeForBinary(bo.NodeType, left.SqlType, right.SqlType));
}
if (bo.NodeType.IsComparisonOperator()) {
// When comparing a unicode value against a non-unicode column,
// we want retype the parameter as non-unicode.
Func needsRetype =
(expr, val) => (val.NodeType == SqlNodeType.Value || val.NodeType == SqlNodeType.ClientParameter) &&
!(expr.NodeType == SqlNodeType.Value || expr.NodeType == SqlNodeType.ClientParameter) &&
val.SqlType.IsUnicodeType && !expr.SqlType.IsUnicodeType;
SqlSimpleTypeExpression valueToRetype = null;
if (needsRetype(bo.Left, bo.Right)) {
valueToRetype = (SqlSimpleTypeExpression)bo.Right;
} else if (needsRetype(bo.Right, bo.Left)) {
valueToRetype = (SqlSimpleTypeExpression)bo.Left;
}
if(valueToRetype != null) {
valueToRetype.SetSqlType(valueToRetype.SqlType.GetNonUnicodeEquivalent());
}
}
return bo;
}
internal override SqlExpression VisitLike(SqlLike like) {
base.VisitLike(like);
// When comparing a unicode pattern against a non-unicode expression,
// we want retype the pattern as non-unicode.
if (!like.Expression.SqlType.IsUnicodeType && like.Pattern.SqlType.IsUnicodeType &&
(like.Pattern.NodeType == SqlNodeType.Value || like.Pattern.NodeType == SqlNodeType.ClientParameter)) {
SqlSimpleTypeExpression pattern = (SqlSimpleTypeExpression)like.Pattern;
pattern.SetSqlType(pattern.SqlType.GetNonUnicodeEquivalent());
}
return like;
}
internal override SqlExpression VisitScalarSubSelect(SqlSubSelect ss) {
base.VisitScalarSubSelect(ss);
ss.SetSqlType(ss.Select.Selection.SqlType);
return ss;
}
internal override SqlExpression VisitSearchedCase(SqlSearchedCase c) {
base.VisitSearchedCase(c);
// determine the best common type for all the when and else values
ProviderType type = c.Whens[0].Value.SqlType;
for (int i = 1; i < c.Whens.Count; i++) {
ProviderType whenType = c.Whens[i].Value.SqlType;
type = typeProvider.GetBestType(type, whenType);
}
if (c.Else != null) {
ProviderType elseType = c.Else.SqlType;
type = typeProvider.GetBestType(type, elseType);
}
// coerce each one
foreach (SqlWhen when in c.Whens.Where(w => w.Value.SqlType != type && !w.Value.SqlType.IsRuntimeOnlyType)) {
when.Value = sql.UnaryConvert(when.Value.ClrType, type, when.Value, when.Value.SourceExpression);
}
if (c.Else != null && c.Else.SqlType != type && !c.Else.SqlType.IsRuntimeOnlyType) {
c.Else = sql.UnaryConvert(c.Else.ClrType, type, c.Else, c.Else.SourceExpression);
}
return c;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
base.VisitSimpleCase(c);
// determine the best common type for all the when values
ProviderType type = c.Whens[0].Value.SqlType;
for (int i = 1; i < c.Whens.Count; i++) {
ProviderType whenType = c.Whens[i].Value.SqlType;
type = typeProvider.GetBestType(type, whenType);
}
// coerce each one
foreach (SqlWhen when in c.Whens.Where(w => w.Value.SqlType != type && !w.Value.SqlType.IsRuntimeOnlyType)) {
when.Value = sql.UnaryConvert(when.Value.ClrType, type, when.Value, when.Value.SourceExpression);
}
return c;
}
internal override SqlStatement VisitAssign(SqlAssign sa) {
base.VisitAssign(sa);
SqlExpression right = sa.RValue;
this.CoerceToFirst(sa.LValue, ref right);
sa.RValue = right;
return sa;
}
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
for (int i = 0, n = fc.Arguments.Count; i < n; i++) {
fc.Arguments[i] = this.VisitExpression(fc.Arguments[i]);
}
if (fc.Arguments.Count > 0) {
ProviderType oldType = fc.Arguments[0].SqlType;
// if this has a real argument (not e.g. the symbol "DAY" in DATEDIFF(DAY,...))
if (oldType != null) {
ProviderType newType = this.typeProvider.ReturnTypeOfFunction(fc);
if (newType != null) {
fc.SetSqlType(newType);
}
}
}
return fc;
}
private void CoerceToFirst(SqlExpression arg1, ref SqlExpression arg2) {
if (arg1.SqlType != null && arg2.SqlType != null) {
if (arg2.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg2;
arg2 = sql.Value(
arg1.ClrType, arg1.SqlType,
DBConvert.ChangeType(val.Value, arg1.ClrType),
val.IsClientSpecified, arg2.SourceExpression
);
} else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg2;
cp.SetSqlType(arg1.SqlType);
} else {
arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression);
}
}
}
private void CoerceBinaryArgs(ref SqlExpression arg1, ref SqlExpression arg2) {
if (arg1.SqlType != null && arg2.SqlType != null) {
if (!arg1.SqlType.IsSameTypeFamily(arg2.SqlType)) {
if (arg1.ClrType == typeof(bool) || arg2.ClrType == typeof(bool)) {
// Don't coerce bools because predicates and bits have not been resolved yet.
// Leave this for booleanizer.
return;
} else if (arg2.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg2;
object clrValue = val.Value;
if (!val.ClrType.IsAssignableFrom(arg1.ClrType)) {
clrValue = DBConvert.ChangeType(clrValue, arg1.ClrType);
}
ProviderType newSqlType1 = typeProvider.ChangeTypeFamilyTo(arg2.SqlType, arg1.SqlType);
arg2 = sql.Value(arg1.ClrType, newSqlType1, clrValue, val.IsClientSpecified, arg2.SourceExpression);
} else if (arg1.NodeType == SqlNodeType.Value) {
SqlValue val = (SqlValue)arg1;
object clrValue = val.Value;
if (!val.ClrType.IsAssignableFrom(arg2.ClrType)) {
clrValue = DBConvert.ChangeType(clrValue, arg2.ClrType);
}
ProviderType newSqlType2 = typeProvider.ChangeTypeFamilyTo(arg1.SqlType, arg2.SqlType);
arg1 = sql.Value(arg2.ClrType, newSqlType2, clrValue, val.IsClientSpecified, arg1.SourceExpression);
} else if (arg2.NodeType == SqlNodeType.ClientParameter && arg2.SqlType != arg1.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg2;
cp.SetSqlType(arg1.SqlType);
} else if (arg1.NodeType == SqlNodeType.ClientParameter && arg1.SqlType != arg2.SqlType) {
SqlClientParameter cp = (SqlClientParameter)arg1;
cp.SetSqlType(arg2.SqlType);
} else {
int coercionPrecedence = arg1.SqlType.ComparePrecedenceTo(arg2.SqlType);
if (coercionPrecedence > 0) {
arg2 = sql.UnaryConvert(arg1.ClrType, arg1.SqlType, arg2, arg2.SourceExpression);
} else if (coercionPrecedence < 0) {
arg1 = sql.UnaryConvert(arg2.ClrType, arg2.SqlType, arg1, arg1.SourceExpression);
}
}
} else if ((arg1.SqlType.HasPrecisionAndScale && arg2.SqlType.HasPrecisionAndScale && arg1.SqlType!=arg2.SqlType) ||
sql.IsSqlHighPrecisionDateTimeType(arg1) || sql.IsSqlHighPrecisionDateTimeType(arg2)) {
var best = typeProvider.GetBestType(arg1.SqlType, arg2.SqlType);
var te1 = arg1 as SqlSimpleTypeExpression;
if (te1 != null) {
te1.SetSqlType(best);
}
var te2 = arg2 as SqlSimpleTypeExpression;
if (te2 != null) {
te2.SetSqlType(best);
}
//
// The SQL data type DATE is special, in that it has a higher range but lower
// precedence, so we need to account for that here (DevDiv 175229)
//
} else if (sql.IsSqlDateType(arg1) && !sql.IsSqlHighPrecisionDateTimeType(arg2)) {
var te2 = arg2 as SqlSimpleTypeExpression;
if (te2 != null) {
te2.SetSqlType(arg1.SqlType);
}
} else if (sql.IsSqlDateType(arg2) && !sql.IsSqlHighPrecisionDateTimeType(arg1)) {
var te1 = arg1 as SqlSimpleTypeExpression;
if (te1 != null) {
te1.SetSqlType(arg2.SqlType);
}
}
}
}
}
}
}
// 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
- SaveLedgerEntryRequest.cs
- GlyphsSerializer.cs
- PropertyItemInternal.cs
- DoubleAnimationUsingKeyFrames.cs
- HttpCacheParams.cs
- SqlTriggerContext.cs
- ServiceOperation.cs
- OperatorExpressions.cs
- CornerRadiusConverter.cs
- NativeMethods.cs
- QilStrConcatenator.cs
- OleAutBinder.cs
- EventManager.cs
- util.cs
- SafeNativeMethods.cs
- DbModificationCommandTree.cs
- TreeNodeCollection.cs
- RSAPKCS1KeyExchangeFormatter.cs
- SamlSecurityTokenAuthenticator.cs
- LayoutTableCell.cs
- HtmlMeta.cs
- CssStyleCollection.cs
- MenuStrip.cs
- SevenBitStream.cs
- StandardOleMarshalObject.cs
- StylusPointDescription.cs
- TimeStampChecker.cs
- NonParentingControl.cs
- ADMembershipUser.cs
- SqlProcedureAttribute.cs
- ReferentialConstraint.cs
- WebPermission.cs
- ToolStripItemClickedEventArgs.cs
- SnapLine.cs
- PassportIdentity.cs
- ElementProxy.cs
- EdmRelationshipRoleAttribute.cs
- DrawingAttributes.cs
- ServiceHostingEnvironment.cs
- TypeNameConverter.cs
- CharConverter.cs
- CookieHandler.cs
- ScaleTransform3D.cs
- HtmlTableCellCollection.cs
- InputManager.cs
- MatrixAnimationBase.cs
- DependencyPropertyChangedEventArgs.cs
- IndexOutOfRangeException.cs
- AutomationPattern.cs
- DataBinder.cs
- cache.cs
- GeneralTransform.cs
- RSACryptoServiceProvider.cs
- HyperLinkStyle.cs
- SafeNativeMethods.cs
- SafeThemeHandle.cs
- DeclaredTypeValidator.cs
- WinFormsSecurity.cs
- EntityProxyFactory.cs
- GeometryGroup.cs
- SystemIcons.cs
- Triangle.cs
- RawStylusInput.cs
- Vector3DIndependentAnimationStorage.cs
- MonthCalendarDesigner.cs
- Currency.cs
- SQLByte.cs
- _DynamicWinsockMethods.cs
- Event.cs
- ToolStripComboBox.cs
- LocationUpdates.cs
- StringAnimationUsingKeyFrames.cs
- wgx_exports.cs
- DesignParameter.cs
- AggregationMinMaxHelpers.cs
- ObjectAnimationUsingKeyFrames.cs
- DataGridView.cs
- DataServiceEntityAttribute.cs
- RestClientProxyHandler.cs
- DataGridTextBoxColumn.cs
- SaveRecipientRequest.cs
- DependencyObjectProvider.cs
- FontFamily.cs
- DrawingState.cs
- RemotingConfiguration.cs
- TableItemProviderWrapper.cs
- SerializableTypeCodeDomSerializer.cs
- Base64Encoder.cs
- StringCollection.cs
- XamlClipboardData.cs
- COM2IManagedPerPropertyBrowsingHandler.cs
- Effect.cs
- ToolStripDropDownClosingEventArgs.cs
- MenuEventArgs.cs
- XmlTextReader.cs
- CrossContextChannel.cs
- RuntimeEnvironment.cs
- CollectionsUtil.cs
- ButtonAutomationPeer.cs
- SapiInterop.cs