public static Expressions.BooleanComparisonType ConvertNot(Expressions.BooleanComparisonType booleanComparisonType, bool isNot) { if (!isNot) { return(booleanComparisonType); } else { //Convert rules according to DeMorgans law switch (booleanComparisonType) { case Expressions.BooleanComparisonType.Equals: return(Expressions.BooleanComparisonType.NotEqualTo); case Expressions.BooleanComparisonType.NotEqualTo: return(Expressions.BooleanComparisonType.Equals); case Expressions.BooleanComparisonType.GreaterThan: return(Expressions.BooleanComparisonType.LessThanOrEqualTo); case Expressions.BooleanComparisonType.GreaterThanOrEqualTo: return(Expressions.BooleanComparisonType.LessThan); case Expressions.BooleanComparisonType.LessThan: return(Expressions.BooleanComparisonType.GreaterThanOrEqualTo); case Expressions.BooleanComparisonType.LessThanOrEqualTo: return(Expressions.BooleanComparisonType.GreaterThan); default: throw new NotImplementedException(); } } }
private void VisitBooleanComparisonExpression(BinaryExpression binaryExpression) { //Check if it is a string compareTo if (FilterUtils.CheckIfStringCompareTo(binaryExpression, _inNot, out var stringComparison)) { _stack.Push(stringComparison); return; } var left = VisitPop <Expressions.ScalarExpression>(binaryExpression.Left); var right = VisitPop <Expressions.ScalarExpression>(binaryExpression.Right); Expressions.BooleanComparisonType booleanComparisonType = FilterUtils.ConvertNot(FilterUtils.ParseBooleanComparisonType(binaryExpression.NodeType), _inNot); _stack.Push(new Expressions.BooleanComparisonExpression() { Type = booleanComparisonType, Left = left, Right = right }); }
public static bool CheckIfStringCompareTo(BinaryExpression binaryExpression, bool isNot, out Expressions.BooleanComparisonExpression stringComparison) { stringComparison = null; //check that it follows: o.prop.CompareTo("text") > < >= <= != == 0 1 -1 if (binaryExpression.Left.NodeType == ExpressionType.Call && binaryExpression.Left is MethodCallExpression methodCallExpression && methodCallExpression.Method.Name == "CompareTo" && methodCallExpression.Object is MemberExpression memberExpression && methodCallExpression.Object.Type.Equals(typeof(string)) && binaryExpression.Right.NodeType == ExpressionType.Constant && binaryExpression.Right is ConstantExpression constantExpression && methodCallExpression.Arguments.Count == 1 && methodCallExpression.Arguments[0] is ConstantExpression argumentExpression) { Expressions.BooleanComparisonType booleanComparisonType = FilterUtils.ParseBooleanComparisonType(binaryExpression.NodeType); var compareValue = (long)Convert.ChangeType(constantExpression.Value, typeof(long)); var convertedComparison = ConvertNot(ConvertBooleanComparisonType(booleanComparisonType, compareValue), isNot); var columnReference = new Expressions.ColumnReference() { Identifiers = new List <string>() { memberExpression.Member.Name } }; stringComparison = new Expressions.BooleanComparisonExpression() { Left = columnReference, Right = new StringLiteral() { Value = (string)argumentExpression.Value }, Type = convertedComparison }; return(true); } return(false); }
/// <summary> /// Converts the current boolean comparison type based on the comparison value. /// </summary> /// <param name="type"></param> /// <param name="val"></param> /// <returns></returns> private static Expressions.BooleanComparisonType ConvertBooleanComparisonType(Expressions.BooleanComparisonType type, long val) { if (val == 0) { return(type); } if (val == -1) { switch (type) { //compareTo == -1 is v1 < v2 case Expressions.BooleanComparisonType.Equals: return(Expressions.BooleanComparisonType.LessThan); //compareTo != -1 is v1 >= v2 case Expressions.BooleanComparisonType.NotEqualTo: return(Expressions.BooleanComparisonType.GreaterThanOrEqualTo); //compareTo > -1 is v1 >= v2 case Expressions.BooleanComparisonType.GreaterThan: return(Expressions.BooleanComparisonType.GreaterThanOrEqualTo); //compareTo >= -1 is always true since it hits -1 0 1 case Expressions.BooleanComparisonType.GreaterThanOrEqualTo: //always true? //TODO throw new Exception("Found a string compareTo that is always true"); //compareTo < -1 is always false, it never hits -1 0 1 case Expressions.BooleanComparisonType.LessThan: //always false, throw exception? throw new Exception("Found a string compareTo that is always false"); //compareTo <= -1 hits -1, is v1 < v2 case Expressions.BooleanComparisonType.LessThanOrEqualTo: return(Expressions.BooleanComparisonType.LessThan); } } else if (val == 1) { switch (type) { //compareTo == 1 is v1 > v2 case Expressions.BooleanComparisonType.Equals: return(Expressions.BooleanComparisonType.GreaterThan); //compareTo != 1 is v1 <= v2 case Expressions.BooleanComparisonType.NotEqualTo: return(Expressions.BooleanComparisonType.LessThanOrEqualTo); //compareTo > 1 is is always false case Expressions.BooleanComparisonType.GreaterThan: throw new Exception("Found a string compareTo that is always false"); break; //compareTo >= 1 is v1 > v2 case Expressions.BooleanComparisonType.GreaterThanOrEqualTo: return(Expressions.BooleanComparisonType.GreaterThan); //compareTo < 1 is v1 <= v2 case Expressions.BooleanComparisonType.LessThan: return(Expressions.BooleanComparisonType.LessThanOrEqualTo); //compareTo <= 1 is always true case Expressions.BooleanComparisonType.LessThanOrEqualTo: //always true //TODO throw new Exception("Found a string compareTo that is always true"); } } //TODO: fix exception throw new Exception("Only use values 0, 1, -1 when comparing strings in compareTo."); }