Наследование: ExpressionNode
Пример #1
0
        public TreeNode BuildNode(BinaryNode<int> node)
        {
            TreeNode n = new TreeNode() { Text = node.Value.ToString() };

            if (node.LeftNode != null)
                n.Nodes.Add(BuildNode(node.LeftNode));

            if (node.RightNode != null)
                n.Nodes.Add(BuildNode(node.RightNode));

            return 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:
            ;
        }
Пример #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;
        }
Пример #4
0
        // Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (_linearExpression == _expression)
                return;

            if (expr._op == Operators.Or)
            {
                _linearExpression = _expression;
                return;
            }
            else
            if (expr._op == Operators.And)
            {
                bool isLeft = false, isRight = false;
                if (expr._left is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._left);
                    if (_linearExpression == _expression)
                        return;
                    isLeft = true;
                }
                else
                {
                    UnaryNode unaryNode = expr._left as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }
                            isLeft = true;
                        }
                    }
                }

                if (expr._right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._right);
                    if (_linearExpression == _expression)
                        return;
                    isRight = true;
                }
                else
                {
                    UnaryNode unaryNode = expr._right as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }

                            isRight = true;
                        }
                    }
                }

                if (isLeft && isRight)
                    return;

                ExpressionNode e = isLeft ? expr._right : expr._left;
                _linearExpression = (_linearExpression == null ? e : new BinaryNode(_table, Operators.And, e, _linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr._op))
            {
                if (expr._left is NameNode && expr._right is ConstNode)
                {
                    ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
                    if (expr._op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    _candidatesForBinarySearch = true;
                    return;
                }
                else
                if (expr._right is NameNode && expr._left is ConstNode)
                {
                    ExpressionNode temp = expr._left;
                    expr._left = expr._right;
                    expr._right = temp;
                    switch (expr._op)
                    {
                        case Operators.GreaterThen: expr._op = Operators.LessThen; break;
                        case Operators.LessThen: expr._op = Operators.GreaterThen; break;
                        case Operators.GreaterOrEqual: expr._op = Operators.LessOrEqual; break;
                        case Operators.LessOrEqual: expr._op = Operators.GreaterOrEqual; break;
                        default: break;
                    }
                    ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
                    if (expr._op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    _candidatesForBinarySearch = true;
                    return;
                }
            }

            _linearExpression = (_linearExpression == null ? expr : new BinaryNode(_table, Operators.And, expr, _linearExpression));
            return;
        }
Пример #5
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);
        }
Пример #6
0
        // Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (_linearExpression == _expression)
            {
                return;
            }

            if (expr._op == Operators.Or)
            {
                _linearExpression = _expression;
                return;
            }
            else
            if (expr._op == Operators.And)
            {
                bool isLeft = false, isRight = false;
                if (expr._left is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._left);
                    if (_linearExpression == _expression)
                    {
                        return;
                    }
                    isLeft = true;
                }
                else
                {
                    UnaryNode unaryNode = expr._left as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }
                            isLeft = true;
                        }
                    }
                }

                if (expr._right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._right);
                    if (_linearExpression == _expression)
                    {
                        return;
                    }
                    isRight = true;
                }
                else
                {
                    UnaryNode unaryNode = expr._right as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }

                            isRight = true;
                        }
                    }
                }

                if (isLeft && isRight)
                {
                    return;
                }

                ExpressionNode e = isLeft ? expr._right : expr._left;
                _linearExpression = (_linearExpression == null ? e : new BinaryNode(_table, Operators.And, e, _linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr._op))
            {
                if (expr._left is NameNode && expr._right is ConstNode)
                {
                    ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
                    if (expr._op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    _candidatesForBinarySearch = true;
                    return;
                }
                else
                if (expr._right is NameNode && expr._left is ConstNode)
                {
                    ExpressionNode temp = expr._left;
                    expr._left  = expr._right;
                    expr._right = temp;
                    switch (expr._op)
                    {
                    case Operators.GreaterThen: expr._op = Operators.LessThen; break;

                    case Operators.LessThen: expr._op = Operators.GreaterThen; break;

                    case Operators.GreaterOrEqual: expr._op = Operators.LessOrEqual; break;

                    case Operators.LessOrEqual: expr._op = Operators.GreaterOrEqual; break;

                    default: break;
                    }
                    ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(_table, Operators.And, expr, canColumn.expr));
                    if (expr._op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    _candidatesForBinarySearch = true;
                    return;
                }
            }

            _linearExpression = (_linearExpression == null ? expr : new BinaryNode(_table, Operators.And, expr, _linearExpression));
            return;
        }
