Пример #1
0
        internal DataExpression(DataTable table, string expression, Type type)
        {
            ExpressionParser parser = new ExpressionParser(table);
            parser.LoadExpression(expression);

            _originalExpression = expression;
            _expr = null;

            if (expression != null)
            {
                _storageType = DataStorage.GetStorageType(type);
                if (_storageType == StorageType.BigInteger)
                {
                    throw ExprException.UnsupportedDataType(type);
                }

                _dataType = type;
                _expr = parser.Parse();
                _parsed = true;
                if (_expr != null && table != null)
                {
                    Bind(table);
                }
                else
                {
                    _bound = false;
                }
            }
        }
Пример #2
0
 public Select(DataTable table, string filterExpression, string sort, DataViewRowState recordStates) {
     this.table = table;
     IndexFields = table.ParseSortString(sort);
     if (filterExpression != null && filterExpression.Length > 0) {
         this.rowFilter = new DataExpression(this.table, filterExpression);
         this.expression = this.rowFilter.ExpressionNode;
     }
     this.recordStates = recordStates;
 }
Пример #3
0
        internal override ExpressionNode Optimize()
        {
            _left = _left.Optimize();

            if (_op == Operators.Is)
            {
                // only 'Is Null' or 'Is Not Null' are valid
                if (_right is UnaryNode)
                {
                    UnaryNode un = (UnaryNode)_right;
                    if (un._op != Operators.Not)
                    {
                        throw ExprException.InvalidIsSyntax();
                    }
                    _op = Operators.IsNot;
                    _right = un._right;
                }
                if (_right is ZeroOpNode)
                {
                    if (((ZeroOpNode)_right)._op != Operators.Null)
                    {
                        throw ExprException.InvalidIsSyntax();
                    }
                }
                else
                {
                    throw ExprException.InvalidIsSyntax();
                }
            }
            else
            {
                _right = _right.Optimize();
            }


            if (IsConstant())
            {
                object val = Eval();

                if (val == DBNull.Value)
                {
                    return new ZeroOpNode(Operators.Null);
                }

                if (val is bool)
                {
                    if ((bool)val)
                        return new ZeroOpNode(Operators.True);
                    else
                        return new ZeroOpNode(Operators.False);
                }
                return new ConstNode(table, ValueType.Object, val, false);
            }
            else
                return this;
        }
Пример #4
0
 public Select(DataTable table, string filterExpression, string sort, DataViewRowState recordStates)
 {
     _table = table;
     _indexFields = table.ParseSortString(sort);
     if (filterExpression != null && filterExpression.Length > 0)
     {
         _rowFilter = new DataExpression(_table, filterExpression);
         _expression = _rowFilter.ExpressionNode;
     }
     _recordStates = recordStates;
 }
Пример #5
0
        internal void AddArgument(ExpressionNode argument) {
            if (!funcs[info].IsVariantArgumentList && argumentCount >= funcs[info].argumentCount)
                throw ExprException.FunctionArgumentCount(this.name);

            if (arguments == null) {
                arguments = new ExpressionNode[initialCapacity];
            }
            else if (argumentCount == arguments.Length) {
                ExpressionNode[] bigger = new ExpressionNode[argumentCount * 2];
                System.Array.Copy(arguments, 0, bigger, 0, argumentCount);
                arguments = bigger;
            }
            arguments[argumentCount++] = argument;
        }
        internal void Bind(DataTable table) {
            this.table = table;

            if (table == null)
                return;

            if (expr != null) {
                Debug.Assert(parsed, "Invalid calling order: Bind() before Parse()");
                List<DataColumn> list = new List<DataColumn>();
                expr.Bind(table, list);
                expr = expr.Optimize();
                this.table = table;
                bound = true;
                dependency = list.ToArray();
            }
        }
Пример #7
0
        internal void AddArgument(ExpressionNode argument)
        {
            if (!s_funcs[_info]._isVariantArgumentList && _argumentCount >= s_funcs[_info]._argumentCount)
                throw ExprException.FunctionArgumentCount(_name);

            if (_arguments == null)
            {
                _arguments = new ExpressionNode[initialCapacity];
            }
            else if (_argumentCount == _arguments.Length)
            {
                ExpressionNode[] bigger = new ExpressionNode[_argumentCount * 2];
                Array.Copy(_arguments, 0, bigger, 0, _argumentCount);
                _arguments = bigger;
            }
            _arguments[_argumentCount++] = argument;
        }
 internal void AddArgument(ExpressionNode argument)
 {
     if (!funcs[this.info].IsVariantArgumentList && (this.argumentCount >= funcs[this.info].argumentCount))
     {
         throw ExprException.FunctionArgumentCount(this.name);
     }
     if (this.arguments == null)
     {
         this.arguments = new ExpressionNode[1];
     }
     else if (this.argumentCount == this.arguments.Length)
     {
         ExpressionNode[] destinationArray = new ExpressionNode[this.argumentCount * 2];
         Array.Copy(this.arguments, 0, destinationArray, 0, this.argumentCount);
         this.arguments = destinationArray;
     }
     this.arguments[this.argumentCount++] = argument;
 }
