private bool OldWillFitInNew(ProviderType oldSqlType, ProviderType newSqlType) {
            bool result = newSqlType.IsLargeType                // we can fit into a large type
                || !newSqlType.HasSizeOrIsLarge                 // if the type is not large, and doesn't have a size specified, assume OK
                || (!oldSqlType.IsLargeType                     // else, if the old type isn't large
                    && oldSqlType.HasSizeOrIsLarge              // and both old ..
                    && newSqlType.HasSizeOrIsLarge              // .. and new sizes are specified
                    && newSqlType.Size >= oldSqlType.Size);     // and if the new size is larger or equal to the old, then OK

            return result;
        }
        bool StringConversionIsSafe(ProviderType oldSqlType, ProviderType newSqlType) {
            // if we are dealing with a conversion from a fixed-size string or char
            if (BothTypesAreStrings(oldSqlType, newSqlType)) {
                    // we assume we can convert to an unknown size
                    // we can do the conversion when both sizes are specified and the destination size is larger
                return !newSqlType.HasSizeOrIsLarge || OldWillFitInNew(oldSqlType, newSqlType);
            }

            // give the benefit of the doubt for conversion from non-string types
            return true;
        }
        bool StringConversionIsNeeded(ProviderType oldSqlType, ProviderType newSqlType) {
            if (BothTypesAreStrings(oldSqlType, newSqlType)) {
                bool stringsFixedSize = oldSqlType.IsFixedSize || newSqlType.IsFixedSize;

                if (!newSqlType.HasSizeOrIsLarge) {
                    // we assume we can convert to an unknown size
                    return true;
                }
                else if (OldWillFitInNew(oldSqlType, newSqlType)) {
                    // we can do the conversion when both sizes are specified and the destination size is larger
                    // but we only need to do it when one is fixed size
                    return stringsFixedSize;
                } else {
                    return false;
                }
            } else {
                return true;
            }
        }
        internal SqlBinary Binary(SqlNodeType nodeType, SqlExpression left, SqlExpression right, MethodInfo method, Type clrType)
        {
            ProviderType sqlType = null;

            if (nodeType.IsPredicateBinaryOperator())
            {
                if (clrType == null)
                {
                    clrType = typeof(bool);
                }
                sqlType = typeProvider.From(clrType);
            }
            else
            {
                ProviderType resultType = this.typeProvider.PredictTypeForBinary(nodeType, left.SqlType, right.SqlType);
                if (resultType == right.SqlType)
                {
                    if (clrType == null)
                    {
                        clrType = right.ClrType;
                    }
                    sqlType = right.SqlType;
                }
                else if (resultType == left.SqlType)
                {
                    if (clrType == null)
                    {
                        clrType = left.ClrType;
                    }
                    sqlType = left.SqlType;
                }
                else
                {
                    sqlType = resultType;
                    if (clrType == null)
                    {
                        clrType = resultType.GetClosestRuntimeType();
                    }
                }
            }
            return(new SqlBinary(nodeType, clrType, sqlType, left, right, method));
        }
Ejemplo n.º 5
0
            internal override SqlExpression VisitBinaryOperator(SqlBinary bo)
            {
                //
                // Special case to allow DateTime CLR type to be passed as a paramater where
                // a SQL type TIME is expected. We do this only for the equality/inequality
                // comparisons.
                //
                switch (bo.NodeType)
                {
                case SqlNodeType.EQ:
                case SqlNodeType.EQ2V:
                case SqlNodeType.NE:
                case SqlNodeType.NE2V: {
                    SqlDbType leftSqlDbType  = ((SqlTypeSystem.SqlType)(bo.Left.SqlType)).SqlDbType;
                    SqlDbType rightSqlDbType = ((SqlTypeSystem.SqlType)(bo.Right.SqlType)).SqlDbType;
                    if (leftSqlDbType == rightSqlDbType)
                    {
                        break;
                    }

                    bool isLeftColRef  = bo.Left is SqlColumnRef;
                    bool isRightColRef = bo.Right is SqlColumnRef;
                    if (isLeftColRef == isRightColRef)
                    {
                        break;
                    }

                    if (isLeftColRef && leftSqlDbType == SqlDbType.Time && bo.Right.ClrType == typeof(DateTime))
                    {
                        this.timeProviderType = bo.Left.SqlType;
                    }
                    else if (isRightColRef && rightSqlDbType == SqlDbType.Time && bo.Left.ClrType == typeof(DateTime))
                    {
                        this.timeProviderType = bo.Left.SqlType;
                    }
                    break;
                }
                }
                base.VisitBinaryOperator(bo);
                return(bo);
            }