Пример #7
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);
        }
Пример #8
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;
        }
Пример #9
0
        // haroona : Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (this.linearExpression == this.expression)
            {
                return;
            }

            if (expr.op == Operators.Or)
            {
                this.linearExpression = this.expression;
                return;
            }
            else
            if (expr.op == Operators.And)
            {
                bool isLeft = false, isRight = false;
                if (expr.left is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr.left);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isLeft = true;
                }
                else
                if (expr.left is UnaryNode && ((UnaryNode)(expr.left)).op == Operators.Noop && ((UnaryNode)(expr.left)).right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)((UnaryNode)(expr.left)).right);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isLeft = true;
                }

                if (expr.right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr.right);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isRight = true;
                }
                else
                if (expr.right is UnaryNode && ((UnaryNode)(expr.right)).op == Operators.Noop && ((UnaryNode)(expr.right)).right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)((UnaryNode)(expr.right)).right);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isRight = true;
                }

                if (isLeft && isRight)
                {
                    return;
                }

                ExpressionNode e = isLeft ? expr.right : expr.left;
                this.linearExpression = (this.linearExpression == null ? e : new BinaryNode(Operators.And, e, this.linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr.op))
            {
                if (expr.left is NameNode && expr.right is ConstNode)
                {
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
                else
                if (expr.right is NameNode && expr.left is ConstNode)
                {
                    ExpressionNode temp = expr.left;
                    expr.left  = expr.right;
                    expr.right = temp;
                    switch (expr.op)
                    {
                    case Operators.GreaterThen:     expr.op = Operators.LessThen; break;

                    case Operators.LessThen:        expr.op = Operators.GreaterThen; break;

                    case Operators.GreaterOrEqual:  expr.op = Operators.LessOrEqual; break;

                    case Operators.LessOrEqual:     expr.op = Operators.GreaterOrEqual; break;

                    default: break;
                    }
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
            }

            this.linearExpression = (this.linearExpression == null ? expr : new BinaryNode(Operators.And, expr, this.linearExpression));
            return;
        }
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (this.linearExpression != this.expression)
            {
                if (expr.op == 0x1b)
                {
                    this.linearExpression = this.expression;
                }
                else if (expr.op == 0x1a)
                {
                    bool flag = false;
                    bool flag2 = false;
                    if (expr.left is BinaryNode)
                    {
                        this.AnalyzeExpression((BinaryNode) expr.left);
                        if (this.linearExpression == this.expression)
                        {
                            return;
                        }
                        flag = true;
                    }
                    else
                    {
                        UnaryNode left = expr.left as UnaryNode;
                        if (left != null)
                        {
                            while (((left.op == 0) && (left.right is UnaryNode)) && (((UnaryNode) left.right).op == 0))
                            {
                                left = (UnaryNode) left.right;
                            }
                            if ((left.op == 0) && (left.right is BinaryNode))
                            {
                                this.AnalyzeExpression((BinaryNode) left.right);
                                if (this.linearExpression == this.expression)
                                {
                                    return;
                                }
                                flag = true;
                            }
                        }
                    }
                    if (expr.right is BinaryNode)
                    {
                        this.AnalyzeExpression((BinaryNode) expr.right);
                        if (this.linearExpression == this.expression)
                        {
                            return;
                        }
                        flag2 = true;
                    }
                    else
                    {
                        UnaryNode right = expr.right as UnaryNode;
                        if (right != null)
                        {
                            while (((right.op == 0) && (right.right is UnaryNode)) && (((UnaryNode) right.right).op == 0))
                            {
                                right = (UnaryNode) right.right;
                            }
                            if ((right.op == 0) && (right.right is BinaryNode))
                            {
                                this.AnalyzeExpression((BinaryNode) right.right);
                                if (this.linearExpression == this.expression)
                                {
                                    return;
                                }
                                flag2 = true;
                            }
                        }
                    }
                    if (!flag || !flag2)
                    {
                        ExpressionNode node3 = flag ? expr.right : expr.left;
                        this.linearExpression = (this.linearExpression == null) ? node3 : new BinaryNode(this.table, 0x1a, node3, this.linearExpression);
                    }
                }
                else
                {
                    if (this.IsSupportedOperator(expr.op))
                    {
                        if ((expr.left is NameNode) && (expr.right is ConstNode))
                        {
                            ColumnInfo info2 = this.candidateColumns[((NameNode) expr.left).column.Ordinal];
                            info2.expr = (info2.expr == null) ? expr : new BinaryNode(this.table, 0x1a, expr, info2.expr);
                            if (expr.op == 7)
                            {
                                info2.equalsOperator = true;
                            }
                            this.candidatesForBinarySearch = true;
                            return;
                        }
                        if ((expr.right is NameNode) && (expr.left is ConstNode))
                        {
                            ExpressionNode node4 = expr.left;
                            expr.left = expr.right;
                            expr.right = node4;
                            switch (expr.op)
                            {
                                case 8:
                                    expr.op = 9;
                                    break;

                                case 9:
                                    expr.op = 8;
                                    break;

                                case 10:
                                    expr.op = 11;
                                    break;

                                case 11:
                                    expr.op = 10;
                                    break;
                            }
                            ColumnInfo info = this.candidateColumns[((NameNode) expr.left).column.Ordinal];
                            info.expr = (info.expr == null) ? expr : new BinaryNode(this.table, 0x1a, expr, info.expr);
                            if (expr.op == 7)
                            {
                                info.equalsOperator = true;
                            }
                            this.candidatesForBinarySearch = true;
                            return;
                        }
                    }
                    this.linearExpression = (this.linearExpression == null) ? expr : new BinaryNode(this.table, 0x1a, expr, this.linearExpression);
                }
            }
        }
        private int Eval(BinaryNode expr, DataRow row, DataRowVersion version)
        {
            if (expr.op == 0x1a)
            {
                int num4 = this.Eval((BinaryNode) expr.left, row, version);
                if (num4 != 0)
                {
                    return num4;
                }
                int num3 = this.Eval((BinaryNode) expr.right, row, version);
                if (num3 != 0)
                {
                    return num3;
                }
                return 0;
            }
            long num = 0L;
            object obj3 = expr.left.Eval(row, version);
            if ((expr.op != 13) && (expr.op != 0x27))
            {
                StorageType type;
                object obj2 = expr.right.Eval(row, version);
                bool lc = expr.left is ConstNode;
                bool rc = expr.right is ConstNode;
                if ((obj3 == DBNull.Value) || (expr.left.IsSqlColumn && DataStorage.IsObjectSqlNull(obj3)))
                {
                    return -1;
                }
                if ((obj2 == DBNull.Value) || (expr.right.IsSqlColumn && DataStorage.IsObjectSqlNull(obj2)))
                {
                    return 1;
                }
                StorageType storageType = DataStorage.GetStorageType(obj3.GetType());
                if (StorageType.Char == storageType)
                {
                    if (rc || !expr.right.IsSqlColumn)
                    {
                        obj2 = Convert.ToChar(obj2, this.table.FormatProvider);
                    }
                    else
                    {
                        obj2 = SqlConvert.ChangeType2(obj2, StorageType.Char, typeof(char), this.table.FormatProvider);
                    }
                }
                StorageType right = DataStorage.GetStorageType(obj2.GetType());
                if (expr.left.IsSqlColumn || expr.right.IsSqlColumn)
                {
                    type = expr.ResultSqlType(storageType, right, lc, rc, expr.op);
                }
                else
                {
                    type = expr.ResultType(storageType, right, lc, rc, expr.op);
                }
                if (type == StorageType.Empty)
                {
                    expr.SetTypeMismatchError(expr.op, obj3.GetType(), obj2.GetType());
                }
                num = expr.BinaryCompare(obj3, obj2, type, expr.op);
            }
            switch (expr.op)
            {
                case 7:
                    num = (num == 0L) ? ((long) 0) : ((num < 0L) ? ((long) (-1)) : ((long) 1));
                    break;

                case 8:
                    num = (num > 0L) ? ((long) 0) : ((long) (-1));
                    break;

                case 9:
                    num = (num < 0L) ? ((long) 0) : ((long) 1);
                    break;

                case 10:
                    num = (num >= 0L) ? ((long) 0) : ((long) (-1));
                    break;

                case 11:
                    num = (num <= 0L) ? ((long) 0) : ((long) 1);
                    break;

                case 13:
                    num = (obj3 == DBNull.Value) ? ((long) 0) : ((long) (-1));
                    break;

                case 0x27:
                    num = (obj3 != DBNull.Value) ? ((long) 0) : ((long) 1);
                    break;
            }
            return (int) num;
        }
