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

ResultType() private method

private ResultType ( 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 ResultType(StorageType left, StorageType right, bool lc, bool rc, int op)
        {
            if ((left == StorageType.Guid) && (right == StorageType.Guid) && Operators.IsRelational(op))
                return left;
            if ((left == StorageType.String) && (right == StorageType.Guid) && Operators.IsRelational(op))
                return left;
            if ((left == StorageType.Guid) && (right == StorageType.String) && Operators.IsRelational(op))
                return right;

            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 && right == StorageType.Boolean)
                    return StorageType.Boolean;
                else
                    return StorageType.Empty;
            }
            if ((left == StorageType.DateTimeOffset) || (right == StorageType.DateTimeOffset))
            {
                // Rules to handle DateTimeOffset:
                // we only allow Relational operations to operate only on DTO vs DTO
                // all other operations: "exception"
                if (Operators.IsRelational(op) && left == StorageType.DateTimeOffset && right == StorageType.DateTimeOffset)
                    return StorageType.DateTimeOffset;
                return StorageType.Empty;
            }

            if ((op == Operators.Plus) && ((left == StorageType.String) || (right == StorageType.String)))
                return StorageType.String;

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

            StorageType result = GetPrecedenceType(higherPrec);

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

            // if the operation is a division the result should be at least a double

            if ((op == Operators.Divide) && IsInteger(result))
            {
                return StorageType.Double;
            }

            if (IsMixed(left, right))
            {
                // we are dealing with one signed and one unsigned type so
                // try to see if one of them is a ConstNode
                if (lc && (!rc))
                {
                    return right;
                }
                else if ((!lc) && rc)
                {
                    return left;
                }

                if (IsUnsigned(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

示例#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::ResultType