private int Eval(BinaryNode expr, DataRow row, DataRowVersion version) {
if (expr.op == Operators.And) {
int lResult = Eval((BinaryNode)expr.left,row,version);
if (lResult != 0)
return lResult;
int rResult = Eval((BinaryNode)expr.right,row,version);
if (rResult != 0)
return rResult;
return 0;
}
long c = 0;
object vLeft = expr.left.Eval(row, version);
if (expr.op != Operators.Is && expr.op != Operators.IsNot) {
object vRight = expr.right.Eval(row, version);
bool isLConst = (expr.left is ConstNode);
bool isRConst = (expr.right is ConstNode);
if ((vLeft == DBNull.Value)||(expr.left.IsSqlColumn && DataStorage.IsObjectSqlNull(vLeft)))
return -1;
if ((vRight == DBNull.Value)||(expr.right.IsSqlColumn && DataStorage.IsObjectSqlNull(vRight)))
return 1;
StorageType leftType = DataStorage.GetStorageType(vLeft.GetType());
if (StorageType.Char == leftType) {
if ((isRConst)||(!expr.right.IsSqlColumn))
vRight = Convert.ToChar(vRight, table.FormatProvider);
else
vRight = SqlConvert.ChangeType2(vRight, StorageType.Char, typeof(char), table.FormatProvider);
}
StorageType rightType = DataStorage.GetStorageType(vRight.GetType());
StorageType resultType;
if (expr.left.IsSqlColumn || expr.right.IsSqlColumn) {
resultType = expr.ResultSqlType(leftType, rightType, isLConst, isRConst, expr.op);
}
else {
resultType = expr.ResultType(leftType, rightType, isLConst, isRConst, expr.op);
}
if (StorageType.Empty == resultType) {
expr.SetTypeMismatchError(expr.op, vLeft.GetType(), vRight.GetType());
}
// if comparing a Guid column value against a string literal
// use InvariantCulture instead of DataTable.Locale because in the Danish related cultures
// sorting a Guid as a string has different results than in Invariant and English related cultures.
// This fix is restricted to DataTable.Select("GuidColumn = 'string literal'") types of queries
NameNode namedNode = null;
System.Globalization.CompareInfo comparer =
((isLConst && !isRConst && (leftType == StorageType.String) && (rightType == StorageType.Guid) && (null != (namedNode = expr.right as NameNode)) && (namedNode.column.DataType == typeof(Guid))) ||
(isRConst && !isLConst && (rightType == StorageType.String) && (leftType == StorageType.Guid) && (null != (namedNode = expr.left as NameNode)) && (namedNode.column.DataType == typeof(Guid))))
? System.Globalization.CultureInfo.InvariantCulture.CompareInfo : null;
c = expr.BinaryCompare(vLeft, vRight, resultType, expr.op, comparer);
}
switch(expr.op) {
case Operators.EqualTo: c = (c == 0 ? 0 : c < 0 ? -1 : 1); break;
case Operators.GreaterThen: c = (c > 0 ? 0 : -1); break;
case Operators.LessThen: c = (c < 0 ? 0 : 1); break;
case Operators.GreaterOrEqual: c = (c >= 0 ? 0 : -1); break;
case Operators.LessOrEqual: c = (c <= 0 ? 0 : 1); break;
case Operators.Is: c = (vLeft == DBNull.Value ? 0 : -1); break;
case Operators.IsNot: c = (vLeft != DBNull.Value ? 0 : 1); break;
default: Debug.Assert(true, "Unsupported Binary Search Operator!"); break;
}
return (int)c;
}