Пример #12
0
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (this.linearExpression != this.expression)
            {
                if (expr.op == 0x1b)
                {
                    this.linearExpression = this.expression;
                }
                else if (expr.op == 0x1a)
                {
                    bool flag  = false;
                    bool flag2 = false;
                    if (expr.left is BinaryNode)
                    {
                        this.AnalyzeExpression((BinaryNode)expr.left);
                        if (this.linearExpression == this.expression)
                        {
                            return;
                        }
                        flag = true;
                    }
                    else
                    {
                        UnaryNode left = expr.left as UnaryNode;
                        if (left != null)
                        {
                            while (((left.op == 0) && (left.right is UnaryNode)) && (((UnaryNode)left.right).op == 0))
                            {
                                left = (UnaryNode)left.right;
                            }
                            if ((left.op == 0) && (left.right is BinaryNode))
                            {
                                this.AnalyzeExpression((BinaryNode)left.right);
                                if (this.linearExpression == this.expression)
                                {
                                    return;
                                }
                                flag = true;
                            }
                        }
                    }
                    if (expr.right is BinaryNode)
                    {
                        this.AnalyzeExpression((BinaryNode)expr.right);
                        if (this.linearExpression == this.expression)
                        {
                            return;
                        }
                        flag2 = true;
                    }
                    else
                    {
                        UnaryNode right = expr.right as UnaryNode;
                        if (right != null)
                        {
                            while (((right.op == 0) && (right.right is UnaryNode)) && (((UnaryNode)right.right).op == 0))
                            {
                                right = (UnaryNode)right.right;
                            }
                            if ((right.op == 0) && (right.right is BinaryNode))
                            {
                                this.AnalyzeExpression((BinaryNode)right.right);
                                if (this.linearExpression == this.expression)
                                {
                                    return;
                                }
                                flag2 = true;
                            }
                        }
                    }
                    if (!flag || !flag2)
                    {
                        ExpressionNode node3 = flag ? expr.right : expr.left;
                        this.linearExpression = (this.linearExpression == null) ? node3 : new BinaryNode(this.table, 0x1a, node3, this.linearExpression);
                    }
                }
                else
                {
                    if (this.IsSupportedOperator(expr.op))
                    {
                        if ((expr.left is NameNode) && (expr.right is ConstNode))
                        {
                            ColumnInfo info2 = this.candidateColumns[((NameNode)expr.left).column.Ordinal];
                            info2.expr = (info2.expr == null) ? expr : new BinaryNode(this.table, 0x1a, expr, info2.expr);
                            if (expr.op == 7)
                            {
                                info2.equalsOperator = true;
                            }
                            this.candidatesForBinarySearch = true;
                            return;
                        }
                        if ((expr.right is NameNode) && (expr.left is ConstNode))
                        {
                            ExpressionNode node4 = expr.left;
                            expr.left  = expr.right;
                            expr.right = node4;
                            switch (expr.op)
                            {
                            case 8:
                                expr.op = 9;
                                break;

                            case 9:
                                expr.op = 8;
                                break;

                            case 10:
                                expr.op = 11;
                                break;

                            case 11:
                                expr.op = 10;
                                break;
                            }
                            ColumnInfo info = this.candidateColumns[((NameNode)expr.left).column.Ordinal];
                            info.expr = (info.expr == null) ? expr : new BinaryNode(this.table, 0x1a, expr, info.expr);
                            if (expr.op == 7)
                            {
                                info.equalsOperator = true;
                            }
                            this.candidatesForBinarySearch = true;
                            return;
                        }
                    }
                    this.linearExpression = (this.linearExpression == null) ? expr : new BinaryNode(this.table, 0x1a, expr, this.linearExpression);
                }
            }
        }