Ejemplo n.º 6
0
            private bool RetypeOutParameter(SqlParameter node)
            {
                if (!node.SqlType.IsLargeType)
                {
                    return(false);
                }
                ProviderType newType = this.parameterizer.typeProvider.GetBestLargeType(node.SqlType);

                if (node.SqlType != newType)
                {
                    node.SetSqlType(newType);
                    return(true);
                }
                // Since we are dealing with a long out parameter that hasn't been
                // retyped, we need to annotate
                this.parameterizer.annotations.Add(
                    node,
                    new SqlServerCompatibilityAnnotation(
                        SqlClient.Strings.MaxSizeNotSupported(node.SourceExpression), SqlProvider.ProviderMode.Sql2000));
                return(false);
            }
Ejemplo n.º 7
0
 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);
 }
Ejemplo n.º 8
0
            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);
            }
Ejemplo n.º 9
0
            private void CoerceTypeFamily(SqlExpression arg1, SqlExpression arg2)
            {
                if ((arg1.SqlType.HasPrecisionAndScale && arg2.SqlType.HasPrecisionAndScale && arg1.SqlType != arg2.SqlType) ||
                    SqlFactory.IsSqlHighPrecisionDateTimeType(arg1) || SqlFactory.IsSqlHighPrecisionDateTimeType(arg2))
                {
                    ProviderType best = typeProvider.GetBestType(arg1.SqlType, arg2.SqlType);
                    SetSqlTypeIfSimpleExpression(arg1, best);
                    SetSqlTypeIfSimpleExpression(arg2, best);
                    return;
                }

                // 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)
                if (SqlFactory.IsSqlDateType(arg1) && !SqlFactory.IsSqlHighPrecisionDateTimeType(arg2))
                {
                    SetSqlTypeIfSimpleExpression(arg2, arg1.SqlType);
                }
                else if (SqlFactory.IsSqlDateType(arg2) && !SqlFactory.IsSqlHighPrecisionDateTimeType(arg1))
                {
                    SetSqlTypeIfSimpleExpression(arg1, arg2.SqlType);
                }
            }
        internal SqlUnary Unary(SqlNodeType nodeType, SqlExpression expression, MethodInfo method, Expression sourceExpression)
        {
            Type         clrType = null;
            ProviderType sqlType = null;

            if (nodeType == SqlNodeType.Count)
            {
                clrType = typeof(int);
                sqlType = typeProvider.From(typeof(int));
            }
            else if (nodeType == SqlNodeType.LongCount)
            {
                clrType = typeof(long);
                sqlType = typeProvider.From(typeof(long));
            }
            else if (nodeType == SqlNodeType.ClrLength)
            {
                clrType = typeof(int);
                sqlType = typeProvider.From(typeof(int));
            }
            else
            {
                if (nodeType.IsPredicateUnaryOperator())
                {
                    // DevDiv 201730 - Do not ignore nullability of bool type
                    clrType = expression.ClrType.Equals(typeof(bool?)) ? typeof(bool?) : typeof(bool);
                }
                else
                {
                    clrType = expression.ClrType;
                }
                sqlType = typeProvider.PredictTypeForUnary(nodeType, expression.SqlType);
            }

            return(new SqlUnary(nodeType, clrType, sqlType, expression, method, sourceExpression));
        }
Ejemplo n.º 11
0
 internal SqlBinary(SqlNodeType nt, Type clrType, ProviderType sqlType, SqlExpression left, SqlExpression right)
     : this(nt, clrType, sqlType, left, right, null)
 {
 }
 internal abstract ProviderType PredictTypeForBinary(SqlNodeType binaryOp, ProviderType leftType, ProviderType rightType);
 internal abstract ProviderType PredictTypeForBinary(SqlNodeType binaryOp, ProviderType leftType, ProviderType rightType);
 internal abstract ProviderType PredictTypeForUnary(SqlNodeType unaryOp, ProviderType operandType);
