System.Data.BinaryNode.ResultSqlType C# (CSharp) Method

ResultSqlType() private method

private ResultSqlType ( StorageType left, StorageType right, bool lc, bool rc, int op ) : StorageType
left StorageType
right StorageType
lc bool
rc bool
op int
return StorageType
        internal StorageType ResultSqlType(StorageType left, StorageType right, bool lc, bool rc, int op)
        {
            int leftPrecedence = (int)GetPrecedence(left);
            if (leftPrecedence == (int)DataTypePrecedence.Error)
            {
                return StorageType.Empty;
            }

            int rightPrecedence = (int)GetPrecedence(right);
            if (rightPrecedence == (int)DataTypePrecedence.Error)
            {
                return StorageType.Empty;
            }

            if (Operators.IsLogical(op))
            {
                if ((left != StorageType.Boolean && left != StorageType.SqlBoolean) || (right != StorageType.Boolean && right != StorageType.SqlBoolean))
                    return StorageType.Empty;
                if (left == StorageType.Boolean && right == StorageType.Boolean)
                    return StorageType.Boolean;
                return StorageType.SqlBoolean;
            }

            if (op == Operators.Plus)
            {
                if ((left == StorageType.SqlString) || (right == StorageType.SqlString))
                    return StorageType.SqlString;
                if ((left == StorageType.String) || (right == StorageType.String))
                    return StorageType.String;
            }
            //SqlBinary is operable just with SqlBinary
            if ((left == StorageType.SqlBinary && right != StorageType.SqlBinary) || (left != StorageType.SqlBinary && right == StorageType.SqlBinary))
                return StorageType.Empty;
            //SqlGuid is operable just with SqlGuid
            if ((left == StorageType.SqlGuid && right != StorageType.SqlGuid) || (left != StorageType.SqlGuid && right == StorageType.SqlGuid))
                return StorageType.Empty;

            if ((leftPrecedence > (int)DataTypePrecedence.SqlDouble && rightPrecedence < (int)DataTypePrecedence.TimeSpan))
            {
                return StorageType.Empty;
            }

            if ((leftPrecedence < (int)DataTypePrecedence.TimeSpan && rightPrecedence > (int)DataTypePrecedence.SqlDouble))
            {
                return StorageType.Empty;
            }

            if (leftPrecedence > (int)DataTypePrecedence.SqlDouble)
            {
                if (op == Operators.Plus || op == Operators.Minus)
                {
                    if (left == StorageType.TimeSpan)
                        return right;
                    if (right == StorageType.TimeSpan)
                        return left;
                    return StorageType.Empty; // for plus or minus operations for  time types, one of them MUST be time span
                }

                if (!Operators.IsRelational(op))
                    return StorageType.Empty; // we just have relational operations amoung time types
                return left;
            }
            // time types finished
            // continue with numerical types, numbers

            DataTypePrecedence higherPrec = (DataTypePrecedence)Math.Max(leftPrecedence, rightPrecedence);

            StorageType result = GetPrecedenceType(higherPrec);
            // if we have at least one Sql type, the intermediate result should be Sql type
            result = GetPrecedenceType((DataTypePrecedence)SqlResultType((int)higherPrec));

            if (Operators.IsArithmetical(op))
            {
                if (result != StorageType.String && result != StorageType.Char && result != StorageType.SqlString)
                {
                    if (!IsNumericSql(left))
                        return StorageType.Empty;
                    if (!IsNumericSql(right))
                        return StorageType.Empty;
                }
            }

            // if the operation is a division the result should be at least a double
            if ((op == Operators.Divide) && IsIntegerSql(result))
            {
                return StorageType.SqlDouble;
            }

            if (result == StorageType.SqlMoney)
            {
                if ((left != StorageType.SqlMoney) && (right != StorageType.SqlMoney))
                    result = StorageType.SqlDecimal;
            }

            if (IsMixedSql(left, right))
            {
                // we are dealing with one signed and one unsigned type so
                // try to see if one of them is a ConstNode

                if (IsUnsignedSql(result))
                {
                    if (higherPrec < DataTypePrecedence.UInt64)
                        // left and right are mixed integers but with the same length
                        // so promote to the next signed type
                        result = GetPrecedenceType(higherPrec + 1);
                    else
                        throw ExprException.AmbiguousBinop(op, DataStorage.GetTypeStorage(left), DataStorage.GetTypeStorage(right));
                }
            }

            return result;
        }