Пример #13
0
        private int Eval(BinaryNode expr, DataRow row, DataRowVersion version)
        {
            if (expr.op == 0x1a)
            {
                int num4 = this.Eval((BinaryNode)expr.left, row, version);
                if (num4 != 0)
                {
                    return(num4);
                }
                int num3 = this.Eval((BinaryNode)expr.right, row, version);
                if (num3 != 0)
                {
                    return(num3);
                }
                return(0);
            }
            long   num  = 0L;
            object obj3 = expr.left.Eval(row, version);

            if ((expr.op != 13) && (expr.op != 0x27))
            {
                StorageType type;
                object      obj2 = expr.right.Eval(row, version);
                bool        lc   = expr.left is ConstNode;
                bool        rc   = expr.right is ConstNode;
                if ((obj3 == DBNull.Value) || (expr.left.IsSqlColumn && DataStorage.IsObjectSqlNull(obj3)))
                {
                    return(-1);
                }
                if ((obj2 == DBNull.Value) || (expr.right.IsSqlColumn && DataStorage.IsObjectSqlNull(obj2)))
                {
                    return(1);
                }
                StorageType storageType = DataStorage.GetStorageType(obj3.GetType());
                if (StorageType.Char == storageType)
                {
                    if (rc || !expr.right.IsSqlColumn)
                    {
                        obj2 = Convert.ToChar(obj2, this.table.FormatProvider);
                    }
                    else
                    {
                        obj2 = SqlConvert.ChangeType2(obj2, StorageType.Char, typeof(char), this.table.FormatProvider);
                    }
                }
                StorageType right = DataStorage.GetStorageType(obj2.GetType());
                if (expr.left.IsSqlColumn || expr.right.IsSqlColumn)
                {
                    type = expr.ResultSqlType(storageType, right, lc, rc, expr.op);
                }
                else
                {
                    type = expr.ResultType(storageType, right, lc, rc, expr.op);
                }
                if (type == StorageType.Empty)
                {
                    expr.SetTypeMismatchError(expr.op, obj3.GetType(), obj2.GetType());
                }
                num = expr.BinaryCompare(obj3, obj2, type, expr.op);
            }
            switch (expr.op)
            {
            case 7:
                num = (num == 0L) ? ((long)0) : ((num < 0L) ? ((long)(-1)) : ((long)1));
                break;

            case 8:
                num = (num > 0L) ? ((long)0) : ((long)(-1));
                break;

            case 9:
                num = (num < 0L) ? ((long)0) : ((long)1);
                break;

            case 10:
                num = (num >= 0L) ? ((long)0) : ((long)(-1));
                break;

            case 11:
                num = (num <= 0L) ? ((long)0) : ((long)1);
                break;

            case 13:
                num = (obj3 == DBNull.Value) ? ((long)0) : ((long)(-1));
                break;

            case 0x27:
                num = (obj3 != DBNull.Value) ? ((long)0) : ((long)1);
                break;
            }
            return((int)num);
        }