Ejemplo n.º 15
0
 internal SqlMember(Type clrType, ProviderType sqlType, SqlExpression expr, MemberInfo member)
     : base(SqlNodeType.Member, clrType, sqlType, expr.SourceExpression)
 {
     this.member = member;
     Expression  = expr;
 }
 private SqlExpression ConvertToMax(SqlExpression expr, ProviderType newType) {
     return sql.UnaryConvert(expr.ClrType, newType, expr, expr.SourceExpression);
 }
Ejemplo n.º 17
0
 internal SqlFunctionCall(Type clrType, ProviderType sqlType, string name, IEnumerable <SqlExpression> args, Expression source)
     : this(SqlNodeType.FunctionCall, clrType, sqlType, name, args, source)
 {
 }
 internal SqlExpression ConvertTo(Type clrType, ProviderType sqlType, SqlExpression expr)
 {
     return(UnaryConvert(clrType, sqlType, expr, expr.SourceExpression));
 }
            internal override SqlExpression VisitBinaryOperator(SqlBinary bo)
            {
                //
                // Special case to allow DateTime CLR type to be passed as a paramater where
                // a SQL type TIME is expected. We do this only for the equality/inequality
                // comparisons.
                //
                switch (bo.NodeType) {
                    case SqlNodeType.EQ:
                    case SqlNodeType.EQ2V:
                    case SqlNodeType.NE:
                    case SqlNodeType.NE2V: {
                        SqlDbType leftSqlDbType = ((SqlTypeSystem.SqlType)(bo.Left.SqlType)).SqlDbType;
                        SqlDbType rightSqlDbType = ((SqlTypeSystem.SqlType)(bo.Right.SqlType)).SqlDbType;
                        if (leftSqlDbType == rightSqlDbType)
                            break;

                        bool isLeftColRef = bo.Left is SqlColumnRef;
                        bool isRightColRef = bo.Right is SqlColumnRef;
                        if (isLeftColRef == isRightColRef)
                            break;

                        if (isLeftColRef && leftSqlDbType == SqlDbType.Time && bo.Right.ClrType == typeof(DateTime))
                            this.timeProviderType = bo.Left.SqlType;
                        else if (isRightColRef && rightSqlDbType == SqlDbType.Time && bo.Left.ClrType == typeof(DateTime))
                            this.timeProviderType = bo.Left.SqlType;
                        break;
                    }
                }
                base.VisitBinaryOperator(bo);
                return bo;
            }
 internal abstract void InitializeParameter(ProviderType type, System.Data.Common.DbParameter parameter, object value);
 /// <summary>
 /// Get a type that can hold the same information but belongs to a different type family.
 /// For example, to represent a SQL NChar as an integer type, we need to use the type int.
 /// (SQL smallint would not be able to contain characters with unicode >32768)
 /// </summary>
 /// <param name="toType">Type of the target type family</param>
 /// <returns>Smallest type of target type family that can hold equivalent information</returns>
 internal abstract ProviderType ChangeTypeFamilyTo(ProviderType type, ProviderType typeWithFamily);
 /// <summary>
 /// Returns a type that can be used to hold values for both the current
 /// type and the specified type without data loss.
 /// </summary>
 internal abstract ProviderType GetBestType(ProviderType typeA, ProviderType typeB);
 /// <summary>
 /// For LOB data types that have large type equivalents, this function returns the equivalent large
 /// data type.  If the type is not an LOB or cannot be converted, the function returns the current type.
 /// For example SqlServer defines the 'Image' LOB type, whose large type equivalent is VarBinary(MAX).
 /// </summary>
 internal abstract ProviderType GetBestLargeType(ProviderType type);
 /// <summary>
 /// Returns the most precise type in the family of the type given.
 /// A family is a group types that serve similar functions. For example,
 /// in SQL SmallInt and Int are part of one family.
 /// </summary>
 internal abstract ProviderType MostPreciseTypeInFamily(ProviderType type);
