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; } } }
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; }
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; }
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; }
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(); } }
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; }
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; }
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; }
// 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 }
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; } }
// 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; }
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(); } } }
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); } }
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; }
internal LikeNode(DataTable table, int op, ExpressionNode left, ExpressionNode right) : base(table, op, left, right) { }
internal UnaryNode(DataTable table, int op, ExpressionNode right) : base(table) { _op = op; _right = right; }
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; }
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(); } } }
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; }
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); } }
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; }
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); } }
// [....] : 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; }
// 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];