Exemple #1
0
 public static String FormatCriteria(String fieldName, Object fieldValue,
     Operators eO, Type sysType)
 {
     return FormatCriteria(fieldName, fieldValue, eO, "", sysType, ConnectionLibrary.SQlClient);
 }
 /// <summary>
 /// 根据枚举值返回操作符
 /// </summary>
 /// <param name="op">枚举值</param>
 /// <returns></returns>
 public static string GetOperator(Operators op)
 {
     switch(op)
     {
         case Operators.gt:
             {
                 return ">";
             }
         case Operators.lt:
             {
                 return "<";
             }
         case Operators.eq:
             {
                 return "=";
             }
         case Operators.le:
             {
                 return "<=";
             }
         case Operators.ge:
             {
                 return ">=";
             }
         case Operators.ne:
             {
                 return "!=";
             }
         default:
             {
                 return "";
             }
     }
 }
Exemple #3
0
        public static String FormatCriteria(String fieldName, Object fieldValue, Operators eO, String tableName, Type sysType, ConnectionLibrary eCl)
        {
            String criteria = String.Empty;
            String value;

            String strOperator = AryOperator[Convert.ToInt32(eO)];

            try
            {
                if (fieldName.Trim().Length > 0 && fieldValue != null)
                {
                    if (eCl == ConnectionLibrary.SQlClient)
                    {
                        if (sysType == typeof(String))
                        {
                            value = fieldValue.ToString();
                            value = value.Replace("'", "''");
                            criteria = fieldName + strOperator + "'" + value + "'";

                        }
                        else if (sysType == typeof(DateTime))
                        {
                            value = fieldValue.ToString();
                            criteria = fieldName + strOperator + "'" + value + "'";
                        }
                        else if (sysType == typeof(Int16) || sysType == typeof(Int32)
                            || sysType == typeof(Int64) || sysType == typeof(Decimal))
                        {

                            value = fieldValue.ToString();
                            criteria = fieldName + strOperator + value;

                        }
                        else if (sysType == typeof(DBNull))
                        {

                            value = "Null";
                            if (eO == Operators.Not)
                            {
                                criteria = fieldName + " is not " + value;
                            }
                            else
                            {
                                criteria = fieldName + " is " + value;
                            }
                        }

                    }

                    if (tableName.Trim().Length > 0)
                    {
                        criteria = tableName + "." + criteria;
                    }
                }
                else
                {
                    if (fieldName.Trim().Length > 0)
                    {
                        throw new Exception("Field name is blank.");
                    }
                    if (fieldValue == null)
                    {
                        throw new Exception("Field value is Null.");
                    }
                }
                return criteria;
            }
            catch (Exception ex)
            {
                throw (ex);
            }
        }
