UnsupportedOperator() public static method

public static UnsupportedOperator ( int op ) : Exception
op int
return Exception
Ejemplo n.º 1
0
        private object EvalUnaryOp(int op, object vl)
        {
            object value = DBNull.Value;

            if (DataExpression.IsUnknown(vl))
            {
                return(DBNull.Value);
            }

            StorageType storageType;

            switch (op)
            {
            case Operators.Noop:
                return(vl);

            case Operators.UnaryPlus:
                storageType = DataStorage.GetStorageType(vl.GetType());
                if (ExpressionNode.IsNumericSql(storageType))
                {
                    return(vl);
                }
                throw ExprException.TypeMismatch(ToString());

            case Operators.Negative:
                // the have to be better way for doing this..
                storageType = DataStorage.GetStorageType(vl.GetType());
                if (ExpressionNode.IsNumericSql(storageType))
                {
                    switch (storageType)
                    {
                    case StorageType.Byte:
                        value = -(byte)vl;
                        break;

                    case StorageType.Int16:
                        value = -(short)vl;
                        break;

                    case StorageType.Int32:
                        value = -(int)vl;
                        break;

                    case StorageType.Int64:
                        value = -(long)vl;
                        break;

                    case StorageType.Single:
                        value = -(float)vl;
                        break;

                    case StorageType.Double:
                        value = -(double)vl;
                        break;

                    case StorageType.Decimal:
                        value = -(decimal)vl;
                        break;

                    case StorageType.SqlDecimal:
                        value = -(SqlDecimal)vl;
                        break;

                    case StorageType.SqlDouble:
                        value = -(SqlDouble)vl;
                        break;

                    case StorageType.SqlSingle:
                        value = -(SqlSingle)vl;
                        break;

                    case StorageType.SqlMoney:
                        value = -(SqlMoney)vl;
                        break;

                    case StorageType.SqlInt64:
                        value = -(SqlInt64)vl;
                        break;

                    case StorageType.SqlInt32:
                        value = -(SqlInt32)vl;
                        break;

                    case StorageType.SqlInt16:
                        value = -(SqlInt16)vl;
                        break;

                    default:
                        Debug.Fail("Missing a type conversion");
                        value = DBNull.Value;
                        break;
                    }
                    return(value);
                }

                throw ExprException.TypeMismatch(ToString());

            case Operators.Not:
                if (vl is SqlBoolean)
                {
                    if (((SqlBoolean)vl).IsFalse)
                    {
                        return(SqlBoolean.True);
                    }
                    else if (((SqlBoolean)vl).IsTrue)
                    {
                        return(SqlBoolean.False);
                    }
                    throw ExprException.UnsupportedOperator(op);      // or should the result of not SQLNull  be SqlNull ?
                }
                else
                {
                    if (DataExpression.ToBoolean(vl) != false)
                    {
                        return(false);
                    }
                    return(true);
                }

            default:
                throw ExprException.UnsupportedOperator(op);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Builds expression tree for higher-precedence operator to be used as left
        ///     operand of current operator. May cause errors - always do ErrorCheck() upin return.
        /// </summary>

        private void BuildExpression(int pri)
        {
            ExpressionNode expr = null;

            Debug.Assert(pri > Operators.priStart && pri <= Operators.priMax, "Invalid priority value");

            /* For all operators of higher or same precedence (we are always
             * left-associative) */
            while (true)
            {
                Debug.Assert(_topOperator > 0, "Empty operator stack!!");
                OperatorInfo opInfo = _ops[_topOperator - 1];

                if (opInfo._priority < pri)
                {
                    goto end_loop;
                }

                Debug.Assert(opInfo._priority >= pri, "Invalid prioriry value");
                _topOperator--;

                ExpressionNode nodeLeft;
                ExpressionNode nodeRight;
                switch (opInfo._type)
                {
                case Nodes.Binop:
                {
                    // get right, left operands. Bind them.

                    nodeRight = NodePop();
                    nodeLeft  = NodePop();

                    /* This is the place to do type and other checks */

                    switch (opInfo._op)
                    {
                    case Operators.Between:
                    case Operators.BetweenAnd:
                    case Operators.BitwiseAnd:
                    case Operators.BitwiseOr:
                    case Operators.BitwiseXor:
                    case Operators.BitwiseNot:
                        throw ExprException.UnsupportedOperator(opInfo._op);

                    case Operators.Is:
                    case Operators.Or:
                    case Operators.And:
                    case Operators.EqualTo:
                    case Operators.NotEqual:
                    case Operators.Like:
                    case Operators.LessThen:
                    case Operators.LessOrEqual:
                    case Operators.GreaterThen:
                    case Operators.GreaterOrEqual:
                    case Operators.In:
                        break;

                    default:
                        Debug.Assert(opInfo._op == Operators.Plus ||
                                     opInfo._op == Operators.Minus ||
                                     opInfo._op == Operators.Multiply ||
                                     opInfo._op == Operators.Divide ||
                                     opInfo._op == Operators.Modulo,
                                     "Invalud Binary operation");

                        break;
                    }
                    Debug.Assert(nodeLeft != null, "Invalid left operand");
                    Debug.Assert(nodeRight != null, "Invalid right operand");

                    if (opInfo._op == Operators.Like)
                    {
                        expr = new LikeNode(_table, opInfo._op, nodeLeft, nodeRight);
                    }
                    else
                    {
                        expr = new BinaryNode(_table, opInfo._op, nodeLeft, nodeRight);
                    }

                    break;
                }

                case Nodes.Unop:
                    /* Unary operator: Pop and bind right op. */
                    nodeLeft  = null;
                    nodeRight = NodePop();

                    /* Check for special cases */
                    switch (opInfo._op)
                    {
                    case Operators.Not:
                        break;

                    case Operators.BitwiseNot:
                        throw ExprException.UnsupportedOperator(opInfo._op);

                    case Operators.Negative:
                        break;
                    }

                    Debug.Assert(nodeLeft == null, "Invalid left operand");
                    Debug.Assert(nodeRight != null, "Invalid right operand");

                    expr = new UnaryNode(_table, opInfo._op, nodeRight);
                    break;

                case Nodes.Zop:
                    /* Intrinsic constant: just create node. */
                    expr = new ZeroOpNode(opInfo._op);
                    break;

                default:
                    Debug.Fail("Unhandled operator type");
                    goto end_loop;
                }
                Debug.Assert(expr != null, "Failed to create expression");

                NodePush(expr);
                // countinue while loop;
            }
end_loop:
            ;
        }
Ejemplo n.º 3
0
        private void BuildExpression(int pri)
        {
            OperatorInfo   info;
            ExpressionNode node = null;

Label_0002:
            info = this.ops[this.topOperator - 1];
            if (info.priority >= pri)
            {
                ExpressionNode node2;
                ExpressionNode node3;
                this.topOperator--;
                switch (info.type)
                {
                case Nodes.Unop:
                    node3 = null;
                    node2 = this.NodePop();
                    switch (info.op)
                    {
                    case 0x19:
                        throw ExprException.UnsupportedOperator(info.op);
                    }
                    node = new UnaryNode(this._table, info.op, node2);
                    goto Label_016C;

                case Nodes.UnopSpec:
                case Nodes.BinopSpec:
                    return;

                case Nodes.Binop:
                    node2 = this.NodePop();
                    node3 = this.NodePop();
                    switch (info.op)
                    {
                    case 4:
                    case 6:
                    case 0x16:
                    case 0x17:
                    case 0x18:
                    case 0x19:
                        throw ExprException.UnsupportedOperator(info.op);
                    }
                    if (info.op == 14)
                    {
                        node = new LikeNode(this._table, info.op, node3, node2);
                    }
                    else
                    {
                        node = new BinaryNode(this._table, info.op, node3, node2);
                    }
                    goto Label_016C;

                case Nodes.Zop:
                    node = new ZeroOpNode(info.op);
                    goto Label_016C;
                }
            }
            return;

Label_016C:
            this.NodePush(node);
            goto Label_0002;
        }
Ejemplo n.º 4
0
        private object EvalUnaryOp(int op, object vl)
        {
            object value = DBNull.Value;

            if (DataExpression.IsUnknown(vl))
            {
                return(DBNull.Value);
            }

            switch (op)
            {
            case Operators.Noop:
                return(vl);

            case Operators.UnaryPlus:
                if (ExpressionNode.IsNumeric(vl.GetType()))
                {
                    return(vl);
                }
                throw ExprException.TypeMismatch(this.ToString());

            case Operators.Negative:
                // the have to be better way for doing this..
                if (ExpressionNode.IsNumeric(vl.GetType()))
                {
                    if (vl is byte)
                    {
                        value = -(Byte)vl;
                    }
                    else if (vl is Int16)
                    {
                        value = -(Int16)vl;
                    }
                    else if (vl is Int32)
                    {
                        value = -(Int32)vl;
                    }
                    else if (vl is Int64)
                    {
                        value = -(Int64)vl;
                    }
                    else if (vl is Single)
                    {
                        value = -(Single)vl;
                    }
                    else if (vl is Double)
                    {
                        value = -(Double)vl;
                    }
                    else if (vl is Decimal)
                    {
                        value = -(Decimal)vl;
                    }
                    else
                    {
                        Debug.Assert(false, "Missing a type conversion " + vl.GetType().FullName);
                        value = DBNull.Value;
                    }
                    return(value);
                }

                throw ExprException.TypeMismatch(this.ToString());

            case Operators.Not:
                if (DataExpression.ToBoolean(vl) != false)
                {
                    return(false);
                }
                return(true);

            default:
                throw ExprException.UnsupportedOperator(op);
            }
        }
Ejemplo n.º 5
0
        private object EvalBinaryOp(int op, ExpressionNode left, ExpressionNode right, DataRow row, DataRowVersion version, int[] recordNos)
        {
            object vLeft;
            object vRight;
            bool   isLConst, isRConst;
            Type   result;

            /*
             * special case for OR and AND operators: we don't want to evaluate
             * both right and left operands, because we can shortcut :
             *  for OR  operator If one of the operands is true the result is true
             *  for AND operator If one of rhe operands is flase the result is false
             * CONSIDER : in the shortcut case do we want to type-check the other operand?
             */

            if (op != Operators.Or && op != Operators.And && op != Operators.In && op != Operators.Is && op != Operators.IsNot)
            {
                vLeft    = BinaryNode.Eval(left, row, version, recordNos);
                vRight   = BinaryNode.Eval(right, row, version, recordNos);
                isLConst = (left is ConstNode);
                isRConst = (right is ConstNode);

                //    special case of handling NULLS, currently only OR operator can work with NULLS
                if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                {
                    return(DBNull.Value);
                }

                result = ResultType(vLeft.GetType(), vRight.GetType(), isLConst, isRConst, op);

                if (result == null)
                {
                    SetTypeMismatchError(op, vLeft.GetType(), vRight.GetType());
                }

#if DEBUG
                if (CompModSwitches.BinaryNode.TraceVerbose)
                {
                    Debug.WriteLine("Result of the operator: " + result.Name);
                }
#endif
            }
            else
            {
                vLeft  = vRight = DBNull.Value;
                result = null;
            }

            object value        = DBNull.Value;
            bool   typeMismatch = false;

            try {
                switch (op)
                {
                case Operators.Plus:
                    if (result == typeof(Byte))
                    {
                        value = Convert.ToByte(Convert.ToByte(vLeft) + Convert.ToByte(vRight));
                    }
                    else if (result == typeof(SByte))
                    {
                        value = Convert.ToSByte(Convert.ToSByte(vLeft) + Convert.ToSByte(vRight));
                    }
                    else if (result == typeof(Int16))
                    {
                        value = Convert.ToInt16(Convert.ToInt16(vLeft) + Convert.ToInt16(vRight));
                    }
                    else if (result == typeof(UInt16))
                    {
                        value = Convert.ToUInt16(Convert.ToUInt16(vLeft) + Convert.ToUInt16(vRight));
                    }
                    else if (result == typeof(Int32))
                    {
                        Int32 a = Convert.ToInt32(vLeft);
                        Int32 b = Convert.ToInt32(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(UInt32))
                    {
                        UInt32 a = Convert.ToUInt32(vLeft);
                        UInt32 b = Convert.ToUInt32(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(UInt64))
                    {
                        UInt64 a = Convert.ToUInt64(vLeft);
                        UInt64 b = Convert.ToUInt64(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(Int64))
                    {
                        Int64 a = Convert.ToInt64(vLeft);
                        Int64 b = Convert.ToInt64(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(Decimal))
                    {
                        Decimal a = Convert.ToDecimal(vLeft);
                        Decimal b = Convert.ToDecimal(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(Single))
                    {
                        Single a = Convert.ToSingle(vLeft);
                        Single b = Convert.ToSingle(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(double))
                    {
                        Double a = Convert.ToDouble(vLeft);
                        Double b = Convert.ToDouble(vRight);
                        checked { value = a + b; }
                    }
                    else if (result == typeof(string) || result == typeof(char))
                    {
                        value = Convert.ToString(vLeft) + Convert.ToString(vRight);
                    }
                    else if (result == typeof(DateTime))
                    {
                        // one of the operands should be a DateTime, and an other a TimeSpan

                        if (vLeft is TimeSpan && vRight is DateTime)
                        {
                            value = (DateTime)vRight + (TimeSpan)vLeft;
                        }
                        else if (vLeft is DateTime && vRight is TimeSpan)
                        {
                            value = (DateTime)vLeft + (TimeSpan)vRight;
                        }
                        else
                        {
                            typeMismatch = true;
                        }
                    }
                    else if (result == typeof(TimeSpan))
                    {
                        value = (TimeSpan)vLeft + (TimeSpan)vRight;
                    }
                    else
                    {
                        typeMismatch = true;
                    }
                    break;

                case Operators.Minus:
                    if (result == typeof(Byte))
                    {
                        value = Convert.ToByte(Convert.ToByte(vLeft) - Convert.ToByte(vRight));
                    }
                    else if (result == typeof(SByte))
                    {
                        value = Convert.ToSByte(Convert.ToSByte(vLeft) - Convert.ToSByte(vRight));
                    }
                    else if (result == typeof(Int16))
                    {
                        value = Convert.ToInt16(Convert.ToInt16(vLeft) - Convert.ToInt16(vRight));
                    }
                    else if (result == typeof(UInt16))
                    {
                        value = Convert.ToUInt16(Convert.ToUInt16(vLeft) - Convert.ToUInt16(vRight));
                    }
                    else if (result == typeof(Int32))
                    {
                        Int32 a = Convert.ToInt32(vLeft);
                        Int32 b = Convert.ToInt32(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(UInt32))
                    {
                        UInt32 a = Convert.ToUInt32(vLeft);
                        UInt32 b = Convert.ToUInt32(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(Int64))
                    {
                        Int64 a = Convert.ToInt64(vLeft);
                        Int64 b = Convert.ToInt64(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(UInt64))
                    {
                        UInt64 a = Convert.ToUInt64(vLeft);
                        UInt64 b = Convert.ToUInt64(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(Decimal))
                    {
                        Decimal a = Convert.ToDecimal(vLeft);
                        Decimal b = Convert.ToDecimal(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(Single))
                    {
                        Single a = Convert.ToSingle(vLeft);
                        Single b = Convert.ToSingle(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(double))
                    {
                        Double a = Convert.ToDouble(vLeft);
                        Double b = Convert.ToDouble(vRight);
                        checked { value = a - b; }
                    }
                    else if (result == typeof(DateTime))
                    {
                        value = (DateTime)vLeft - (TimeSpan)vRight;
                    }
                    else if (result == typeof(TimeSpan))
                    {
                        if (vLeft is DateTime)
                        {
                            value = (DateTime)vLeft - (DateTime)vRight;
                        }
                        else
                        {
                            value = (TimeSpan)vLeft - (TimeSpan)vRight;
                        }
                    }
                    else
                    {
                        typeMismatch = true;
                    }
                    break;

                case Operators.Multiply:
                    if (result == typeof(Byte))
                    {
                        value = Convert.ToByte(Convert.ToByte(vLeft) * Convert.ToByte(vRight));
                    }
                    else if (result == typeof(SByte))
                    {
                        value = Convert.ToSByte(Convert.ToSByte(vLeft) * Convert.ToSByte(vRight));
                    }
                    else if (result == typeof(Int16))
                    {
                        value = Convert.ToInt16(Convert.ToInt16(vLeft) * Convert.ToInt16(vRight));
                    }
                    else if (result == typeof(UInt16))
                    {
                        value = Convert.ToUInt16(Convert.ToUInt16(vLeft) * Convert.ToUInt16(vRight));
                    }
                    else if (result == typeof(Int32))
                    {
                        Int32 a = Convert.ToInt32(vLeft);
                        Int32 b = Convert.ToInt32(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(UInt32))
                    {
                        UInt32 a = Convert.ToUInt32(vLeft);
                        UInt32 b = Convert.ToUInt32(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(Int64))
                    {
                        Int64 a = Convert.ToInt64(vLeft);
                        Int64 b = Convert.ToInt64(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(UInt64))
                    {
                        UInt64 a = Convert.ToUInt64(vLeft);
                        UInt64 b = Convert.ToUInt64(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(Decimal))
                    {
                        Decimal a = Convert.ToDecimal(vLeft);
                        Decimal b = Convert.ToDecimal(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(Single))
                    {
                        Single a = Convert.ToSingle(vLeft);
                        Single b = Convert.ToSingle(vRight);
                        checked { value = a * b; }
                    }
                    else if (result == typeof(double))
                    {
                        Double a = Convert.ToDouble(vLeft);
                        Double b = Convert.ToDouble(vRight);
                        checked { value = a * b; }
                    }
                    else
                    {
                        typeMismatch = true;
                    }
                    break;

                case Operators.Divide:
                    if (result == typeof(Byte))
                    {
                        value = Convert.ToByte(Convert.ToByte(vLeft) / Convert.ToByte(vRight));
                    }
                    else if (result == typeof(SByte))
                    {
                        value = Convert.ToSByte(Convert.ToSByte(vLeft) / Convert.ToSByte(vRight));
                    }
                    else if (result == typeof(Int16))
                    {
                        value = Convert.ToInt16(Convert.ToInt16(vLeft) / Convert.ToInt16(vRight));
                    }
                    else if (result == typeof(UInt16))
                    {
                        value = Convert.ToUInt16(Convert.ToUInt16(vLeft) / Convert.ToUInt16(vRight));
                    }
                    else if (result == typeof(Int32))
                    {
                        Int32 a = Convert.ToInt32(vLeft);
                        Int32 b = Convert.ToInt32(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(UInt32))
                    {
                        UInt32 a = Convert.ToUInt32(vLeft);
                        UInt32 b = Convert.ToUInt32(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(UInt64))
                    {
                        UInt64 a = Convert.ToUInt64(vLeft);
                        UInt64 b = Convert.ToUInt64(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(Int64))
                    {
                        Int64 a = Convert.ToInt64(vLeft);
                        Int64 b = Convert.ToInt64(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(Decimal))
                    {
                        Decimal a = Convert.ToDecimal(vLeft);
                        Decimal b = Convert.ToDecimal(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(Single))
                    {
                        Single a = Convert.ToSingle(vLeft);
                        Single b = Convert.ToSingle(vRight);
                        checked { value = a / b; }
                    }
                    else if (result == typeof(double))
                    {
                        Double a = Convert.ToDouble(vLeft);
                        Double b = Convert.ToDouble(vRight);
                        checked { value = a / b; }
                    }
                    else
                    {
                        typeMismatch = true;
                    }
                    break;

                case Operators.EqualTo:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 == Compare(vLeft, vRight, result, Operators.EqualTo));

                case Operators.GreaterThen:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 < Compare(vLeft, vRight, result, op));

                case Operators.LessThen:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 > Compare(vLeft, vRight, result, op));

                case Operators.GreaterOrEqual:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 <= Compare(vLeft, vRight, result, op));

                case Operators.LessOrEqual:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 >= Compare(vLeft, vRight, result, op));

                case Operators.NotEqual:
                    if ((vLeft == DBNull.Value) || (vRight == DBNull.Value))
                    {
                        return(DBNull.Value);
                    }
                    return(0 != Compare(vLeft, vRight, result, op));

                case Operators.Is:
                    vLeft = BinaryNode.Eval(left, row, version, recordNos);
                    if (vLeft == DBNull.Value)
                    {
                        return(true);
                    }
                    return(false);

                case Operators.IsNot:
                    vLeft = BinaryNode.Eval(left, row, version, recordNos);
                    if (vLeft == DBNull.Value)
                    {
                        return(false);
                    }
                    return(true);

                case Operators.And:
                    /*
                     * special case evaluating of the AND operator: we don't want to evaluate
                     * both right and left operands, because we can shortcut :
                     *  If one of the operands is flase the result is false
                     * CONSIDER : in the shortcut case do we want to type-check the other operand?
                     */

                    vLeft = BinaryNode.Eval(left, row, version, recordNos);

                    if (vLeft == DBNull.Value)
                    {
                        return(DBNull.Value);
                    }

                    if (!(vLeft is bool))
                    {
                        vRight       = BinaryNode.Eval(right, row, version, recordNos);
                        typeMismatch = true;
                        break;
                    }

                    if ((bool)vLeft == false)
                    {
                        value = false;
                        break;
                    }

                    vRight = BinaryNode.Eval(right, row, version, recordNos);

                    if (vRight == DBNull.Value)
                    {
                        return(DBNull.Value);
                    }

                    if (!(vRight is bool))
                    {
                        typeMismatch = true;
                        break;
                    }

                    value = (bool)vRight;
                    break;

                case Operators.Or:
                    /*
                     * special case evaluating the OR operator: we don't want to evaluate
                     * both right and left operands, because we can shortcut :
                     *  If one of the operands is true the result is true
                     * CONSIDER : in the shortcut case do we want to type-check the other operand?
                     */
                    vLeft = BinaryNode.Eval(left, row, version, recordNos);
                    if (vLeft != DBNull.Value)
                    {
                        if (!(vLeft is bool))
                        {
                            vRight       = BinaryNode.Eval(right, row, version, recordNos);
                            typeMismatch = true;
                            break;
                        }

                        if ((bool)vLeft == true)
                        {
                            value = true;
                            break;
                        }
                    }

                    vRight = BinaryNode.Eval(right, row, version, recordNos);
                    if (vRight == DBNull.Value)
                    {
                        return(vLeft);
                    }

                    if (vLeft == DBNull.Value)
                    {
                        return(vRight);
                    }

                    if (!(vRight is bool))
                    {
                        typeMismatch = true;
                        break;
                    }

                    value = (bool)vRight;
                    break;

                case Operators.Modulo:
                    if (ExpressionNode.IsInteger(result))
                    {
                        if (result == typeof(UInt64))
                        {
                            value = Convert.ToUInt64(vLeft) % Convert.ToUInt64(vRight);
                        }
                        else
                        {
                            value = Convert.ToInt64(vLeft) % Convert.ToInt64(vRight);
                            value = Convert.ChangeType(value, result);
                        }
                    }
                    else
                    {
                        typeMismatch = true;
                    }
                    break;

                case Operators.In:
                    /*
                     * special case evaluating of the IN operator: the right have to be IN function node
                     */

#if DEBUG
                    if (CompModSwitches.BinaryNode.TraceVerbose)
                    {
                        Debug.WriteLine("Evaluating IN operator..");
                    }
#endif

                    if (!(right is FunctionNode))
                    {
                        // this is more like an Assert: should never happens, so we do not care about "nice" Exseptions
                        throw ExprException.InWithoutParentheses();
                    }

                    vLeft = BinaryNode.Eval(left, row, version, recordNos);

                    if (vLeft == DBNull.Value)
                    {
                        return(DBNull.Value);
                    }

                    /* validate IN parameters : must all be constant expressions */

                    value = false;

                    FunctionNode into = (FunctionNode)right;

                    for (int i = 0; i < into.argumentCount; i++)
                    {
                        vRight = into.arguments[i].Eval();

#if DEBUG
                        if (CompModSwitches.BinaryNode.TraceVerbose)
                        {
                            Debug.WriteLine("Evaluate IN parameter " + into.arguments[i].ToString() + " = " + vRight.ToString());
                        }
#endif

                        if (vRight == DBNull.Value)
                        {
                            continue;
                        }
                        Debug.Assert((vLeft != DBNull.Value) && (vRight != DBNull.Value), "Imposible..");

                        result = vLeft.GetType();

                        if (0 == Compare(vLeft, vRight, result, Operators.EqualTo))
                        {
                            value = true;
                            break;
                        }
                    }
                    break;

                default:
#if DEBUG
                    if (CompModSwitches.BinaryNode.TraceVerbose)
                    {
                        Debug.WriteLine("NYI : " + Operators.ToString(op));
                    }
#endif
                    throw ExprException.UnsupportedOperator(op);
                }
            }
            catch (OverflowException) {
                throw ExprException.Overflow(result);
            }
            if (typeMismatch)
            {
                SetTypeMismatchError(op, vLeft.GetType(), vRight.GetType());
            }

            return(value);
        }
        private object EvalUnaryOp(int op, object vl)
        {
            if (!DataExpression.IsUnknown(vl))
            {
                switch (op)
                {
                case 0:
                    return(vl);

                case 1:
                {
                    StorageType storageType = DataStorage.GetStorageType(vl.GetType());
                    if (!ExpressionNode.IsNumericSql(storageType))
                    {
                        throw ExprException.TypeMismatch(this.ToString());
                    }
                    switch (storageType)
                    {
                    case StorageType.Byte:
                        return((int)-((byte)vl));

                    case StorageType.Int16:
                        return((int)-((short)vl));

                    case StorageType.Int32:
                        return(-((int)vl));

                    case StorageType.Int64:
                        return(-((long)vl));

                    case StorageType.Single:
                        return(-((float)vl));

                    case StorageType.Double:
                        return(-((double)vl));

                    case StorageType.Decimal:
                        return(-((decimal)vl));

                    case StorageType.SqlDecimal:
                        return(-((SqlDecimal)vl));

                    case StorageType.SqlDouble:
                        return(-((SqlDouble)vl));

                    case StorageType.SqlInt16:
                        return(-((SqlInt16)vl));

                    case StorageType.SqlInt32:
                        return(-((SqlInt32)vl));

                    case StorageType.SqlInt64:
                        return(-((SqlInt64)vl));

                    case StorageType.SqlMoney:
                        return(-((SqlMoney)vl));

                    case StorageType.SqlSingle:
                        return(-((SqlSingle)vl));
                    }
                    break;
                }

                case 2:
                    if (!ExpressionNode.IsNumericSql(DataStorage.GetStorageType(vl.GetType())))
                    {
                        throw ExprException.TypeMismatch(this.ToString());
                    }
                    return(vl);

                case 3:
                {
                    if (!(vl is SqlBoolean))
                    {
                        if (DataExpression.ToBoolean(vl))
                        {
                            return(false);
                        }
                        return(true);
                    }
                    SqlBoolean flag2 = (SqlBoolean)vl;
                    if (!flag2.IsFalse)
                    {
                        SqlBoolean flag = (SqlBoolean)vl;
                        if (!flag.IsTrue)
                        {
                            throw ExprException.UnsupportedOperator(op);
                        }
                        return(SqlBoolean.False);
                    }
                    return(SqlBoolean.True);
                }

                default:
                    throw ExprException.UnsupportedOperator(op);
                }
            }
            return(DBNull.Value);
        }