Пример #14
0
        // Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr)
        {
            Debug.Assert(_candidateColumns != null);

            if (_linearExpression == _expression)
            {
                return;
            }

            if (expr._op == Operators.Or)
            {
                _linearExpression = _expression;
                return;
            }
            else
            if (expr._op == Operators.And)
            {
                bool isLeft = false, isRight = false;
                if (expr._left is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._left);
                    if (_linearExpression == _expression)
                    {
                        return;
                    }
                    isLeft = true;
                }
                else
                {
                    UnaryNode?unaryNode = expr._left as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }
                            isLeft = true;
                        }
                    }
                }

                if (expr._right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr._right);
                    if (_linearExpression == _expression)
                    {
                        return;
                    }
                    isRight = true;
                }
                else
                {
                    UnaryNode?unaryNode = expr._right as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode._op == Operators.Noop && unaryNode._right is UnaryNode && ((UnaryNode)unaryNode._right)._op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode._right;
                        }
                        if (unaryNode._op == Operators.Noop && unaryNode._right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode._right));
                            if (_linearExpression == _expression)
                            {
                                return;
                            }

                            isRight = true;
                        }
                    }
                }

                if (isLeft && isRight)
                {
                    return;
                }

                ExpressionNode e = isLeft ? expr._right : expr._left;
                _linearExpression = (_linearExpression == null ? e : new BinaryNode(_table, Operators.And, e, _linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr._op))
            {
                if (expr._left is NameNode && expr._right is ConstNode)
                {
                    ColumnInfo canColumn = _candidateColumns[((NameNode)(expr._left))._column !.Ordinal];
Пример #15
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)
                {
                    return(-1);
                }
                if (vRight == DBNull.Value)
                {
                    return(1);
                }

                if (vLeft.GetType() == typeof(char))
                {
                    vRight = Convert.ToChar(vRight);
                }

                Type result = expr.ResultType(vLeft.GetType(), vRight.GetType(), isLConst, isRConst, expr.op);
                if (result == null)
                {
                    expr.SetTypeMismatchError(expr.op, vLeft.GetType(), vRight.GetType());
                }

                c = expr.Compare(vLeft, vRight, result, expr.op);
            }
            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);
        }
        /// <devdoc>
        ///     Builds expression tree for higher-precedence operator to be used as left
        ///     operand of current operator. May cause errors - always do ErrorCheck() upin return.
        /// </devdoc>

        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.Assert(false, "Unhandled operator type");
                        goto end_loop;
                }
                Debug.Assert(expr != null, "Failed to create expression");

                NodePush(expr);
                // countinue while loop;
            }
            end_loop:
            ;
        }