Exemple #4
0
 public static String FormatCriteria(String fieldName, Object fieldValue,
     Operators eO, String tablename)
 {
     return FormatCriteria(fieldName, fieldValue, eO, tablename, fieldValue.GetType(), ConnectionLibrary.SQlClient);
 }
        // CONSIDER: configure the scanner : local info

        internal ExpressionNode Parse()
        {
            // free all nodes
            _expression = null;

            StartScan();

            int          cParens = 0;
            OperatorInfo opInfo;

            while (_token != Tokens.EOS)
            {
loop:
                Scan();

                switch (_token)
                {
                case Tokens.EOS:
                    // End of string: must be operand; force out expression;
                    // check for bomb; check nothing left on stack.

                    if (_prevOperand == Empty)
                    {
                        if (_topNode == 0)
                        {
                            // we have an empty expression
                            break;
                        }
                        // set error missing operator
                        // read the last operator info
                        opInfo = _ops[_topOperator - 1];

                        throw ExprException.MissingOperand(opInfo);
                    }
                    // collect all nodes
                    BuildExpression(Operators.PriLow);
                    if (_topOperator != 1)
                    {
                        throw ExprException.MissingRightParen();
                    }
                    break;

                case Tokens.Name:
                case Tokens.Parent:
                case Tokens.Numeric:
                case Tokens.Decimal:
                case Tokens.Float:
                case Tokens.StringConst:
                case Tokens.Date:
                    ExpressionNode?node = null;
                    string?        str;

                    /* Constants and identifiers: create leaf node */

                    if (_prevOperand != Empty)
                    {
                        // set error missing operator
                        throw ExprException.MissingOperator(new string(_text, _start, _pos - _start));
                    }

                    if (_topOperator > 0)
                    {
                        // special check for IN without parentheses

                        opInfo = _ops[_topOperator - 1];

                        if (opInfo._type == Nodes.Binop && opInfo._op == Operators.In && _token != Tokens.Parent)
                        {
                            throw ExprException.InWithoutParentheses();
                        }
                    }

                    _prevOperand = Scalar;

                    switch (_token)
                    {
                    case Tokens.Parent:
                        string?relname;
                        string colname;

                        // parsing Parent[(relation_name)].column_name)
                        try
                        {
                            // expecting an '(' or '.'
                            Scan();
                            if (_token == Tokens.LeftParen)
                            {
                                //read the relation name
                                ScanToken(Tokens.Name);
                                relname = NameNode.ParseName(_text, _start, _pos);
                                ScanToken(Tokens.RightParen);
                                ScanToken(Tokens.Dot);
                            }
                            else
                            {
                                relname = null;
                                CheckToken(Tokens.Dot);
                            }
                        }
                        catch (Exception e) when(Common.ADP.IsCatchableExceptionType(e))
                        {
                            throw ExprException.LookupArgument();
                        }

                        ScanToken(Tokens.Name);
                        colname = NameNode.ParseName(_text, _start, _pos);

                        node = new LookupNode(_table, colname, relname);

                        break;

                    case Tokens.Name:
                        /* Qualify name now for nice error checking */


                        /* Create tree element -                */
                        // CONSIDER: Check for reserved proc names here
                        node = new NameNode(_table, _text, _start, _pos);

                        break;

                    case Tokens.Numeric:
                        str  = new string(_text, _start, _pos - _start);
                        node = new ConstNode(_table, ValueType.Numeric, str);
                        break;

                    case Tokens.Decimal:
                        str  = new string(_text, _start, _pos - _start);
                        node = new ConstNode(_table, ValueType.Decimal, str);
                        break;

                    case Tokens.Float:
                        str  = new string(_text, _start, _pos - _start);
                        node = new ConstNode(_table, ValueType.Float, str);
                        break;

                    case Tokens.StringConst:
                        Debug.Assert(_text[_start] == '\'' && _text[_pos - 1] == '\'', "The expression contains an invalid string constant");
                        Debug.Assert(_pos - _start > 1, "The expression contains an invalid string constant");
                        // Store string without quotes..
                        str  = new string(_text, _start + 1, _pos - _start - 2);
                        node = new ConstNode(_table, ValueType.Str, str);
                        break;

                    case Tokens.Date:
                        Debug.Assert(_text[_start] == '#' && _text[_pos - 1] == '#', "The expression contains invalid date constant.");
                        Debug.Assert(_pos - _start > 2, "The expression contains invalid date constant '{0}'.");
                        // Store date without delimiters(#s)..
                        str  = new string(_text, _start + 1, _pos - _start - 2);
                        node = new ConstNode(_table, ValueType.Date, str);
                        break;

                    default:
                        Debug.Fail("unhandled token");
                        break;
                    }

                    NodePush(node);
                    goto loop;

                case Tokens.LeftParen:
                    cParens++;
                    if (_prevOperand == Empty)
                    {
                        // Check for ( following IN/IFF. if not, we have a normal (.
                        // Peek: take a look at the operators stack

                        Debug.Assert(_topOperator > 0, "Empty operator stack!!");
                        opInfo = _ops[_topOperator - 1];

                        if (opInfo._type == Nodes.Binop && opInfo._op == Operators.In)
                        {
                            /* IN - handle as procedure call */

                            node = new FunctionNode(_table, "In");
                            NodePush(node);
                            /* Push operator decriptor */
                            _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.PriParen);
                        }
                        else
                        {      /* Normal ( */
                            /* Push operator decriptor */
                            _ops[_topOperator++] = new OperatorInfo(Nodes.Paren, Operators.Noop, Operators.PriParen);
                        }
                    }
                    else
                    {
                        // This is a procedure call or () qualification
                        // Force out any dot qualifiers; check for bomb

                        BuildExpression(Operators.PriProc);
                        _prevOperand = Empty;
                        ExpressionNode?nodebefore = NodePeek();

                        if (nodebefore == null || nodebefore.GetType() != typeof(NameNode))
                        {
                            // this is more like an assert, so we not care about "nice" exception text..
                            throw ExprException.SyntaxError();
                        }

                        /* Get the proc name */
                        NameNode name = (NameNode)NodePop();

                        // Make sure that we can bind the name as a Function
                        // then get the argument count and types, and parse arguments..

                        node = new FunctionNode(_table, name._name);

                        // check to see if this is an aggregate function
                        Aggregate agg = (Aggregate)(int)((FunctionNode)node).Aggregate;
                        if (agg != Aggregate.None)
                        {
                            node = ParseAggregateArgument((FunctionId)(int)agg);
                            NodePush(node);
                            _prevOperand = Expr;
                            goto loop;
                        }

                        NodePush(node);
                        _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.PriParen);
                    }
                    goto loop;

                case Tokens.RightParen:
                {
                    /* Right parentheses: Build expression if we have an operand. */
                    if (_prevOperand != Empty)
                    {
                        BuildExpression(Operators.PriLow);
                    }

                    /* We must have Tokens.LeftParen on stack. If no operand, must be procedure call. */
                    if (_topOperator <= 1)
                    {
                        // set error, syntax: too many right parens..
                        throw ExprException.TooManyRightParentheses();
                    }

                    Debug.Assert(_topOperator > 1, "melformed operator stack.");
                    _topOperator--;
                    opInfo = _ops[_topOperator];

                    if (_prevOperand == Empty && opInfo._type != Nodes.Call)
                    {
                        // set error, syntax: missing operand.
                        throw ExprException.MissingOperand(opInfo);
                    }

                    Debug.Assert(opInfo._priority == Operators.PriParen, "melformed operator stack.");

                    if (opInfo._type == Nodes.Call)
                    {
                        /* add argument to the function call. */

                        if (_prevOperand != Empty)
                        {
                            // read last function argument
                            ExpressionNode argument = NodePop();

                            /* Get the procedure name and append argument */
                            Debug.Assert(_topNode > 0 && NodePeek() !.GetType() == typeof(FunctionNode), "The function node should be created on '('");

                            FunctionNode func = (FunctionNode)NodePop();
                            func.AddArgument(argument);
                            func.Check();
                            NodePush(func);
                        }
                    }
                    else
                    {
                        /* Normal parentheses: create tree node */
                        // Construct & Put the Nodes.Paren node on node stack
                        node = NodePop();
                        node = new UnaryNode(_table, Operators.Noop, node);
                        NodePush(node);
                    }

                    _prevOperand = Expr;
                    cParens--;
                    goto loop;
                }

                case Tokens.ListSeparator:
                {
                    /* Comma encountered: Must be operand; force out subexpression */

                    if (_prevOperand == Empty)
                    {
                        throw ExprException.MissingOperandBefore(",");
                    }

                    /* We are be in a procedure call */

                    /* build next argument */
                    BuildExpression(Operators.PriLow);

                    opInfo = _ops[_topOperator - 1];

                    if (opInfo._type != Nodes.Call)
                    {
                        throw ExprException.SyntaxError();
                    }

                    ExpressionNode argument2 = NodePop();

                    /* Get the procedure name */

                    FunctionNode func = (FunctionNode)NodePop();

                    func.AddArgument(argument2);

                    NodePush(func);

                    _prevOperand = Empty;

                    goto loop;
                }

                case Tokens.BinaryOp:
                    if (_prevOperand == Empty)
                    {
                        /* Check for unary plus/minus */
                        if (_op == Operators.Plus)
                        {
                            _op = Operators.UnaryPlus;
                            // fall through to UnaryOperator;
                        }
                        else if (_op == Operators.Minus)
                        {
                            /* Unary minus */
                            _op = Operators.Negative;
                            // fall through to UnaryOperator;
                        }
                        else
                        {
                            // Error missing operand:
                            throw ExprException.MissingOperandBefore(Operators.ToString(_op));
                        }
                    }
                    else
                    {
                        _prevOperand = Empty;

                        /* CNSIDER: If we are going to support BETWEEN Translate AND to special BetweenAnd if it is. */

                        /* Force out to appropriate precedence; push operator. */

                        BuildExpression(Operators.Priority(_op));

                        // PushOperator descriptor
                        _ops[_topOperator++] = new OperatorInfo(Nodes.Binop, _op, Operators.Priority(_op));
                        goto loop;
                    }

                    goto
                case Tokens.UnaryOp;     // fall through to UnaryOperator;

                case Tokens.UnaryOp:
                    /* Must be no operand. Push it. */
                    _ops[_topOperator++] = new OperatorInfo(Nodes.Unop, _op, Operators.Priority(_op));
                    goto loop;

                case Tokens.ZeroOp:
                    // check the we have operator on the stack
                    if (_prevOperand != Empty)
                    {
                        // set error missing operator
                        throw ExprException.MissingOperator(new string(_text, _start, _pos - _start));
                    }

                    // PushOperator descriptor
                    _ops[_topOperator++] = new OperatorInfo(Nodes.Zop, _op, Operators.PriMax);
                    _prevOperand         = Expr;
                    goto loop;

                case Tokens.Dot:
                    //if there is a name on the stack append it.
                    ExpressionNode?before = NodePeek();

                    if (before != null && before.GetType() == typeof(NameNode))
                    {
                        Scan();

                        if (_token == Tokens.Name)
                        {
                            NameNode nameBefore = (NameNode)NodePop();
                            string   newName    = nameBefore._name + "." + NameNode.ParseName(_text, _start, _pos);
                            NodePush(new NameNode(_table, newName));
                            goto loop;
                        }
                    }
                    // fall through to default
                    goto default;

                default:
                    throw ExprException.UnknownToken(new string(_text, _start, _pos - _start), _start + 1);
                }
            }
            goto end_loop;