Usage Example

Example #1
0
        private int Eval(BinaryNode expr, DataRow row, DataRowVersion version) {
            if (expr.op == Operators.And) {
                int lResult = Eval((BinaryNode)expr.left,row,version);
                if (lResult != 0)
                    return lResult;
                int rResult = Eval((BinaryNode)expr.right,row,version);
                if (rResult != 0)
                    return rResult;
                return 0;
            }

            long c = 0;
            object vLeft  = expr.left.Eval(row, version);
            if (expr.op != Operators.Is && expr.op != Operators.IsNot) {
                object vRight = expr.right.Eval(row, version);
                bool isLConst = (expr.left is ConstNode);
                bool isRConst = (expr.right is ConstNode);

                if ((vLeft == DBNull.Value)||(expr.left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)))
                    return -1;
                if ((vRight == DBNull.Value)||(expr.right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                    return 1;

                StorageType leftType = DataStorage.GetStorageType(vLeft.GetType());
                if (StorageType.Char == leftType) {
                    if ((isRConst)||(!expr.right.IsSqlColumn))
                        vRight = Convert.ToChar(vRight, table.FormatProvider);
                    else
                       vRight = SqlConvert.ChangeType2(vRight, StorageType.Char, typeof(char), table.FormatProvider);
                }

                StorageType rightType = DataStorage.GetStorageType(vRight.GetType());
                StorageType resultType;
                if (expr.left.IsSqlColumn || expr.right.IsSqlColumn) {
                    resultType = expr.ResultSqlType(leftType, rightType, isLConst, isRConst, expr.op);
                }
                else {
                    resultType = expr.ResultType(leftType, rightType, isLConst, isRConst, expr.op);
                }
                if (StorageType.Empty == resultType) {
                    expr.SetTypeMismatchError(expr.op, vLeft.GetType(), vRight.GetType());
                }

                // if comparing a Guid column value against a string literal
                // use InvariantCulture instead of DataTable.Locale because in the Danish related cultures
                // sorting a Guid as a string has different results than in Invariant and English related cultures.
                // This fix is restricted to DataTable.Select("GuidColumn = 'string literal'") types of queries
                NameNode namedNode = null;
                System.Globalization.CompareInfo comparer =
                    ((isLConst && !isRConst && (leftType == StorageType.String) && (rightType == StorageType.Guid) && (null != (namedNode = expr.right as NameNode)) && (namedNode.column.DataType == typeof(Guid))) ||
                     (isRConst && !isLConst && (rightType == StorageType.String) && (leftType == StorageType.Guid) && (null != (namedNode = expr.left as NameNode)) && (namedNode.column.DataType == typeof(Guid))))
                     ? System.Globalization.CultureInfo.InvariantCulture.CompareInfo : null;

                c = expr.BinaryCompare(vLeft, vRight, resultType, expr.op, comparer);
            }
            switch(expr.op) {
                case Operators.EqualTo:         c = (c == 0 ? 0 : c < 0  ? -1 :  1); break;
                case Operators.GreaterThen:     c = (c > 0  ? 0 : -1); break;
                case Operators.LessThen:        c = (c < 0  ? 0 : 1); break;
                case Operators.GreaterOrEqual:  c = (c >= 0 ? 0 : -1); break;
                case Operators.LessOrEqual:     c = (c <= 0 ? 0 : 1); break;
                case Operators.Is:              c = (vLeft == DBNull.Value ? 0 : -1); break;
                case Operators.IsNot:           c = (vLeft != DBNull.Value ? 0 : 1);  break;
                default:                        Debug.Assert(true, "Unsupported Binary Search Operator!"); break;
            }
            return (int)c;
        }
All Usage Examples Of System.Data.BinaryNode::ResultSqlType