Ejemplo n.º 25
0
        private bool BothTypesAreStrings(ProviderType oldSqlType, ProviderType newSqlType) {
            bool result = oldSqlType.IsSameTypeFamily(sql.TypeProvider.From(typeof(string)))
                && newSqlType.IsSameTypeFamily(sql.TypeProvider.From(typeof(string)));

            return result;
        }
 /// <summary>
 /// Determines whether two types are in the same type family.
 /// A family is a group types that serve similar functions. For example,
 /// in SQL SmallInt and Int are part of one family.
 /// </summary>
 internal abstract bool IsSameTypeFamily(ProviderType type);
 internal SqlUnary UnaryConvert(Type targetClrType, ProviderType targetSqlType, SqlExpression expression, Expression sourceExpression)
 {
     System.Diagnostics.Debug.Assert(!targetSqlType.IsRuntimeOnlyType, "Attempted coversion to a runtime type: from = " + expression.SqlType.ToQueryString() + "; to = " + targetSqlType.ToQueryString() + "; source = " + sourceExpression.ToString());
     return(new SqlUnary(SqlNodeType.Convert, targetClrType, targetSqlType, expression, null, sourceExpression));
 }
Ejemplo n.º 28
0
 internal SqlFunctionCall(SqlNodeType nodeType, Type clrType, ProviderType sqlType, string name, IEnumerable <SqlExpression> args, Expression source)
     : base(nodeType, clrType, sqlType, source)
 {
     Name      = name;
     Arguments = new List <SqlExpression>(args);
 }
Ejemplo n.º 29
0
 internal SqlJoinedCollection(Type clrType, ProviderType sqlType, SqlExpression expression, SqlExpression count, Expression sourceExpression)
     : base(SqlNodeType.JoinedCollection, clrType, sqlType, sourceExpression)
 {
     this.expression = expression;
     this.count      = count;
 }
Ejemplo n.º 30
0
 private SqlExpression ConvertToMax(SqlExpression expr, ProviderType newType)
 {
     return(sql.UnaryConvert(expr.ClrType, newType, expr, expr.SourceExpression));
 }
 internal SqlFunctionCall FunctionCall(Type clrType, ProviderType sqlType, string name, IEnumerable <SqlExpression> args, Expression source)
 {
     return(new SqlFunctionCall(clrType, sqlType, name, args, source));
 }
 /// <summary>
 /// Compare implicit type coercion precedence.
 /// -1 means there is an implicit conversion from this->type.
 /// 0 means there is a two way implicit conversion from this->type
 /// 1 means there is an implicit conversion from type->this.
 /// </summary>
 internal abstract int ComparePrecedenceTo(ProviderType type);
 /// <summary>
 /// For LOB data types that have large type equivalents, this function returns the equivalent large
 /// data type.  If the type is not an LOB or cannot be converted, the function returns the current type.
 /// For example SqlServer defines the 'Image' LOB type, whose large type equivalent is VarBinary(MAX).
 /// </summary>
 internal abstract ProviderType GetBestLargeType(ProviderType type);
 /// <summary>
 /// Determines whether two types are in the same type family.
 /// A family is a group types that serve similar functions. For example,
 /// in SQL SmallInt and Int are part of one family.
 /// </summary>
 internal abstract bool IsSameTypeFamily(ProviderType type);
 /// <summary>
 /// Get a type that can hold the same information but belongs to a different type family.
 /// For example, to represent a SQL NChar as an integer type, we need to use the type int.
 /// (SQL smallint would not be able to contain characters with unicode >32768)
 /// </summary>
 /// <param name="toType">Type of the target type family</param>
 /// <returns>Smallest type of target type family that can hold equivalent information</returns>
 internal abstract ProviderType ChangeTypeFamilyTo(ProviderType type, ProviderType typeWithFamily);
 /// <summary>
 /// Returns the most precise type in the family of the type given.
 /// A family is a group types that serve similar functions. For example,
 /// in SQL SmallInt and Int are part of one family.
 /// </summary>
 internal abstract ProviderType MostPreciseTypeInFamily(ProviderType type);
 internal abstract ProviderType PredictTypeForUnary(SqlNodeType unaryOp, ProviderType operandType);
 /// <summary>
 /// Returns a type that can be used to hold values for both the current
 /// type and the specified type without data loss.
 /// </summary>
 internal abstract ProviderType GetBestType(ProviderType typeA, ProviderType typeB);