end_loop:
            Debug.Assert(_topNode == 1 || _topNode == 0, "Invalid Node Stack");
            _expression = _nodeStack[0];

            return(_expression);
        }
Exemple #6
0
 public static String FormatCriteria(String fieldName, Object fieldValue,
     Operators eO, ConnectionLibrary eCl)
 {
     return FormatCriteria(fieldName, fieldValue, eO, "", fieldValue.GetType(), eCl);
 }
 /// <summary>
 /// ����ȽϿؼ�
 /// </summary>
 /// <param name="dc"></param>
 /// <param name="notNull"></param>
 /// <param name="op"></param>
 protected void AddDataControl(IDataControl dc, bool notNull, Operators op)
 {
     //m_dataControlGroup.Add(dc);
     m_ht.Add(dc, op);
     dc.NotNull = notNull;
 }
        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);
        }
        public override string ToString()
        {
            string str = left.ToString() + " " + Operators.ToString(op) + " " + right.ToString();

            return(str);
        }
        internal Type ResultType(Type left, Type right, bool lc, bool rc, int op)
        {
            if ((left == typeof(System.Guid)) && (right == typeof(System.Guid)) && Operators.IsRelational(op))
            {
                return(left);
            }

            if ((left == typeof(System.String)) && (right == typeof(System.Guid)) && Operators.IsRelational(op))
            {
                return(left);
            }

            if ((left == typeof(System.Guid)) && (right == typeof(System.String)) && Operators.IsRelational(op))
            {
                return(right);
            }

            int leftPrecedence = (int)GetPrecedence(left);

            if (leftPrecedence == (int)DataTypePrecedence.Error)
            {
                return(null);
            }
            int rightPrecedence = (int)GetPrecedence(right);

            if (rightPrecedence == (int)DataTypePrecedence.Error)
            {
                return(null);
            }

            if (Operators.IsLogical(op))
            {
                if (left == typeof(Boolean) && right == typeof(Boolean))
                {
                    return(typeof(Boolean));
                }
                else
                {
                    return(null);
                }
            }

            if ((op == Operators.Plus) && ((left == typeof(String)) || (right == typeof(String))))
            {
                return(typeof(string));
            }

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


            Type result = GetType(higherPrec);

            if (Operators.IsArithmetical(op))
            {
                if (result != typeof(string) && result != typeof(char))
                {
                    if (!IsNumeric(left))
                    {
                        return(null);
                    }
                    if (!IsNumeric(right))
                    {
                        return(null);
                    }
                }
            }

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

            if ((op == Operators.Divide) && IsInteger(result))
            {
                return(typeof(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 = GetType(higherPrec + 1);
                    }
                    else
                    {
                        throw ExprException.AmbiguousBinop(op, left, right);
                    }
                }
            }

            return(result);
        }
 /// <summary>
 /// Построить выражение
 /// </summary>
 /// <param name="op">Оператор</param>
 /// <param name="fieldRef">Поле</param>
 /// <param name="o">Значение</param>
 /// <returns></returns>
 protected CriteriaOperator BuildQueryExpression(Operators op, OperandProperty fieldRef, DateTime o)
 {
     if (op == Operators.NotEqual)
     {
         return new BinaryOperator(new FunctionOperator(FunctionOperatorType.GetDate, fieldRef), new OperandValue(o), BinaryOperatorType.NotEqual);
     }
     else if (op.Binary)
     {
         return new GroupOperator(op.Or ? GroupOperatorType.Or : GroupOperatorType.And,
             new BinaryOperator(new FunctionOperator(FunctionOperatorType.GetDate, fieldRef), new OperandValue(o), op.GetOperators()[0]),
             new BinaryOperator(new FunctionOperator(FunctionOperatorType.GetDate, fieldRef), new OperandValue(o), op.GetOperators()[1])
             );
     }
     else
     {
         return new BinaryOperator(new FunctionOperator(FunctionOperatorType.GetDate, fieldRef), new OperandValue(o), op.GetOperators()[0]);
     }
 }