Пример #9
0
 internal BinaryNode(DataTable table, int op, ExpressionNode left, ExpressionNode right) : base(table) {
     this.op = op;
     this.left = left;
     this.right = right;
 }
        private object EvalBinaryOp(int op, ExpressionNode left, ExpressionNode right, DataRow row, DataRowVersion version, int[] recordNos)
        {
            object obj2;
            object obj3;
            StorageType empty;
            if ((((op != 0x1b) && (op != 0x1a)) && ((op != 5) && (op != 13))) && (op != 0x27))
            {
                obj2 = Eval(left, row, version, recordNos);
                obj3 = Eval(right, row, version, recordNos);
                Type dataType = obj2.GetType();
                Type type4 = obj3.GetType();
                StorageType storageType = DataStorage.GetStorageType(dataType);
                StorageType type2 = DataStorage.GetStorageType(type4);
                bool flag3 = DataStorage.IsSqlType(storageType);
                bool flag2 = DataStorage.IsSqlType(type2);
                if (flag3 && DataStorage.IsObjectSqlNull(obj2))
                {
                    return obj2;
                }
                if (flag2 && DataStorage.IsObjectSqlNull(obj3))
                {
                    return obj3;
                }
                if ((obj2 == DBNull.Value) || (obj3 == DBNull.Value))
                {
                    return DBNull.Value;
                }
                if (flag3 || flag2)
                {
                    empty = this.ResultSqlType(storageType, type2, left is ConstNode, right is ConstNode, op);
                }
                else
                {
                    empty = this.ResultType(storageType, type2, left is ConstNode, right is ConstNode, op);
                }
                if (empty == StorageType.Empty)
                {
                    this.SetTypeMismatchError(op, dataType, type4);
                }
            }
            else
            {
                obj2 = obj3 = DBNull.Value;
                empty = StorageType.Empty;
            }
            object isTrue = DBNull.Value;
            bool flag = false;
            try
            {
                double num4;
                switch (op)
                {
                    case 5:
                        if (!(right is FunctionNode))
                        {
                            throw ExprException.InWithoutParentheses();
                        }
                        goto Label_165C;

                    case 7:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 == this.BinaryCompare(obj2, obj3, empty, 7));
                        }
                        return DBNull.Value;

                    case 8:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 < this.BinaryCompare(obj2, obj3, empty, op));
                        }
                        return DBNull.Value;

                    case 9:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 > this.BinaryCompare(obj2, obj3, empty, op));
                        }
                        return DBNull.Value;

                    case 10:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 <= this.BinaryCompare(obj2, obj3, empty, op));
                        }
                        return DBNull.Value;

                    case 11:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 >= this.BinaryCompare(obj2, obj3, empty, op));
                        }
                        return DBNull.Value;

                    case 12:
                        if (((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2))) && ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3))))
                        {
                            return (0 != this.BinaryCompare(obj2, obj3, empty, op));
                        }
                        return DBNull.Value;

                    case 13:
                        obj2 = Eval(left, row, version, recordNos);
                        if ((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2)))
                        {
                            return false;
                        }
                        return true;

                    case 15:
                        switch (empty)
                        {
                            case StorageType.Char:
                            case StorageType.String:
                                goto Label_03FB;

                            case StorageType.SByte:
                                goto Label_025F;

                            case StorageType.Int16:
                                goto Label_0293;

                            case StorageType.UInt16:
                                goto Label_02C7;

                            case StorageType.Int32:
                                goto Label_02FB;

                            case StorageType.UInt32:
                                goto Label_031F;

                            case StorageType.Int64:
                                goto Label_0367;

                            case StorageType.UInt64:
                                goto Label_0343;

                            case StorageType.Single:
                                goto Label_03B3;

                            case StorageType.Double:
                                goto Label_03D7;

                            case StorageType.Decimal:
                                goto Label_038B;

                            case StorageType.DateTime:
                                goto Label_041E;

                            case StorageType.TimeSpan:
                                goto Label_047E;

                            case StorageType.SqlByte:
                                goto Label_055E;

                            case StorageType.SqlDateTime:
                                goto Label_0596;

                            case StorageType.SqlDecimal:
                                goto Label_0526;

                            case StorageType.SqlDouble:
                                goto Label_04EE;

                            case StorageType.SqlInt16:
                                goto Label_049A;

                            case StorageType.SqlInt32:
                                goto Label_04B6;

                            case StorageType.SqlInt64:
                                goto Label_04D2;

                            case StorageType.SqlMoney:
                                goto Label_0542;

                            case StorageType.SqlSingle:
                                goto Label_050A;

                            case StorageType.SqlString:
                                goto Label_057A;
                        }
                        goto Label_061C;

                    case 0x10:
                        switch (empty)
                        {
                            case StorageType.SByte:
                                goto Label_0711;

                            case StorageType.Byte:
                                goto Label_06C1;

                            case StorageType.Int16:
                                goto Label_0745;

                            case StorageType.UInt16:
                                goto Label_0795;

                            case StorageType.Int32:
                                goto Label_07C9;

                            case StorageType.UInt32:
                                goto Label_0809;

                            case StorageType.Int64:
                                goto Label_082D;

                            case StorageType.UInt64:
                                goto Label_086D;

                            case StorageType.Single:
                                goto Label_08D5;

                            case StorageType.Double:
                                goto Label_0915;

                            case StorageType.Decimal:
                                goto Label_0891;

                            case StorageType.DateTime:
                                goto Label_0971;

                            case StorageType.TimeSpan:
                                goto Label_098D;

                            case StorageType.SqlByte:
                                goto Label_06F5;

                            case StorageType.SqlDateTime:
                                goto Label_09CD;

                            case StorageType.SqlDecimal:
                                goto Label_08B9;

                            case StorageType.SqlDouble:
                                goto Label_0939;

                            case StorageType.SqlInt16:
                                goto Label_0779;

                            case StorageType.SqlInt32:
                                goto Label_07ED;

                            case StorageType.SqlInt64:
                                goto Label_0851;

                            case StorageType.SqlMoney:
                                goto Label_0955;

                            case StorageType.SqlSingle:
                                goto Label_08F9;
                        }
                        goto Label_0A53;

                    case 0x11:
                        switch (empty)
                        {
                            case StorageType.SByte:
                                goto Label_0B48;

                            case StorageType.Byte:
                                goto Label_0AF8;

                            case StorageType.Int16:
                                goto Label_0B7C;

                            case StorageType.UInt16:
                                goto Label_0BCC;

                            case StorageType.Int32:
                                goto Label_0C00;

                            case StorageType.UInt32:
                                goto Label_0C40;

                            case StorageType.Int64:
                                goto Label_0C64;

                            case StorageType.UInt64:
                                goto Label_0CA4;

                            case StorageType.Single:
                                goto Label_0D0C;

                            case StorageType.Double:
                                goto Label_0D68;

                            case StorageType.Decimal:
                                goto Label_0CC8;

                            case StorageType.SqlByte:
                                goto Label_0B2C;

                            case StorageType.SqlDecimal:
                                goto Label_0CF0;

                            case StorageType.SqlDouble:
                                goto Label_0D8C;

                            case StorageType.SqlInt16:
                                goto Label_0BB0;

                            case StorageType.SqlInt32:
                                goto Label_0C24;

                            case StorageType.SqlInt64:
                                goto Label_0C88;

                            case StorageType.SqlMoney:
                                goto Label_0D4C;

                            case StorageType.SqlSingle:
                                goto Label_0D30;
                        }
                        goto Label_0DA8;

                    case 0x12:
                        switch (empty)
                        {
                            case StorageType.SByte:
                                goto Label_0E9D;

                            case StorageType.Byte:
                                goto Label_0E4D;

                            case StorageType.Int16:
                                goto Label_0ED1;

                            case StorageType.UInt16:
                                goto Label_0F21;

                            case StorageType.Int32:
                                goto Label_0F55;

                            case StorageType.UInt32:
                                goto Label_0F95;

                            case StorageType.Int64:
                                goto Label_0FDD;

                            case StorageType.UInt64:
                                goto Label_0FB9;

                            case StorageType.Single:
                                goto Label_1061;

                            case StorageType.Double:
                                goto Label_10BD;

                            case StorageType.Decimal:
                                goto Label_101D;

                            case StorageType.SqlByte:
                                goto Label_0E81;

                            case StorageType.SqlDecimal:
                                goto Label_1045;

                            case StorageType.SqlDouble:
                                goto Label_10E5;

                            case StorageType.SqlInt16:
                                goto Label_0F05;

                            case StorageType.SqlInt32:
                                goto Label_0F79;

                            case StorageType.SqlInt64:
                                goto Label_1001;

                            case StorageType.SqlMoney:
                                goto Label_10A1;

                            case StorageType.SqlSingle:
                                goto Label_1085;
                        }
                        goto Label_1101;

                    case 20:
                        if (!ExpressionNode.IsIntegerSql(empty))
                        {
                            goto Label_1646;
                        }
                        if (empty != StorageType.UInt64)
                        {
                            goto Label_15A2;
                        }
                        isTrue = Convert.ToUInt64(obj2, base.FormatProvider) % Convert.ToUInt64(obj3, base.FormatProvider);
                        goto Label_1715;

                    case 0x1a:
                        obj2 = Eval(left, row, version, recordNos);
                        if ((obj2 != DBNull.Value) && (!left.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj2)))
                        {
                            goto Label_13BF;
                        }
                        return DBNull.Value;

                    case 0x1b:
                        obj2 = Eval(left, row, version, recordNos);
                        if ((obj2 == DBNull.Value) || DataStorage.IsObjectSqlNull(obj2))
                        {
                            goto Label_14EF;
                        }
                        if ((obj2 is bool) || (obj2 is SqlBoolean))
                        {
                            goto Label_14DB;
                        }
                        obj3 = Eval(right, row, version, recordNos);
                        flag = true;
                        goto Label_1715;

                    case 0x27:
                        obj2 = Eval(left, row, version, recordNos);
                        if ((obj2 == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(obj2)))
                        {
                            return false;
                        }
                        return true;

                    default:
                        throw ExprException.UnsupportedOperator(op);
                }
                isTrue = Convert.ToByte(Convert.ToByte(obj2, base.FormatProvider) + Convert.ToByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_025F:
                isTrue = Convert.ToSByte(Convert.ToSByte(obj2, base.FormatProvider) + Convert.ToSByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0293:
                isTrue = Convert.ToInt16(Convert.ToInt16(obj2, base.FormatProvider) + Convert.ToInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_02C7:
                isTrue = Convert.ToUInt16(Convert.ToUInt16(obj2, base.FormatProvider) + Convert.ToUInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_02FB:
                isTrue = Convert.ToInt32(obj2, base.FormatProvider) + Convert.ToInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_031F:
                isTrue = Convert.ToUInt32(obj2, base.FormatProvider) + Convert.ToUInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0343:
                isTrue = Convert.ToUInt64(obj2, base.FormatProvider) + Convert.ToUInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0367:
                isTrue = Convert.ToInt64(obj2, base.FormatProvider) + Convert.ToInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_038B:
                isTrue = Convert.ToDecimal(obj2, base.FormatProvider) + Convert.ToDecimal(obj3, base.FormatProvider);
                goto Label_1715;
            Label_03B3:
                isTrue = Convert.ToSingle(obj2, base.FormatProvider) + Convert.ToSingle(obj3, base.FormatProvider);
                goto Label_1715;
            Label_03D7:
                isTrue = Convert.ToDouble(obj2, base.FormatProvider) + Convert.ToDouble(obj3, base.FormatProvider);
                goto Label_1715;
            Label_03FB:
                isTrue = Convert.ToString(obj2, base.FormatProvider) + Convert.ToString(obj3, base.FormatProvider);
                goto Label_1715;
            Label_041E:
                if ((obj2 is TimeSpan) && (obj3 is DateTime))
                {
                    isTrue = ((DateTime) obj3) + ((TimeSpan) obj2);
                }
                else if ((obj2 is DateTime) && (obj3 is TimeSpan))
                {
                    isTrue = ((DateTime) obj2) + ((TimeSpan) obj3);
                }
                else
                {
                    flag = true;
                }
                goto Label_1715;
            Label_047E:
                isTrue = ((TimeSpan) obj2) + ((TimeSpan) obj3);
                goto Label_1715;
            Label_049A:
                isTrue = SqlConvert.ConvertToSqlInt16(obj2) + SqlConvert.ConvertToSqlInt16(obj3);
                goto Label_1715;
            Label_04B6:
                isTrue = SqlConvert.ConvertToSqlInt32(obj2) + SqlConvert.ConvertToSqlInt32(obj3);
                goto Label_1715;
            Label_04D2:
                isTrue = SqlConvert.ConvertToSqlInt64(obj2) + SqlConvert.ConvertToSqlInt64(obj3);
                goto Label_1715;
            Label_04EE:
                isTrue = SqlConvert.ConvertToSqlDouble(obj2) + SqlConvert.ConvertToSqlDouble(obj3);
                goto Label_1715;
            Label_050A:
                isTrue = SqlConvert.ConvertToSqlSingle(obj2) + SqlConvert.ConvertToSqlSingle(obj3);
                goto Label_1715;
            Label_0526:
                isTrue = SqlConvert.ConvertToSqlDecimal(obj2) + SqlConvert.ConvertToSqlDecimal(obj3);
                goto Label_1715;
            Label_0542:
                isTrue = SqlConvert.ConvertToSqlMoney(obj2) + SqlConvert.ConvertToSqlMoney(obj3);
                goto Label_1715;
            Label_055E:
                isTrue = SqlConvert.ConvertToSqlByte(obj2) + SqlConvert.ConvertToSqlByte(obj3);
                goto Label_1715;
            Label_057A:
                isTrue = SqlConvert.ConvertToSqlString(obj2) + SqlConvert.ConvertToSqlString(obj3);
                goto Label_1715;
            Label_0596:
                if ((obj2 is TimeSpan) && (obj3 is SqlDateTime))
                {
                    isTrue = SqlConvert.ConvertToSqlDateTime(SqlConvert.ConvertToSqlDateTime(obj3).Value + ((TimeSpan) obj2));
                }
                else if ((obj2 is SqlDateTime) && (obj3 is TimeSpan))
                {
                    isTrue = SqlConvert.ConvertToSqlDateTime(SqlConvert.ConvertToSqlDateTime(obj2).Value + ((TimeSpan) obj3));
                }
                else
                {
                    flag = true;
                }
                goto Label_1715;
            Label_061C:
                flag = true;
                goto Label_1715;
            Label_06C1:
                isTrue = Convert.ToByte(Convert.ToByte(obj2, base.FormatProvider) - Convert.ToByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_06F5:
                isTrue = SqlConvert.ConvertToSqlByte(obj2) - SqlConvert.ConvertToSqlByte(obj3);
                goto Label_1715;
            Label_0711:
                isTrue = Convert.ToSByte(Convert.ToSByte(obj2, base.FormatProvider) - Convert.ToSByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0745:
                isTrue = Convert.ToInt16(Convert.ToInt16(obj2, base.FormatProvider) - Convert.ToInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0779:
                isTrue = SqlConvert.ConvertToSqlInt16(obj2) - SqlConvert.ConvertToSqlInt16(obj3);
                goto Label_1715;
            Label_0795:
                isTrue = Convert.ToUInt16(Convert.ToUInt16(obj2, base.FormatProvider) - Convert.ToUInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_07C9:
                isTrue = Convert.ToInt32(obj2, base.FormatProvider) - Convert.ToInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_07ED:
                isTrue = SqlConvert.ConvertToSqlInt32(obj2) - SqlConvert.ConvertToSqlInt32(obj3);
                goto Label_1715;
            Label_0809:
                isTrue = Convert.ToUInt32(obj2, base.FormatProvider) - Convert.ToUInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_082D:
                isTrue = Convert.ToInt64(obj2, base.FormatProvider) - Convert.ToInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0851:
                isTrue = SqlConvert.ConvertToSqlInt64(obj2) - SqlConvert.ConvertToSqlInt64(obj3);
                goto Label_1715;
            Label_086D:
                isTrue = Convert.ToUInt64(obj2, base.FormatProvider) - Convert.ToUInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0891:
                isTrue = Convert.ToDecimal(obj2, base.FormatProvider) - Convert.ToDecimal(obj3, base.FormatProvider);
                goto Label_1715;
            Label_08B9:
                isTrue = SqlConvert.ConvertToSqlDecimal(obj2) - SqlConvert.ConvertToSqlDecimal(obj3);
                goto Label_1715;
            Label_08D5:
                isTrue = Convert.ToSingle(obj2, base.FormatProvider) - Convert.ToSingle(obj3, base.FormatProvider);
                goto Label_1715;
            Label_08F9:
                isTrue = SqlConvert.ConvertToSqlSingle(obj2) - SqlConvert.ConvertToSqlSingle(obj3);
                goto Label_1715;
            Label_0915:
                isTrue = Convert.ToDouble(obj2, base.FormatProvider) - Convert.ToDouble(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0939:
                isTrue = SqlConvert.ConvertToSqlDouble(obj2) - SqlConvert.ConvertToSqlDouble(obj3);
                goto Label_1715;
            Label_0955:
                isTrue = SqlConvert.ConvertToSqlMoney(obj2) - SqlConvert.ConvertToSqlMoney(obj3);
                goto Label_1715;
            Label_0971:
                isTrue = ((DateTime) obj2) - ((TimeSpan) obj3);
                goto Label_1715;
            Label_098D:
                if (obj2 is DateTime)
                {
                    isTrue = (TimeSpan) (((DateTime) obj2) - ((DateTime) obj3));
                }
                else
                {
                    isTrue = ((TimeSpan) obj2) - ((TimeSpan) obj3);
                }
                goto Label_1715;
            Label_09CD:
                if ((obj2 is TimeSpan) && (obj3 is SqlDateTime))
                {
                    isTrue = SqlConvert.ConvertToSqlDateTime(SqlConvert.ConvertToSqlDateTime(obj3).Value - ((TimeSpan) obj2));
                }
                else if ((obj2 is SqlDateTime) && (obj3 is TimeSpan))
                {
                    isTrue = SqlConvert.ConvertToSqlDateTime(SqlConvert.ConvertToSqlDateTime(obj2).Value - ((TimeSpan) obj3));
                }
                else
                {
                    flag = true;
                }
                goto Label_1715;
            Label_0A53:
                flag = true;
                goto Label_1715;
            Label_0AF8:
                isTrue = Convert.ToByte(Convert.ToByte(obj2, base.FormatProvider) * Convert.ToByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0B2C:
                isTrue = SqlConvert.ConvertToSqlByte(obj2) * SqlConvert.ConvertToSqlByte(obj3);
                goto Label_1715;
            Label_0B48:
                isTrue = Convert.ToSByte(Convert.ToSByte(obj2, base.FormatProvider) * Convert.ToSByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0B7C:
                isTrue = Convert.ToInt16(Convert.ToInt16(obj2, base.FormatProvider) * Convert.ToInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0BB0:
                isTrue = SqlConvert.ConvertToSqlInt16(obj2) * SqlConvert.ConvertToSqlInt16(obj3);
                goto Label_1715;
            Label_0BCC:
                isTrue = Convert.ToUInt16(Convert.ToUInt16(obj2, base.FormatProvider) * Convert.ToUInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0C00:
                isTrue = Convert.ToInt32(obj2, base.FormatProvider) * Convert.ToInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0C24:
                isTrue = SqlConvert.ConvertToSqlInt32(obj2) * SqlConvert.ConvertToSqlInt32(obj3);
                goto Label_1715;
            Label_0C40:
                isTrue = Convert.ToUInt32(obj2, base.FormatProvider) * Convert.ToUInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0C64:
                isTrue = Convert.ToInt64(obj2, base.FormatProvider) * Convert.ToInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0C88:
                isTrue = SqlConvert.ConvertToSqlInt64(obj2) * SqlConvert.ConvertToSqlInt64(obj3);
                goto Label_1715;
            Label_0CA4:
                isTrue = Convert.ToUInt64(obj2, base.FormatProvider) * Convert.ToUInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0CC8:
                isTrue = Convert.ToDecimal(obj2, base.FormatProvider) * Convert.ToDecimal(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0CF0:
                isTrue = SqlConvert.ConvertToSqlDecimal(obj2) * SqlConvert.ConvertToSqlDecimal(obj3);
                goto Label_1715;
            Label_0D0C:
                isTrue = Convert.ToSingle(obj2, base.FormatProvider) * Convert.ToSingle(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0D30:
                isTrue = SqlConvert.ConvertToSqlSingle(obj2) * SqlConvert.ConvertToSqlSingle(obj3);
                goto Label_1715;
            Label_0D4C:
                isTrue = SqlConvert.ConvertToSqlMoney(obj2) * SqlConvert.ConvertToSqlMoney(obj3);
                goto Label_1715;
            Label_0D68:
                isTrue = Convert.ToDouble(obj2, base.FormatProvider) * Convert.ToDouble(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0D8C:
                isTrue = SqlConvert.ConvertToSqlDouble(obj2) * SqlConvert.ConvertToSqlDouble(obj3);
                goto Label_1715;
            Label_0DA8:
                flag = true;
                goto Label_1715;
            Label_0E4D:
                isTrue = Convert.ToByte(Convert.ToByte(obj2, base.FormatProvider) / Convert.ToByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0E81:
                isTrue = SqlConvert.ConvertToSqlByte(obj2) / SqlConvert.ConvertToSqlByte(obj3);
                goto Label_1715;
            Label_0E9D:
                isTrue = Convert.ToSByte(Convert.ToSByte(obj2, base.FormatProvider) / Convert.ToSByte(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0ED1:
                isTrue = Convert.ToInt16(Convert.ToInt16(obj2, base.FormatProvider) / Convert.ToInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0F05:
                isTrue = SqlConvert.ConvertToSqlInt16(obj2) / SqlConvert.ConvertToSqlInt16(obj3);
                goto Label_1715;
            Label_0F21:
                isTrue = Convert.ToUInt16(Convert.ToUInt16(obj2, base.FormatProvider) / Convert.ToUInt16(obj3, base.FormatProvider), base.FormatProvider);
                goto Label_1715;
            Label_0F55:
                isTrue = Convert.ToInt32(obj2, base.FormatProvider) / Convert.ToInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0F79:
                isTrue = SqlConvert.ConvertToSqlInt32(obj2) / SqlConvert.ConvertToSqlInt32(obj3);
                goto Label_1715;
            Label_0F95:
                isTrue = Convert.ToUInt32(obj2, base.FormatProvider) / Convert.ToUInt32(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0FB9:
                isTrue = Convert.ToUInt64(obj2, base.FormatProvider) / Convert.ToUInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_0FDD:
                isTrue = Convert.ToInt64(obj2, base.FormatProvider) / Convert.ToInt64(obj3, base.FormatProvider);
                goto Label_1715;
            Label_1001:
                isTrue = SqlConvert.ConvertToSqlInt64(obj2) / SqlConvert.ConvertToSqlInt64(obj3);
                goto Label_1715;
            Label_101D:
                isTrue = Convert.ToDecimal(obj2, base.FormatProvider) / Convert.ToDecimal(obj3, base.FormatProvider);
                goto Label_1715;
            Label_1045:
                isTrue = SqlConvert.ConvertToSqlDecimal(obj2) / SqlConvert.ConvertToSqlDecimal(obj3);
                goto Label_1715;
            Label_1061:
                isTrue = Convert.ToSingle(obj2, base.FormatProvider) / Convert.ToSingle(obj3, base.FormatProvider);
                goto Label_1715;
            Label_1085:
                isTrue = SqlConvert.ConvertToSqlSingle(obj2) / SqlConvert.ConvertToSqlSingle(obj3);
                goto Label_1715;
            Label_10A1:
                isTrue = SqlConvert.ConvertToSqlMoney(obj2) / SqlConvert.ConvertToSqlMoney(obj3);
                goto Label_1715;
            Label_10BD:
                num4 = Convert.ToDouble(obj3, base.FormatProvider);
                isTrue = Convert.ToDouble(obj2, base.FormatProvider) / num4;
                goto Label_1715;
            Label_10E5:
                isTrue = SqlConvert.ConvertToSqlDouble(obj2) / SqlConvert.ConvertToSqlDouble(obj3);
                goto Label_1715;
            Label_1101:
                flag = true;
                goto Label_1715;
            Label_13BF:
                if (!(obj2 is bool) && !(obj2 is SqlBoolean))
                {
                    obj3 = Eval(right, row, version, recordNos);
                    flag = true;
                    goto Label_1715;
                }
                if (obj2 is bool)
                {
                    if ((bool) obj2)
                    {
                        goto Label_141D;
                    }
                    isTrue = false;
                    goto Label_1715;
                }
                SqlBoolean flag6 = (SqlBoolean) obj2;
                if (flag6.IsFalse)
                {
                    isTrue = false;
                    goto Label_1715;
                }
            Label_141D:
                obj3 = Eval(right, row, version, recordNos);
                if ((obj3 == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(obj3)))
                {
                    return DBNull.Value;
                }
                if ((obj3 is bool) || (obj3 is SqlBoolean))
                {
                    if (obj3 is bool)
                    {
                        isTrue = (bool) obj3;
                    }
                    else
                    {
                        SqlBoolean flag5 = (SqlBoolean) obj3;
                        isTrue = flag5.IsTrue;
                    }
                }
                else
                {
                    flag = true;
                }
                goto Label_1715;
            Label_14DB:
                if ((bool) obj2)
                {
                    isTrue = true;
                    goto Label_1715;
                }
            Label_14EF:
                obj3 = Eval(right, row, version, recordNos);
                if ((obj3 == DBNull.Value) || DataStorage.IsObjectSqlNull(obj3))
                {
                    return obj2;
                }
                if ((obj2 == DBNull.Value) || DataStorage.IsObjectSqlNull(obj2))
                {
                    return obj3;
                }
                if ((obj3 is bool) || (obj3 is SqlBoolean))
                {
                    isTrue = (obj3 is bool) ? ((bool) obj3) : ((SqlBoolean) obj3).IsTrue;
                }
                else
                {
                    flag = true;
                }
                goto Label_1715;
            Label_15A2:
                if (DataStorage.IsSqlType(empty))
                {
                    SqlInt64 num3 = SqlConvert.ConvertToSqlInt64(obj2) % SqlConvert.ConvertToSqlInt64(obj3);
                    switch (empty)
                    {
                        case StorageType.SqlInt32:
                            isTrue = num3.ToSqlInt32();
                            goto Label_1715;

                        case StorageType.SqlInt16:
                            isTrue = num3.ToSqlInt16();
                            goto Label_1715;

                        case StorageType.SqlByte:
                            isTrue = num3.ToSqlByte();
                            goto Label_1715;
                    }
                    isTrue = num3;
                }
                else
                {
                    isTrue = Convert.ToInt64(obj2, base.FormatProvider) % Convert.ToInt64(obj3, base.FormatProvider);
                    isTrue = Convert.ChangeType(isTrue, DataStorage.GetTypeStorage(empty), base.FormatProvider);
                }
                goto Label_1715;
            Label_1646:
                flag = true;
                goto Label_1715;
            Label_165C:
                obj2 = Eval(left, row, version, recordNos);
                if ((obj2 == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(obj2)))
                {
                    return DBNull.Value;
                }
                isTrue = false;
                FunctionNode node = (FunctionNode) right;
                for (int i = 0; i < node.argumentCount; i++)
                {
                    obj3 = node.arguments[i].Eval();
                    if ((obj3 != DBNull.Value) && (!right.IsSqlColumn || !DataStorage.IsObjectSqlNull(obj3)))
                    {
                        empty = DataStorage.GetStorageType(obj2.GetType());
                        if (this.BinaryCompare(obj2, obj3, empty, 7) == 0)
                        {
                            isTrue = true;
                            break;
                        }
                    }
                }
            }
            catch (OverflowException)
            {
                throw ExprException.Overflow(DataStorage.GetTypeStorage(empty));
            }
        Label_1715:
            if (flag)
            {
                this.SetTypeMismatchError(op, obj2.GetType(), obj3.GetType());
            }
            return isTrue;
        }
Пример #11
0
        private Type GetDataType(ExpressionNode node)
        {
            Type nodeType = node.GetType();
            string typeName = null;

            if (nodeType == typeof(NameNode))
            {
                typeName = ((NameNode)node)._name;
            }
            if (nodeType == typeof(ConstNode))
            {
                typeName = ((ConstNode)node)._val.ToString();
            }

            if (typeName == null)
            {
                throw ExprException.ArgumentType(s_funcs[_info]._name, 2, typeof(Type));
            }

            Type dataType = Type.GetType(typeName);

            if (dataType == null)
            {
                throw ExprException.InvalidType(typeName);
            }

            return dataType;
        }
        /// <devdoc>
        ///     Push an operand node onto the node stack
        /// </devdoc>
        private void NodePush(ExpressionNode node) {
            Debug.Assert(null != node, "null NodePush");

            if (topNode >= MaxPredicates-2) {
                throw ExprException.ExpressionTooComplex();
            }
            NodeStack[topNode++] = node;
        }
Пример #13
0
        // Based on the current index and candidate columns settings, build the linear expression; Should be called only when there is atleast something for Binary Searching
        private void BuildLinearExpression() {
            int i;
            IndexField[] fields = index.IndexFields;
            int lenId = fields.Length;
            Debug.Assert(matchedCandidates > 0 && matchedCandidates <= lenId, "BuildLinearExpression : Invalid Index");
            for (i=0; i<matchedCandidates; i++) {
                ColumnInfo canColumn = candidateColumns[fields[i].Column.Ordinal];
                Debug.Assert(canColumn != null && canColumn.expr != null, "BuildLinearExpression : Must be a matched candidate");
                canColumn.flag = true;
            }
            //this is invalid assert, assumption was that all equals operator exists at the begining of candidateColumns
            // but with QFE 1704, this assumption is not true anymore
//            Debug.Assert(matchedCandidates==1 || candidateColumns[matchedCandidates-1].equalsOperator, "BuildLinearExpression : Invalid matched candidates");
            int lenCanColumns = candidateColumns.Length;
            for (i=0; i<lenCanColumns; i++) {
                if (candidateColumns[i] != null) {
                    if (!candidateColumns[i].flag) {
                        if (candidateColumns[i].expr != null) {
                            this.linearExpression = (this.linearExpression == null ? candidateColumns[i].expr : new BinaryNode(table, Operators.And, candidateColumns[i].expr, this.linearExpression));
                        }
                    }
                    else {
                        candidateColumns[i].flag = false;
                    }
                }
            }
//            Debug.Assert(this.linearExpression != null, "BuildLinearExpression : How come there is nothing to search linearly"); bug 97446
        }
Пример #14
0
 internal UnaryNode(DataTable table, int op, ExpressionNode right) : base(table) {
     this.op = op;
     this.right = right;
 }
        internal void LoadExpression(string data) {
            int length;

            if (data == null) {
                length = 0;
                this.text = new char[length+1];
            }
            else {
                length = data.Length;
                this.text = new char[length+1];
                data.CopyTo(0, this.text, 0, length);
            }

            this.text[length] = '\0';

            if (expression != null) {
                // free all nodes
                expression = null;
            }
        }
Пример #16
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;
        }
 private void BuildLinearExpression()
 {
     int num;
     int[] indexDesc = this.index.IndexDesc;
     for (num = 0; num < this.matchedCandidates; num++)
     {
         ColumnInfo info = this.candidateColumns[DataKey.ColumnOrder(indexDesc[num])];
         info.flag = true;
     }
     int length = this.candidateColumns.Length;
     for (num = 0; num < length; num++)
     {
         if (this.candidateColumns[num] != null)
         {
             if (!this.candidateColumns[num].flag)
             {
                 if (this.candidateColumns[num].expr != null)
                 {
                     this.linearExpression = (this.linearExpression == null) ? this.candidateColumns[num].expr : new BinaryNode(this.table, 0x1a, this.candidateColumns[num].expr, this.linearExpression);
                 }
             }
             else
             {
                 this.candidateColumns[num].flag = false;
             }
         }
     }
 }
        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);
                }
            }
        }
 public DataRow[] SelectRows()
 {
     Range binaryFilteredRecords;
     bool flag = true;
     this.InitCandidateColumns();
     if (this.expression is BinaryNode)
     {
         this.AnalyzeExpression((BinaryNode) this.expression);
         if (!this.candidatesForBinarySearch)
         {
             this.linearExpression = this.expression;
         }
         if (this.linearExpression == this.expression)
         {
             for (int i = 0; i < this.candidateColumns.Length; i++)
             {
                 if (this.candidateColumns[i] != null)
                 {
                     this.candidateColumns[i].equalsOperator = false;
                     this.candidateColumns[i].expr = null;
                 }
             }
         }
         else
         {
             flag = !this.FindClosestCandidateIndex();
         }
     }
     else
     {
         this.linearExpression = this.expression;
     }
     if ((this.index == null) && ((this.indexDesc.Length > 0) || (this.linearExpression == this.expression)))
     {
         flag = !this.FindSortIndex();
     }
     if (this.index == null)
     {
         this.CreateIndex();
         flag = false;
     }
     if (this.index.RecordCount == 0)
     {
         return this.table.NewRowArray(0);
     }
     if (this.matchedCandidates == 0)
     {
         binaryFilteredRecords = new Range(0, this.index.RecordCount - 1);
         this.linearExpression = this.expression;
         return this.GetLinearFilteredRows(binaryFilteredRecords);
     }
     binaryFilteredRecords = this.GetBinaryFilteredRecords();
     if (binaryFilteredRecords.Count == 0)
     {
         return this.table.NewRowArray(0);
     }
     if (this.matchedCandidates < this.nCandidates)
     {
         this.BuildLinearExpression();
     }
     if (!flag)
     {
         return this.GetLinearFilteredRows(binaryFilteredRecords);
     }
     this.records = this.GetLinearFilteredRecords(binaryFilteredRecords);
     this.recordCount = this.records.Length;
     if (this.recordCount == 0)
     {
         return this.table.NewRowArray(0);
     }
     this.Sort(0, this.recordCount - 1);
     return this.GetRows();
 }
 private bool IsOperatorIn(ExpressionNode enode)
 {
     BinaryNode node = enode as BinaryNode;
     if ((node == null) || (((5 != node.op) && !this.IsOperatorIn(node.right)) && !this.IsOperatorIn(node.left)))
     {
         return false;
     }
     return true;
 }
Пример #21
0
        public DataRow[] SelectRows()
        {
            bool needSorting = true;

            InitCandidateColumns();

            if (_expression is BinaryNode)
            {
                AnalyzeExpression((BinaryNode)_expression);
                if (!_candidatesForBinarySearch)
                {
                    _linearExpression = _expression;
                }
                if (_linearExpression == _expression)
                {
                    for (int i = 0; i < _candidateColumns.Length; i++)
                    {
                        if (_candidateColumns[i] != null)
                        {
                            _candidateColumns[i].equalsOperator = false;
                            _candidateColumns[i].expr = null;
                        }
                    }
                }
                else
                {
                    needSorting = !FindClosestCandidateIndex();
                }
            }
            else
            {
                _linearExpression = _expression;
            }

            if (_index == null && (_indexFields.Length > 0 || _linearExpression == _expression))
            {
                needSorting = !FindSortIndex();
            }

            if (_index == null)
            {
                CreateIndex();
                needSorting = false;
            }

            if (_index.RecordCount == 0)
                return _table.NewRowArray(0);

            Range range;
            if (_matchedCandidates == 0)
            {
                range = new Range(0, _index.RecordCount - 1);
                Debug.Assert(!needSorting, "What are we doing here if no real reuse of this index ?");
                _linearExpression = _expression;
                return GetLinearFilteredRows(range);
            }
            else
            {
                range = GetBinaryFilteredRecords();
                if (range.Count == 0)
                    return _table.NewRowArray(0);
                if (_matchedCandidates < _nCandidates)
                {
                    BuildLinearExpression();
                }
                if (!needSorting)
                {
                    return GetLinearFilteredRows(range);
                }
                else
                {
                    _records = GetLinearFilteredRecords(range);
                    _recordCount = _records.Length;
                    if (_recordCount == 0)
                        return _table.NewRowArray(0);
                    Sort(0, _recordCount - 1);
                    return GetRows();
                }
            }
        }
Пример #22
0
 private static object Eval(ExpressionNode expr, DataRow row, DataRowVersion version, int[] recordNos)
 {
     if (recordNos == null)
     {
         return expr.Eval(row, version);
     }
     else
     {
         return expr.Eval(recordNos);
     }
 }
Пример #23
0
        internal override ExpressionNode Optimize() {
            right = right.Optimize();

            if (this.IsConstant()) {
                object val = this.Eval();

                return new ConstNode(table, ValueType.Object,  val, false);
            }
            else
                return this;
        }
Пример #24
0
 internal LikeNode(DataTable table, int op, ExpressionNode left, ExpressionNode right)
 : base(table, op, left, right)
 {
 }
Пример #25
0
 internal UnaryNode(DataTable table, int op, ExpressionNode right) : base(table)
 {
     _op    = op;
     _right = right;
 }
Пример #26
0
 internal BinaryNode(DataTable table, int op, ExpressionNode left, ExpressionNode right) : base(table)
 {
     _op = op;
     _left = left;
     _right = right;
 }
        // 

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

            StartScan();

            int cParens = 0;
            OperatorInfo opInfo;

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

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

                        if (prevOperand == Empty) {
                            if (topNode == 0) {
                                // we have an empty expression
                                break;
                            }
                            // set error missing operator
                            // read the last operator info
                            opInfo = ops[topOperator - 1];

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

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

                        /* Constants and identifiers: create leaf node */

                        if (prevOperand != Empty) {
                            // set error missing operator
                            throw ExprException.MissingOperator(new string(text, start, pos - start));
                        }

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

                            opInfo = ops[topOperator-1];

                            if (opInfo.type == Nodes.Binop && opInfo.op == Operators.In && token != Tokens.Parent) {
                                throw ExprException.InWithoutParentheses();
                            }
                        }

                        prevOperand = Scalar;

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

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

                                ScanToken(Tokens.Name);
                                colname = NameNode.ParseName(text, start, pos);

                                opInfo = ops[topOperator - 1];
                                node = new LookupNode(_table, colname, relname);

                                break;

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

                                opInfo = ops[topOperator - 1];

                                /* Create tree element -                */
                                // 
                                node = new NameNode(_table, text, start, pos);

                                break;

                            case Tokens.Numeric:
                                str = new string(text, start, pos - start);
                                node = new ConstNode(_table, ValueType.Numeric, str);
                                break;
                            case Tokens.Decimal:
                                str = new string(text, start, pos - start);
                                node = new ConstNode(_table, ValueType.Decimal, str);
                                break;
                            case Tokens.Float:
                                str = new string(text, start, pos - start);
                                node = new ConstNode(_table, ValueType.Float, str);
                                break;
                            case Tokens.StringConst:
                                Debug.Assert(text[start] == '\'' && text[pos-1] == '\'', "The expression contains an invalid string constant");
                                Debug.Assert(pos - start > 1, "The expression contains an invalid string constant");
                                // Store string without quotes..
                                str = new string(text, start+1, pos - start-2);
                                node = new ConstNode(_table, ValueType.Str, str);
                                break;
                            case Tokens.Date:
                                Debug.Assert(text[start] == '#' && text[pos-1] == '#', "The expression contains invalid date constant.");
                                Debug.Assert(pos - start > 2, "The expression contains invalid date constant '{0}'.");
                                // Store date without delimiters(#s)..
                                str = new string(text, start+1, pos - start-2);
                                node = new ConstNode(_table, ValueType.Date, str);
                                break;
                            default:
                                Debug.Assert(false, "unhandled token");
                                break;
                        }

                        NodePush(node);
                        goto loop;

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

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

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

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

                            BuildExpression(Operators.priProc);
                            prevOperand = Empty;
                            ExpressionNode nodebefore = NodePeek();

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

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

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

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

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

                            NodePush(node);
                            ops[topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.priParen);
                        }
                        goto loop;

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

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

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

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

                            Debug.Assert(opInfo.priority == Operators.priParen, "melformed operator stack.");

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

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

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

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

                            prevOperand = Expr;
                            cParens--;
                            goto loop;
                        }
                    case Tokens.ListSeparator:
                        {
                            /* Comma encountered: Must be operand; force out subexpression */

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

                            /* We are be in a procedure call */

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

                            opInfo = ops[topOperator - 1];

                            if (opInfo.type != Nodes.Call)
                                //
                                throw ExprException.SyntaxError();

                            ExpressionNode argument2 = NodePop();

                            /* Get the procedure name */

                            FunctionNode func = (FunctionNode)NodePop();

                            func.AddArgument(argument2);

                            NodePush(func);

                            prevOperand = Empty;

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

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

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

                            BuildExpression(Operators.Priority(op));

                            // PushOperator descriptor
                            ops[topOperator++] = new OperatorInfo(Nodes.Binop, op, Operators.Priority(op));
                            goto loop;
                        }
                        goto
                    case Tokens.UnaryOp; // fall through to UnaryOperator;

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

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

                        // PushOperator descriptor
                        ops[topOperator++] = new OperatorInfo(Nodes.Zop, op, Operators.priMax);
                        prevOperand = Expr;
                        goto loop;

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

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

                            if (token == Tokens.Name) {
                                NameNode nameBefore = (NameNode)NodePop();
                                //Debug.WriteLine("Before name '" + nameBefore.name + "'");
                                string newName = nameBefore.name + "." + NameNode.ParseName(text, start, pos);
                                //Debug.WriteLine("Create new NameNode " + newName);
                                NodePush(new NameNode(_table, newName));
                                goto loop;
                            }
                        }
                        // fall through to default
                        goto default;
                    default:
                        throw ExprException.UnknownToken(new string(text, start, pos - start), start+1);
                }
            }
            goto end_loop;
            end_loop:
            Debug.Assert(topNode == 1 || topNode == 0, "Invalid Node Stack");
            expression = NodeStack[0];

            return expression;
        }
Пример #28
0
        public DataRow[] SelectRows() {
            bool needSorting = true;

            InitCandidateColumns();

            if (this.expression is BinaryNode) {
                AnalyzeExpression((BinaryNode)this.expression);
                if (!candidatesForBinarySearch) {
                    this.linearExpression = this.expression;
                }
                if (this.linearExpression == this.expression) {
                    for (int i=0; i<candidateColumns.Length; i++) {
                        if (candidateColumns[i] != null) {
                            candidateColumns[i].equalsOperator = false;
                            candidateColumns[i].expr = null;
                        }
                    }
                }
                else {
                    needSorting = !FindClosestCandidateIndex();
                }
            }
            else {
                this.linearExpression = this.expression;
            }

            if (index == null && (IndexFields.Length > 0 || this.linearExpression == this.expression)) {
                needSorting = !FindSortIndex();
            }

            if (index == null) {
                CreateIndex();
                needSorting = false;
            }

            if (index.RecordCount == 0)
                return table.NewRowArray(0);

            Range range;
            if (matchedCandidates == 0) { // [....] : Either dont have rowFilter or only linear search expression
                range = new Range(0, index.RecordCount-1);
                Debug.Assert(!needSorting, "What are we doing here if no real reuse of this index ?");
                this.linearExpression = this.expression;
                return GetLinearFilteredRows(range);
            }
            else {
                range = GetBinaryFilteredRecords();
                if (range.Count == 0)
                    return table.NewRowArray(0);
                if (matchedCandidates < nCandidates) {
                    BuildLinearExpression();
                }
                if (!needSorting) {
                    return GetLinearFilteredRows(range);
                }
                else {
                    this.records = GetLinearFilteredRecords(range);
                    this.recordCount = this.records.Length;
                    if (this.recordCount == 0)
                        return table.NewRowArray(0);
                    Sort(0, this.recordCount-1);
                    return GetRows();
                }
            }
        }
Пример #29
0
 private bool IsOperatorIn(ExpressionNode enode) {
     BinaryNode bnode = (enode as BinaryNode);
     if (null != bnode) {
         if (Operators.In == bnode.op  ||
             IsOperatorIn(bnode.right) ||
             IsOperatorIn(bnode.left))
         {
             return true;
         }
     }
     return false;
 }
Пример #30
0
        private object EvalFunction(FunctionId id, object[] argumentValues, DataRow row, DataRowVersion version)
        {
            StorageType storageType;

            switch (id)
            {
            case FunctionId.Abs:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());
                if (ExpressionNode.IsInteger(storageType))
                {
                    return(Math.Abs((long)argumentValues[0]));
                }
                if (ExpressionNode.IsNumeric(storageType))
                {
                    return(Math.Abs((double)argumentValues[0]));
                }

                throw ExprException.ArgumentTypeInteger(s_funcs[_info]._name, 1);

            case FunctionId.cBool:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());
                switch (storageType)
                {
                case StorageType.Boolean:
                    return((bool)argumentValues[0]);

                case StorageType.Int32:
                    return((int)argumentValues[0] != 0);

                case StorageType.Double:
                    return((double)argumentValues[0] != 0.0);

                case StorageType.String:
                    return(bool.Parse((string)argumentValues[0]));

                default:
                    throw ExprException.DatatypeConvertion(argumentValues[0].GetType(), typeof(bool));
                }

            case FunctionId.cInt:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToInt32(argumentValues[0], FormatProvider));

            case FunctionId.cDate:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToDateTime(argumentValues[0], FormatProvider));

            case FunctionId.cDbl:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToDouble(argumentValues[0], FormatProvider));

            case FunctionId.cStr:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                return(Convert.ToString(argumentValues[0], FormatProvider));

            case FunctionId.Charindex:
                Debug.Assert(_argumentCount == 2, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));

                Debug.Assert(argumentValues[0] is string, "Invalid argument type for " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[1] is string, "Invalid argument type for " + s_funcs[_info]._name);

                if (DataStorage.IsObjectNull(argumentValues[0]) || DataStorage.IsObjectNull(argumentValues[1]))
                {
                    return(DBNull.Value);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                if (argumentValues[1] is SqlString)
                {
                    argumentValues[1] = ((SqlString)argumentValues[1]).Value;
                }

                return(((string)argumentValues[1]).IndexOf((string)argumentValues[0], StringComparison.Ordinal));

            case FunctionId.Iif:
                Debug.Assert(_argumentCount == 3, "Invalid argument argumentCount: " + _argumentCount.ToString(FormatProvider));

                object first = _arguments[0].Eval(row, version);

                if (DataExpression.ToBoolean(first) != false)
                {
                    return(_arguments[1].Eval(row, version));
                }
                else
                {
                    return(_arguments[2].Eval(row, version));
                }

            case FunctionId.In:
                // we never evaluate IN directly: IN as a binary operator, so evaluation of this should be in
                // BinaryNode class
                throw ExprException.NYI(s_funcs[_info]._name);

            case FunctionId.IsNull:
                Debug.Assert(_argumentCount == 2, "Invalid argument argumentCount: ");

                if (DataStorage.IsObjectNull(argumentValues[0]))
                {
                    return(argumentValues[1]);
                }
                else
                {
                    return(argumentValues[0]);
                }

            case FunctionId.Len:
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid argument type for " + s_funcs[_info]._name);

                if (argumentValues[0] is SqlString)
                {
                    if (((SqlString)argumentValues[0]).IsNull)
                    {
                        return(DBNull.Value);
                    }
                    else
                    {
                        argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                    }
                }

                return(((string)argumentValues[0]).Length);


            case FunctionId.Substring:
                Debug.Assert(_argumentCount == 3, "Invalid argument argumentCount: " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid first argument " + argumentValues[0].GetType().FullName + " in " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[1] is int, "Invalid second argument " + argumentValues[1].GetType().FullName + " in " + s_funcs[_info]._name);
                Debug.Assert(argumentValues[2] is int, "Invalid third argument " + argumentValues[2].GetType().FullName + " in " + s_funcs[_info]._name);

                // work around the differences in .NET and VBA implementation of the Substring function
                // 1. The <index> Argument is 0-based in .NET, and 1-based in VBA
                // 2. If the <Length> argument is longer then the string length .NET throws an ArgumentException
                //    but our users still want to get a result.

                int start = (int)argumentValues[1] - 1;

                int length = (int)argumentValues[2];

                if (start < 0)
                {
                    throw ExprException.FunctionArgumentOutOfRange("index", "Substring");
                }

                if (length < 0)
                {
                    throw ExprException.FunctionArgumentOutOfRange("length", "Substring");
                }

                if (length == 0)
                {
                    return(string.Empty);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                int src_length = ((string)argumentValues[0]).Length;

                if (start > src_length)
                {
                    return(DBNull.Value);
                }

                if (start + length > src_length)
                {
                    length = src_length - start;
                }

                return(((string)argumentValues[0]).Substring(start, length));

            case FunctionId.Trim:
            {
                Debug.Assert(_argumentCount == 1, "Invalid argument argumentCount for " + s_funcs[_info]._name + " : " + _argumentCount.ToString(FormatProvider));
                Debug.Assert((argumentValues[0] is string) || (argumentValues[0] is SqlString), "Invalid argument type for " + s_funcs[_info]._name);

                if (DataStorage.IsObjectNull(argumentValues[0]))
                {
                    return(DBNull.Value);
                }

                if (argumentValues[0] is SqlString)
                {
                    argumentValues[0] = ((SqlString)argumentValues[0]).Value;
                }

                return(((string)argumentValues[0]).Trim());
            }

            case FunctionId.Convert:
                if (_argumentCount != 2)
                {
                    throw ExprException.FunctionArgumentCount(_name);
                }

                if (argumentValues[0] == DBNull.Value)
                {
                    return(DBNull.Value);
                }

                Type        type   = (Type)argumentValues[1];
                StorageType mytype = DataStorage.GetStorageType(type);
                storageType = DataStorage.GetStorageType(argumentValues[0].GetType());

                if (mytype == StorageType.DateTimeOffset)
                {
                    if (storageType == StorageType.String)
                    {
                        return(SqlConvert.ConvertStringToDateTimeOffset((string)argumentValues[0], FormatProvider));
                    }
                }

                if (StorageType.Object != mytype)
                {
                    if ((mytype == StorageType.Guid) && (storageType == StorageType.String))
                    {
                        return(new Guid((string)argumentValues[0]));
                    }

                    if (ExpressionNode.IsFloatSql(storageType) && ExpressionNode.IsIntegerSql(mytype))
                    {
                        if (StorageType.Single == storageType)
                        {
                            return(SqlConvert.ChangeType2((float)SqlConvert.ChangeType2(argumentValues[0], StorageType.Single, typeof(float), FormatProvider), mytype, type, FormatProvider));
                        }
                        else if (StorageType.Double == storageType)
                        {
                            return(SqlConvert.ChangeType2((double)SqlConvert.ChangeType2(argumentValues[0], StorageType.Double, typeof(double), FormatProvider), mytype, type, FormatProvider));
                        }
                        else if (StorageType.Decimal == storageType)
                        {
                            return(SqlConvert.ChangeType2((decimal)SqlConvert.ChangeType2(argumentValues[0], StorageType.Decimal, typeof(decimal), FormatProvider), mytype, type, FormatProvider));
                        }
                        return(SqlConvert.ChangeType2(argumentValues[0], mytype, type, FormatProvider));
                    }

                    return(SqlConvert.ChangeType2(argumentValues[0], mytype, type, FormatProvider));
                }

                return(argumentValues[0]);

            case FunctionId.DateTimeOffset:
                if (argumentValues[0] == DBNull.Value || argumentValues[1] == DBNull.Value || argumentValues[2] == DBNull.Value)
                {
                    return(DBNull.Value);
                }
                switch (((DateTime)argumentValues[0]).Kind)
                {
                case DateTimeKind.Utc:
                    if ((int)argumentValues[1] != 0 && (int)argumentValues[2] != 0)
                    {
                        throw ExprException.MismatchKindandTimeSpan();
                    }
                    break;

                case DateTimeKind.Local:
                    if (DateTimeOffset.Now.Offset.Hours != (int)argumentValues[1] && DateTimeOffset.Now.Offset.Minutes != (int)argumentValues[2])
                    {
                        throw ExprException.MismatchKindandTimeSpan();
                    }
                    break;

                case DateTimeKind.Unspecified: break;
                }
                if ((int)argumentValues[1] < -14 || (int)argumentValues[1] > 14)
                {
                    throw ExprException.InvalidHoursArgument();
                }
                if ((int)argumentValues[2] < -59 || (int)argumentValues[2] > 59)
                {
                    throw ExprException.InvalidMinutesArgument();
                }
                // range should be within -14 hours and  +14 hours
                if ((int)argumentValues[1] == 14 && (int)argumentValues[2] > 0)
                {
                    throw ExprException.InvalidTimeZoneRange();
                }
                if ((int)argumentValues[1] == -14 && (int)argumentValues[2] < 0)
                {
                    throw ExprException.InvalidTimeZoneRange();
                }

                return(new DateTimeOffset((DateTime)argumentValues[0], new TimeSpan((int)argumentValues[1], (int)argumentValues[2], 0)));

            default:
                throw ExprException.UndefinedFunction(s_funcs[_info]._name);
            }
        }
Пример #31
0
        private object EvalBinaryOp(int op, ExpressionNode left, ExpressionNode right, DataRow row, DataRowVersion version, int[] recordNos)
        {
            object vLeft;
            object vRight;
            StorageType resultType;

            /*
            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);
                Type typeofLeft = vLeft.GetType();
                Type typeofRight = vRight.GetType();

                StorageType leftStorage = DataStorage.GetStorageType(typeofLeft);
                StorageType rightStorage = DataStorage.GetStorageType(typeofRight);

                bool leftIsSqlType = DataStorage.IsSqlType(leftStorage);
                bool rightIsSqlType = DataStorage.IsSqlType(rightStorage);

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

                if (leftIsSqlType || rightIsSqlType)
                {
                    resultType = ResultSqlType(leftStorage, rightStorage, (left is ConstNode), (right is ConstNode), op);
                }
                else
                {
                    resultType = ResultType(leftStorage, rightStorage, (left is ConstNode), (right is ConstNode), op);
                }

                if (StorageType.Empty == resultType)
                {
                    SetTypeMismatchError(op, typeofLeft, typeofRight);
                }
            }
            else
            {
                vLeft = vRight = DBNull.Value;
                resultType = StorageType.Empty; // shouldnt we make it boolean?
            }

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

            try
            {
                switch (op)
                {
                    case Operators.Plus:
                        switch (resultType)
                        {
                            case StorageType.Byte:
                                {
                                    value = Convert.ToByte((Convert.ToByte(vLeft, FormatProvider) + Convert.ToByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SByte:
                                {
                                    value = Convert.ToSByte((Convert.ToSByte(vLeft, FormatProvider) + Convert.ToSByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int16:
                                {
                                    value = Convert.ToInt16((Convert.ToInt16(vLeft, FormatProvider) + Convert.ToInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.UInt16:
                                {
                                    value = Convert.ToUInt16((Convert.ToUInt16(vLeft, FormatProvider) + Convert.ToUInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int32:
                                {
                                    checked { value = Convert.ToInt32(vLeft, FormatProvider) + Convert.ToInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.UInt32:
                                {
                                    checked { value = Convert.ToUInt32(vLeft, FormatProvider) + Convert.ToUInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.UInt64:
                                {
                                    checked { value = Convert.ToUInt64(vLeft, FormatProvider) + Convert.ToUInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Int64:
                                {
                                    checked { value = Convert.ToInt64(vLeft, FormatProvider) + Convert.ToInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Decimal:
                                {
                                    checked { value = Convert.ToDecimal(vLeft, FormatProvider) + Convert.ToDecimal(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Single:
                                {
                                    checked { value = Convert.ToSingle(vLeft, FormatProvider) + Convert.ToSingle(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Double:
                                {
                                    checked { value = Convert.ToDouble(vLeft, FormatProvider) + Convert.ToDouble(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.String:
                            case StorageType.Char:
                                {
                                    value = Convert.ToString(vLeft, FormatProvider) + Convert.ToString(vRight, FormatProvider);
                                    break;
                                }
                            case StorageType.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;
                                    }
                                    break;
                                }
                            case StorageType.TimeSpan:
                                {
                                    value = (TimeSpan)vLeft + (TimeSpan)vRight;
                                    break;
                                }
                            case StorageType.SqlInt16:
                                {
                                    value = (SqlConvert.ConvertToSqlInt16(vLeft) + SqlConvert.ConvertToSqlInt16(vRight));
                                    break;
                                }
                            case StorageType.SqlInt32:
                                {
                                    value = (SqlConvert.ConvertToSqlInt32(vLeft) + SqlConvert.ConvertToSqlInt32(vRight));
                                    break;
                                }
                            case StorageType.SqlInt64:
                                {
                                    value = (SqlConvert.ConvertToSqlInt64(vLeft) + SqlConvert.ConvertToSqlInt64(vRight));
                                    break;
                                }
                            case StorageType.SqlDouble:
                                {
                                    value = (SqlConvert.ConvertToSqlDouble(vLeft) + SqlConvert.ConvertToSqlDouble(vRight));
                                    break;
                                }
                            case StorageType.SqlSingle:
                                {
                                    value = (SqlConvert.ConvertToSqlSingle(vLeft) + SqlConvert.ConvertToSqlSingle(vRight));
                                    break;
                                }
                            case StorageType.SqlDecimal:
                                {
                                    value = (SqlConvert.ConvertToSqlDecimal(vLeft) + SqlConvert.ConvertToSqlDecimal(vRight));
                                    break;
                                }
                            case StorageType.SqlMoney:
                                {
                                    value = (SqlConvert.ConvertToSqlMoney(vLeft) + SqlConvert.ConvertToSqlMoney(vRight));
                                    break;
                                }
                            case StorageType.SqlByte:
                                {
                                    value = (SqlConvert.ConvertToSqlByte(vLeft) + SqlConvert.ConvertToSqlByte(vRight));
                                    break;
                                }
                            case StorageType.SqlString:
                                {
                                    value = (SqlConvert.ConvertToSqlString(vLeft) + SqlConvert.ConvertToSqlString(vRight));
                                    break;
                                }
                            case StorageType.SqlDateTime:
                                {
                                    if (vLeft is TimeSpan && vRight is SqlDateTime)
                                    {
                                        SqlDateTime rValue = SqlConvert.ConvertToSqlDateTime(vRight);
                                        value = SqlConvert.ConvertToSqlDateTime((DateTime)rValue.Value + (TimeSpan)vLeft);
                                    }
                                    else if (vLeft is SqlDateTime && vRight is TimeSpan)
                                    {
                                        SqlDateTime lValue = SqlConvert.ConvertToSqlDateTime(vLeft);
                                        value = SqlConvert.ConvertToSqlDateTime((DateTime)lValue.Value + (TimeSpan)vRight);
                                    }
                                    else
                                    {
                                        typeMismatch = true;
                                    }
                                    break;
                                }
                            default:
                                {
                                    typeMismatch = true;
                                    break;
                                }
                        }
                        break; // Operators.Plus

                    case Operators.Minus:
                        switch (resultType)
                        {
                            case StorageType.Byte:
                                {
                                    value = Convert.ToByte((Convert.ToByte(vLeft, FormatProvider) - Convert.ToByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlByte:
                                {
                                    value = (SqlConvert.ConvertToSqlByte(vLeft) - SqlConvert.ConvertToSqlByte(vRight));
                                    break;
                                }
                            case StorageType.SByte:
                                {
                                    value = Convert.ToSByte((Convert.ToSByte(vLeft, FormatProvider) - Convert.ToSByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int16:
                                {
                                    value = Convert.ToInt16((Convert.ToInt16(vLeft, FormatProvider) - Convert.ToInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlInt16:
                                {
                                    value = (SqlConvert.ConvertToSqlInt16(vLeft) - SqlConvert.ConvertToSqlInt16(vRight));
                                    break;
                                }
                            case StorageType.UInt16:
                                {
                                    value = Convert.ToUInt16((Convert.ToUInt16(vLeft, FormatProvider) - Convert.ToUInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int32:
                                {
                                    checked { value = Convert.ToInt32(vLeft, FormatProvider) - Convert.ToInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt32:
                                {
                                    value = (SqlConvert.ConvertToSqlInt32(vLeft) - SqlConvert.ConvertToSqlInt32(vRight));
                                    break;
                                }
                            case StorageType.UInt32:
                                {
                                    checked { value = Convert.ToUInt32(vLeft, FormatProvider) - Convert.ToUInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Int64:
                                {
                                    checked { value = Convert.ToInt64(vLeft, FormatProvider) - Convert.ToInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt64:
                                {
                                    value = (SqlConvert.ConvertToSqlInt64(vLeft) - SqlConvert.ConvertToSqlInt64(vRight));
                                    break;
                                }
                            case StorageType.UInt64:
                                {
                                    checked { value = Convert.ToUInt64(vLeft, FormatProvider) - Convert.ToUInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Decimal:
                                {
                                    checked { value = Convert.ToDecimal(vLeft, FormatProvider) - Convert.ToDecimal(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlDecimal:
                                {
                                    value = (SqlConvert.ConvertToSqlDecimal(vLeft) - SqlConvert.ConvertToSqlDecimal(vRight));
                                    break;
                                }
                            case StorageType.Single:
                                {
                                    checked { value = Convert.ToSingle(vLeft, FormatProvider) - Convert.ToSingle(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlSingle:
                                {
                                    value = (SqlConvert.ConvertToSqlSingle(vLeft) - SqlConvert.ConvertToSqlSingle(vRight));
                                    break;
                                }
                            case StorageType.Double:
                                {
                                    checked { value = Convert.ToDouble(vLeft, FormatProvider) - Convert.ToDouble(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlDouble:
                                {
                                    value = (SqlConvert.ConvertToSqlDouble(vLeft) - SqlConvert.ConvertToSqlDouble(vRight));
                                    break;
                                }
                            case StorageType.SqlMoney:
                                {
                                    value = (SqlConvert.ConvertToSqlMoney(vLeft) - SqlConvert.ConvertToSqlMoney(vRight));
                                    break;
                                }
                            case StorageType.DateTime:
                                {
                                    value = (DateTime)vLeft - (TimeSpan)vRight;
                                    break;
                                }
                            case StorageType.TimeSpan:
                                {
                                    if (vLeft is DateTime)
                                    {
                                        value = (DateTime)vLeft - (DateTime)vRight;
                                    }
                                    else
                                        value = (TimeSpan)vLeft - (TimeSpan)vRight;
                                    break;
                                }
                            case StorageType.SqlDateTime:
                                {
                                    if (vLeft is TimeSpan && vRight is SqlDateTime)
                                    {
                                        SqlDateTime rValue = SqlConvert.ConvertToSqlDateTime(vRight);
                                        value = SqlConvert.ConvertToSqlDateTime((DateTime)rValue.Value - (TimeSpan)vLeft);
                                    }
                                    else if (vLeft is SqlDateTime && vRight is TimeSpan)
                                    {
                                        SqlDateTime lValue = SqlConvert.ConvertToSqlDateTime(vLeft);
                                        value = SqlConvert.ConvertToSqlDateTime((DateTime)lValue.Value - (TimeSpan)vRight);
                                    }
                                    else
                                    {
                                        typeMismatch = true;
                                    }
                                    break;
                                }
                            default:
                                {
                                    typeMismatch = true;
                                    break;
                                }
                        }
                        break; // Operators.Minus

                    case Operators.Multiply:
                        switch (resultType)
                        {
                            case StorageType.Byte:
                                {
                                    value = Convert.ToByte((Convert.ToByte(vLeft, FormatProvider) * Convert.ToByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlByte:
                                {
                                    value = (SqlConvert.ConvertToSqlByte(vLeft) * SqlConvert.ConvertToSqlByte(vRight));
                                    break;
                                }
                            case StorageType.SByte:
                                {
                                    value = Convert.ToSByte((Convert.ToSByte(vLeft, FormatProvider) * Convert.ToSByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int16:
                                {
                                    value = Convert.ToInt16((Convert.ToInt16(vLeft, FormatProvider) * Convert.ToInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlInt16:
                                {
                                    value = (SqlConvert.ConvertToSqlInt16(vLeft) * SqlConvert.ConvertToSqlInt16(vRight));
                                    break;
                                }
                            case StorageType.UInt16:
                                {
                                    value = Convert.ToUInt16((Convert.ToUInt16(vLeft, FormatProvider) * Convert.ToUInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int32:
                                {
                                    checked { value = Convert.ToInt32(vLeft, FormatProvider) * Convert.ToInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt32:
                                {
                                    value = (SqlConvert.ConvertToSqlInt32(vLeft) * SqlConvert.ConvertToSqlInt32(vRight));
                                    break;
                                }
                            case StorageType.UInt32:
                                {
                                    checked { value = Convert.ToUInt32(vLeft, FormatProvider) * Convert.ToUInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Int64:
                                {
                                    checked { value = Convert.ToInt64(vLeft, FormatProvider) * Convert.ToInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt64:
                                {
                                    value = (SqlConvert.ConvertToSqlInt64(vLeft) * SqlConvert.ConvertToSqlInt64(vRight));
                                    break;
                                }
                            case StorageType.UInt64:
                                {
                                    checked { value = Convert.ToUInt64(vLeft, FormatProvider) * Convert.ToUInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Decimal:
                                {
                                    checked { value = Convert.ToDecimal(vLeft, FormatProvider) * Convert.ToDecimal(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlDecimal:
                                {
                                    value = (SqlConvert.ConvertToSqlDecimal(vLeft) * SqlConvert.ConvertToSqlDecimal(vRight));
                                    break;
                                }
                            case StorageType.Single:
                                {
                                    checked { value = Convert.ToSingle(vLeft, FormatProvider) * Convert.ToSingle(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlSingle:
                                {
                                    value = (SqlConvert.ConvertToSqlSingle(vLeft) * SqlConvert.ConvertToSqlSingle(vRight));
                                    break;
                                }
                            case StorageType.SqlMoney:
                                {
                                    value = (SqlConvert.ConvertToSqlMoney(vLeft) * SqlConvert.ConvertToSqlMoney(vRight));
                                    break;
                                }
                            case StorageType.Double:
                                {
                                    checked { value = Convert.ToDouble(vLeft, FormatProvider) * Convert.ToDouble(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlDouble:
                                {
                                    value = (SqlConvert.ConvertToSqlDouble(vLeft) * SqlConvert.ConvertToSqlDouble(vRight));
                                    break;
                                }
                            default:
                                {
                                    typeMismatch = true;
                                    break;
                                }
                        }
                        break; // Operators.Multiply

                    case Operators.Divide:
                        switch (resultType)
                        {
                            case StorageType.Byte:
                                {
                                    value = Convert.ToByte((Convert.ToByte(vLeft, FormatProvider) / Convert.ToByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlByte:
                                {
                                    value = (SqlConvert.ConvertToSqlByte(vLeft) / SqlConvert.ConvertToSqlByte(vRight));
                                    break;
                                }
                            case StorageType.SByte:
                                {
                                    value = Convert.ToSByte((Convert.ToSByte(vLeft, FormatProvider) / Convert.ToSByte(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int16:
                                {
                                    value = Convert.ToInt16((Convert.ToInt16(vLeft, FormatProvider) / Convert.ToInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.SqlInt16:
                                {
                                    value = (SqlConvert.ConvertToSqlInt16(vLeft) / SqlConvert.ConvertToSqlInt16(vRight));
                                    break;
                                }
                            case StorageType.UInt16:
                                {
                                    value = Convert.ToUInt16((Convert.ToUInt16(vLeft, FormatProvider) / Convert.ToUInt16(vRight, FormatProvider)), FormatProvider);
                                    break;
                                }
                            case StorageType.Int32:
                                {
                                    checked { value = Convert.ToInt32(vLeft, FormatProvider) / Convert.ToInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt32:
                                {
                                    value = (SqlConvert.ConvertToSqlInt32(vLeft) / SqlConvert.ConvertToSqlInt32(vRight));
                                    break;
                                }
                            case StorageType.UInt32:
                                {
                                    checked { value = Convert.ToUInt32(vLeft, FormatProvider) / Convert.ToUInt32(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.UInt64:
                                {
                                    checked { value = Convert.ToUInt64(vLeft, FormatProvider) / Convert.ToUInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.Int64:
                                {
                                    checked { value = Convert.ToInt64(vLeft, FormatProvider) / Convert.ToInt64(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlInt64:
                                {
                                    value = (SqlConvert.ConvertToSqlInt64(vLeft) / SqlConvert.ConvertToSqlInt64(vRight));
                                    break;
                                }
                            case StorageType.Decimal:
                                {
                                    checked { value = Convert.ToDecimal(vLeft, FormatProvider) / Convert.ToDecimal(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlDecimal:
                                {
                                    value = (SqlConvert.ConvertToSqlDecimal(vLeft) / SqlConvert.ConvertToSqlDecimal(vRight));
                                    break;
                                }
                            case StorageType.Single:
                                {
                                    checked { value = Convert.ToSingle(vLeft, FormatProvider) / Convert.ToSingle(vRight, FormatProvider); }
                                    break;
                                }
                            case StorageType.SqlSingle:
                                {
                                    value = (SqlConvert.ConvertToSqlSingle(vLeft) / SqlConvert.ConvertToSqlSingle(vRight));
                                    break;
                                }
                            case StorageType.SqlMoney:
                                {
                                    value = (SqlConvert.ConvertToSqlMoney(vLeft) / SqlConvert.ConvertToSqlMoney(vRight));
                                    break;
                                }
                            case StorageType.Double:
                                {
                                    double b = Convert.ToDouble(vRight, FormatProvider);
                                    checked { value = Convert.ToDouble(vLeft, FormatProvider) / b; }
                                    break;
                                }
                            case StorageType.SqlDouble:
                                {
                                    value = (SqlConvert.ConvertToSqlDouble(vLeft) / SqlConvert.ConvertToSqlDouble(vRight));
                                    break;
                                }
                            default:
                                {
                                    typeMismatch = true;
                                    break;
                                }
                        }
                        break; // Operators.Divide

                    case Operators.EqualTo:
                        if ((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)) ||
                             (vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                            return DBNull.Value;
                        return (0 == BinaryCompare(vLeft, vRight, resultType, Operators.EqualTo));

                    case Operators.GreaterThen:
                        if ((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)) ||
                             (vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                            return DBNull.Value;
                        return (0 < BinaryCompare(vLeft, vRight, resultType, op));

                    case Operators.LessThen:
                        if ((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)) ||
                             (vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                            return DBNull.Value;
                        return (0 > BinaryCompare(vLeft, vRight, resultType, op));

                    case Operators.GreaterOrEqual:
                        if ((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)) ||
                             (vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                            return DBNull.Value;
                        return (0 <= BinaryCompare(vLeft, vRight, resultType, op));

                    case Operators.LessOrEqual:
                        if (((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft))) ||
                             ((vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight))))
                            return DBNull.Value;
                        return (0 >= BinaryCompare(vLeft, vRight, resultType, op));

                    case Operators.NotEqual:
                        if (((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft))) ||
                             ((vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight))))
                            return DBNull.Value;
                        return (0 != BinaryCompare(vLeft, vRight, resultType, op));

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

                    case Operators.IsNot:
                        vLeft = BinaryNode.Eval(left, row, version, recordNos);
                        if ((vLeft == DBNull.Value) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)))
                        {
                            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) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)))
                            return DBNull.Value;

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

                        if (vLeft is bool)
                        {
                            if ((bool)vLeft == false)
                            {
                                value = false;
                                break;
                            }
                        }
                        else
                        {
                            if (((SqlBoolean)vLeft).IsFalse)
                            {
                                value = false;
                                break;
                            }
                        }
                        vRight = BinaryNode.Eval(right, row, version, recordNos);
                        if ((vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                            return DBNull.Value;

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

                        if (vRight is bool)
                        {
                            value = (bool)vRight;
                            break;
                        }
                        else
                        {
                            value = ((SqlBoolean)vRight).IsTrue;
                        }
                        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) && (!DataStorage.IsObjectSqlNull(vLeft)))
                        {
                            if ((!(vLeft is bool)) && (!(vLeft is SqlBoolean)))
                            {
                                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) || (DataStorage.IsObjectSqlNull(vRight)))
                            return vLeft;

                        if ((vLeft == DBNull.Value) || (DataStorage.IsObjectSqlNull(vLeft)))
                            return vRight;

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

                        value = (vRight is bool) ? ((bool)vRight) : (((SqlBoolean)vRight).IsTrue);
                        break;

                    /*  for M3, use original code , in below,  and make sure to have two different code path; increases perf

                                        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.IsIntegerSql(resultType))
                        {
                            if (resultType == StorageType.UInt64)
                            {
                                value = Convert.ToUInt64(vLeft, FormatProvider) % Convert.ToUInt64(vRight, FormatProvider);
                            }
                            else if (DataStorage.IsSqlType(resultType))
                            {
                                SqlInt64 res = (SqlConvert.ConvertToSqlInt64(vLeft) % SqlConvert.ConvertToSqlInt64(vRight));

                                if (resultType == StorageType.SqlInt32)
                                {
                                    value = res.ToSqlInt32();
                                }
                                else if (resultType == StorageType.SqlInt16)
                                {
                                    value = res.ToSqlInt16();
                                }
                                else if (resultType == StorageType.SqlByte)
                                {
                                    value = res.ToSqlByte();
                                }
                                else
                                {
                                    value = res;
                                }
                            }
                            else
                            {
                                value = Convert.ToInt64(vLeft, FormatProvider) % Convert.ToInt64(vRight, FormatProvider);
                                value = Convert.ChangeType(value, DataStorage.GetTypeStorage(resultType), FormatProvider);
                            }
                        }
                        else
                        {
                            typeMismatch = true;
                        }
                        break;

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


                        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) || (left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)))
                            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 ((vRight == DBNull.Value) || (right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
                                continue;
                            Debug.Assert((!DataStorage.IsObjectNull(vLeft)) && (!DataStorage.IsObjectNull(vRight)), "Imposible..");

                            resultType = DataStorage.GetStorageType(vLeft.GetType());

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

                    default:
                        throw ExprException.UnsupportedOperator(op);
                }
            }
            catch (OverflowException)
            {
                throw ExprException.Overflow(DataStorage.GetTypeStorage(resultType));
            }
            if (typeMismatch)
            {
                SetTypeMismatchError(op, vLeft.GetType(), vRight.GetType());
            }

            return value;
        }
Пример #32
0
        private object EvalUnaryOp(int op, object vl)
        {
            object value = DBNull.Value;

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

            StorageType storageType;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                throw ExprException.TypeMismatch(ToString());

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

            default:
                throw ExprException.UnsupportedOperator(op);
            }
        }
Пример #33
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;
        }
Пример #34
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];