Пример #17
0
        // Microsoft : Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr)
        {
            if (this.linearExpression == this.expression)
            {
                return;
            }

            if (expr.op == Operators.Or)
            {
                this.linearExpression = this.expression;
                return;
            }
            else
            if (expr.op == Operators.And)
            {
                bool isLeft = false, isRight = false;
                if (expr.left is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr.left);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isLeft = true;
                }
                else
                {
                    UnaryNode unaryNode = expr.left as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode.op == Operators.Noop && unaryNode.right is UnaryNode && ((UnaryNode)unaryNode.right).op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode.right;
                        }
                        if (unaryNode.op == Operators.Noop && unaryNode.right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode.right));
                            if (this.linearExpression == this.expression)
                            {
                                return;
                            }
                            isLeft = true;
                        }
                    }
                }

                if (expr.right is BinaryNode)
                {
                    AnalyzeExpression((BinaryNode)expr.right);
                    if (this.linearExpression == this.expression)
                    {
                        return;
                    }
                    isRight = true;
                }
                else
                {
                    UnaryNode unaryNode = expr.right as UnaryNode;
                    if (unaryNode != null)
                    {
                        while (unaryNode.op == Operators.Noop && unaryNode.right is UnaryNode && ((UnaryNode)unaryNode.right).op == Operators.Noop)
                        {
                            unaryNode = (UnaryNode)unaryNode.right;
                        }
                        if (unaryNode.op == Operators.Noop && unaryNode.right is BinaryNode)
                        {
                            AnalyzeExpression((BinaryNode)(unaryNode.right));
                            if (this.linearExpression == this.expression)
                            {
                                return;
                            }
                            // SQLBU 497534: DataTable.Select() returns incorrect results with multiple statements depending '(' and ')'
                            // from copy paste error fixing SQLBU 342141
                            isRight = true;
                        }
                    }
                }

                if (isLeft && isRight)
                {
                    return;
                }

                ExpressionNode e = isLeft ? expr.right : expr.left;
                this.linearExpression = (this.linearExpression == null ? e : new BinaryNode(table, Operators.And, e, this.linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr.op))
            {
                if (expr.left is NameNode && expr.right is ConstNode)
                {
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(table, Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
                else
                if (expr.right is NameNode && expr.left is ConstNode)
                {
                    ExpressionNode temp = expr.left;
                    expr.left  = expr.right;
                    expr.right = temp;
                    switch (expr.op)
                    {
                    case Operators.GreaterThen:     expr.op = Operators.LessThen; break;

                    case Operators.LessThen:        expr.op = Operators.GreaterThen; break;

                    case Operators.GreaterOrEqual:  expr.op = Operators.LessOrEqual; break;

                    case Operators.LessOrEqual:     expr.op = Operators.GreaterOrEqual; break;

                    default: break;
                    }
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(table, Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo)
                    {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
            }

            this.linearExpression = (this.linearExpression == null ? expr : new BinaryNode(table, Operators.And, expr, this.linearExpression));
            return;
        }
Пример #18
0
        // [....] : Gathers all linear expressions in to this.linearExpression and all binary expressions in to their respective candidate columns expressions
        private void AnalyzeExpression(BinaryNode expr) {
            if (this.linearExpression == this.expression)
                return;

            if (expr.op == Operators.Or) {
                this.linearExpression = this.expression;
                return;
            }
            else
            if (expr.op == Operators.And) {
                bool isLeft=false, isRight=false;
                if (expr.left is BinaryNode) {
                    AnalyzeExpression((BinaryNode)expr.left);
                    if (this.linearExpression == this.expression)
                        return;
                    isLeft = true;
                }
                else {
                    UnaryNode unaryNode = expr.left as UnaryNode;
                    if (unaryNode != null) {
                        while (unaryNode.op == Operators.Noop && unaryNode.right is UnaryNode && ((UnaryNode)unaryNode.right).op == Operators.Noop) {
                            unaryNode = (UnaryNode)unaryNode.right;
                        }                        
                        if (unaryNode.op == Operators.Noop && unaryNode.right is BinaryNode) {
                            AnalyzeExpression((BinaryNode)(unaryNode.right));
                            if (this.linearExpression == this.expression) {
                                return;
                            }
                            isLeft = true;
                        } 
                    }
                }

                if (expr.right is BinaryNode) {
                    AnalyzeExpression((BinaryNode)expr.right);
                    if (this.linearExpression == this.expression)
                        return;
                    isRight = true;
                }
                else {
                    UnaryNode unaryNode = expr.right as UnaryNode;
                    if (unaryNode != null) {
                        while (unaryNode.op == Operators.Noop && unaryNode.right is UnaryNode && ((UnaryNode)unaryNode.right).op == Operators.Noop) {
                            unaryNode = (UnaryNode)unaryNode.right;
                        }
                        if (unaryNode.op == Operators.Noop && unaryNode.right is BinaryNode) { 
                            AnalyzeExpression((BinaryNode)(unaryNode.right));
                            if (this.linearExpression == this.expression) {
                                return;
                            }
                            // SQLBU 497534: DataTable.Select() returns incorrect results with multiple statements depending '(' and ')'
                            // from copy paste error fixing SQLBU 342141
                            isRight = true;
                        }
                    }
                }

                if (isLeft && isRight)
                    return;

                ExpressionNode e = isLeft ? expr.right : expr.left;
                this.linearExpression = (this.linearExpression == null ? e : new BinaryNode(table, Operators.And, e, this.linearExpression));
                return;
            }
            else
            if (IsSupportedOperator(expr.op)) {
                if (expr.left is NameNode && expr.right is ConstNode) {
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(table, Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo) {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
                else
                if (expr.right is NameNode && expr.left is ConstNode) {
                    ExpressionNode temp = expr.left;
                    expr.left = expr.right;
                    expr.right = temp;
                    switch(expr.op) {
                        case Operators.GreaterThen:     expr.op = Operators.LessThen; break;
                        case Operators.LessThen:        expr.op = Operators.GreaterThen; break;
                        case Operators.GreaterOrEqual:  expr.op = Operators.LessOrEqual; break;
                        case Operators.LessOrEqual:     expr.op = Operators.GreaterOrEqual; break;
                        default : break;
                    }
                    ColumnInfo canColumn = (ColumnInfo)candidateColumns[((NameNode)(expr.left)).column.Ordinal];
                    canColumn.expr = (canColumn.expr == null ? expr : new BinaryNode(table, Operators.And, expr, canColumn.expr));
                    if (expr.op == Operators.EqualTo) {
                        canColumn.equalsOperator = true;
                    }
                    candidatesForBinarySearch = true;
                    return;
                }
            }

            this.linearExpression = (this.linearExpression == null ? expr : new BinaryNode(table, Operators.And, expr, this.linearExpression));
            return;
        }
        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;
        }