Ejemplo n.º 39
0
 private void FormatType(ProviderType type) {
     sb.Append(type.ToQueryString());
 }
 internal abstract void InitializeParameter(ProviderType type, System.Data.Common.DbParameter parameter, object value);
Ejemplo n.º 41
0
 internal SqlIn(Type clrType, ProviderType sqlType, SqlExpression expression, IEnumerable <SqlExpression> values, Expression sourceExpression)
     : base(SqlNodeType.In, clrType, sqlType, sourceExpression)
 {
     this.expression = expression;
     this.values     = values != null ? new List <SqlExpression>(values) : new List <SqlExpression>(0);
 }
Ejemplo n.º 42
0
 internal SqlDiscriminatorOf(SqlExpression obj, Type clrType, ProviderType sqlType, Expression sourceExpression)
     : base(SqlNodeType.DiscriminatorOf, clrType, sqlType, sourceExpression)
 {
     this.Object = obj;
 }
Ejemplo n.º 43
0
 internal SqlFunctionCall FunctionCall(Type clrType, ProviderType sqlType, string name, IEnumerable<SqlExpression> args, Expression source) {
     return new SqlFunctionCall(clrType, sqlType, name, args, source);
 }
Ejemplo n.º 44
0
 internal SqlClientParameter(Type clrType, ProviderType sqlType, LambdaExpression accessor, Expression sourceExpression) :
     base(SqlNodeType.ClientParameter, clrType, sqlType, sourceExpression)
 {
     this.accessor = accessor;
 }
 /// <summary>
 /// Compare implicit type coercion precedence.
 /// -1 means there is an implicit conversion from this->type.
 /// 0 means there is a two way implicit conversion from this->type
 /// 1 means there is an implicit conversion from type->this.
 /// </summary>
 internal abstract int ComparePrecedenceTo(ProviderType type);
Ejemplo n.º 46
0
 internal SqlExpression Value(Type clrType, ProviderType sqlType, object value, bool isClientSpecified, Expression sourceExpression) {
     if (typeof(Type).IsAssignableFrom(clrType) && value != null) {
         MetaType typeOf = this.model.GetMetaType((Type)value);
         return StaticType(typeOf, sourceExpression);
     }
     return new SqlValue(clrType, sqlType, value, isClientSpecified, sourceExpression);
 }
Ejemplo n.º 47
0
 internal SqlExpression ConvertTo(Type clrType, ProviderType sqlType, SqlExpression expr) {
     return UnaryConvert(clrType, sqlType, expr, expr.SourceExpression);
 }
Ejemplo n.º 48
0
            private static void SetSqlTypeIfSimpleExpression(SqlExpression expression, ProviderType sqlType)
            {
                SqlSimpleTypeExpression simpleExpression = expression as SqlSimpleTypeExpression;

                if (simpleExpression != null)
                {
                    simpleExpression.SetSqlType(sqlType);
                }
            }
Ejemplo n.º 49
0
 internal SqlUnary UnaryConvert(Type targetClrType, ProviderType targetSqlType, SqlExpression expression, Expression sourceExpression) {
     System.Diagnostics.Debug.Assert(!targetSqlType.IsRuntimeOnlyType, "Attempted coversion to a runtime type: from = " + expression.SqlType.ToQueryString() + "; to = " + targetSqlType.ToQueryString() + "; source = " + sourceExpression.ToString());
     return new SqlUnary(SqlNodeType.Convert, targetClrType, targetSqlType, expression, null, sourceExpression);
 }
Ejemplo n.º 50
0
 private static void SetSqlTypeIfSimpleExpression(SqlExpression expression, ProviderType sqlType)
 {
     SqlSimpleTypeExpression simpleExpression = expression as SqlSimpleTypeExpression;
     if (simpleExpression != null) {
         simpleExpression.SetSqlType(sqlType);
     }
 }
Ejemplo n.º 51
0
 internal SqlNop(Type clrType, ProviderType sqlType, Expression sourceExpression)
     : base(SqlNodeType.Nop, clrType, sqlType, sourceExpression)
 {
 }