예제 #1
0
 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;
 }
예제 #2
0
 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);
 }
        internal override SqlExpression VisitUnaryOperator(SqlUnary uo) {
            uo.Operand = this.VisitExpression(uo.Operand);
            if (uo.NodeType != SqlNodeType.Convert) {
                return uo;
            }
            ProviderType oldSqlType = uo.Operand.SqlType;
            ProviderType newSqlType = uo.SqlType;
            Type oldClrType = TypeSystem.GetNonNullableType(uo.Operand.ClrType);
            Type newClrType = TypeSystem.GetNonNullableType(uo.ClrType);

            if (newClrType == typeof(char)) {
                if (oldClrType == typeof(bool)) {
                    throw Error.ConvertToCharFromBoolNotSupported();
                }

                if (oldSqlType.IsNumeric) {
                    // numeric --> char
                    return sql.FunctionCall(uo.ClrType, "NCHAR", new SqlExpression[] { uo.Operand }, uo.SourceExpression);
                }

                if (StringConversionIsSafe(oldSqlType, newSqlType)) {
                    if (StringConversionIsNeeded(oldSqlType, newSqlType)) {
                        // set the new size to the (potentially smaller) oldSqlType.Size
                        uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null));
                    }
                } else {
                    throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString());
                }
            } else if (oldClrType == typeof(char) && (oldSqlType.IsChar || oldSqlType.IsString) && newSqlType.IsNumeric) {
                // char --> int 
                return sql.FunctionCall(newClrType, sql.TypeProvider.From(typeof(int)), "UNICODE", new SqlExpression[] { uo.Operand }, uo.SourceExpression);
            } else if (newClrType == typeof(string)) {
                if (oldClrType == typeof(double)) {
                    // use longer format if it was a double in the CLR expression
                    return ConvertDoubleToString(uo.Operand, uo.ClrType);
                } else if (oldClrType == typeof(bool)) {
                    // use 'true' or 'false' if it was a bool in the CLR expression
                    return ConvertBitToString(uo.Operand, uo.ClrType);
                } else if (StringConversionIsSafe(oldSqlType, newSqlType)) {
                    if (StringConversionIsNeeded(oldSqlType, newSqlType)) {
                        // set the new size to the (potentially smaller) oldSqlType.Size
                        uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null));
                    }
                } else {
                    throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString());
                }
            }
            return uo;
        }
예제 #4
0
        internal override SqlExpression VisitUnaryOperator(SqlUnary uo)
        {
            uo.Operand = this.VisitExpression(uo.Operand);
            if (uo.NodeType != SqlNodeType.Convert)
            {
                return(uo);
            }
            ProviderType oldSqlType = uo.Operand.SqlType;
            ProviderType newSqlType = uo.SqlType;
            Type         oldClrType = TypeSystem.GetNonNullableType(uo.Operand.ClrType);
            Type         newClrType = TypeSystem.GetNonNullableType(uo.ClrType);

            if (newClrType == typeof(char))
            {
                if (oldClrType == typeof(bool))
                {
                    throw Error.ConvertToCharFromBoolNotSupported();
                }

                if (oldSqlType.IsNumeric)
                {
                    // numeric --> char
                    return(sql.FunctionCall(uo.ClrType, "NCHAR", new SqlExpression[] { uo.Operand }, uo.SourceExpression));
                }

                if (StringConversionIsSafe(oldSqlType, newSqlType))
                {
                    if (StringConversionIsNeeded(oldSqlType, newSqlType))
                    {
                        // set the new size to the (potentially smaller) oldSqlType.Size
                        uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null));
                    }
                }
                else
                {
                    throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString());
                }
            }
            else if (oldClrType == typeof(char) && (oldSqlType.IsChar || oldSqlType.IsString) && newSqlType.IsNumeric)
            {
                // char --> int
                return(sql.FunctionCall(newClrType, sql.TypeProvider.From(typeof(int)), "UNICODE", new SqlExpression[] { uo.Operand }, uo.SourceExpression));
            }
            else if (newClrType == typeof(string))
            {
                if (oldClrType == typeof(double))
                {
                    // use longer format if it was a double in the CLR expression
                    return(ConvertDoubleToString(uo.Operand, uo.ClrType));
                }
                if (oldClrType == typeof(bool))
                {
                    // use 'true' or 'false' if it was a bool in the CLR expression
                    return(ConvertBitToString(uo.Operand, uo.ClrType));
                }
                if (StringConversionIsSafe(oldSqlType, newSqlType))
                {
                    if (StringConversionIsNeeded(oldSqlType, newSqlType))
                    {
                        // set the new size to the (potentially smaller) oldSqlType.Size
                        uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null));
                    }
                }
                else
                {
                    throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString());
                }
            }
            return(uo);
        }