protected override Expression VisitBinary(BinaryExpression node) { Visit(node.Left); var left = _expression; Visit(node.Right); var right = _expression; Operator @operator; switch (node.NodeType) { case ExpressionType.And: case ExpressionType.AndAlso: @operator = Operator.And; break; case ExpressionType.Or: case ExpressionType.OrElse: @operator = Operator.Or; break; case ExpressionType.ExclusiveOr: @operator = Operator.OperatorXor; break; default: throw new NotSupportedException(node.ToString()); } _expression = new OperatorExpression(@operator) { Branches = new[]{left,right}}; return node; }
protected List<Microsoft.Z3.BoolExpr> VisitBinary(BinaryExpression b) { // Use recursion to generate Z3 constraints for each operand of the binary expression // left side -> create a Z3 expression representing the left side Expression left = Visit(b.Left); // right side -> creat a Z3 expression representing the right side Expression right = Visit(b.Right); // Put those into a Z3 format ExpressionType op = b.NodeType; using (Context ctx = new Context()) { if (op == ExpressionType.LessThan) { // ctx.MkLt(left, right); } } Console.WriteLine(b.ToString()); // TODO - return a Z3 expression return null; }
public void CloseContext(BinaryExpression node) { if(!_contexts.Any()) return; var last = _contexts.Last(); if (last.ContextKey == node.ToString()) { _contexts.Remove(last); } }
public static void Main() { // Numeric comparison var user1 = new User { Age = 13, Name = "Adam" }; var user2 = new User { Age = 33, Name = "John" }; var user3 = new User { Age = 53, Name = "DBag" }; // Equal, NotEqual, GreaterThanOrEqual, GreaterThan, LessThan, LessThanOrEqual var rule = new Rule("Age", "LessThanOrEqual", "33"); Func <User, bool> compiledRule = CompileUserRule <User>(rule); Console.WriteLine("Rule: " + rule.MemberName + " " + rule.Operator + " " + rule.TargetValue); Console.WriteLine("Evaluating Rule:"); Console.WriteLine("\tuser1: Name: " + user1.Name + ", Age: " + user1.Age + " : " + compiledRule(user1)); Console.WriteLine("\tuser2: Name: " + user2.Name + ", Age: " + user2.Age + " : " + compiledRule(user2)); Console.WriteLine("\tuser3: Name: " + user3.Name + ", Age: " + user3.Age + " : " + compiledRule(user3)); // Search within a string var mystring = new simpleString { searchValue = "I got ants!" }; rule = new Rule("searchValue", "Contains", "ants"); Func <simpleString, bool> compiledStringRule = CompileStringRule <simpleString>(rule); compiledStringRule = CompileStringRule <simpleString>(rule); Console.WriteLine("\nRule: " + rule.MemberName + " " + rule.Operator + " " + rule.TargetValue); Console.WriteLine("Evaluating Rule:"); Console.WriteLine("\tsearchValue: \"" + mystring.searchValue + "\" : " + compiledStringRule(mystring)); mystring.searchValue = "If you see something, say something."; Console.WriteLine("\tsearchValue: \"" + mystring.searchValue + "\" : " + compiledStringRule(mystring)); // Dynamic rule creation and execution Console.WriteLine("\nDynamically constructed rule with simple math expression:"); System.Linq.Expressions.BinaryExpression binaryExpression = System.Linq.Expressions.Expression.MakeBinary( System.Linq.Expressions.ExpressionType.Divide, System.Linq.Expressions.Expression.Constant(1000), System.Linq.Expressions.Expression.Constant(20) ); Console.WriteLine("\tRule: " + binaryExpression.ToString()); // Compile the expression. var compiledExpression = Expression.Lambda <Func <int> >(binaryExpression).Compile(); // Execute the expression. Console.WriteLine("\tResult of rule execution: " + compiledExpression()); Console.WriteLine("\nHit any key to exit"); Console.ReadKey(); }
public void OpenContext(ConvertedExpression expression, BinaryExpression node) { if (!SupportedMethods.Contains((expression.Equality ?? string.Empty).TrimStart(ExpressionType.Not.ToString().ToCharArray()))) return; _contexts.Add(new SubQueryContext { Target = expression.Target, ContextKey = node.ToString(), // ReSharper disable PossibleNullReferenceException NegateContext = expression.Equality.StartsWith(ExpressionType.Not.ToString()) // ReSharper restore PossibleNullReferenceException }); }
internal override Expression VisitBinary(BinaryExpression b) { if (ClientType.CheckElementTypeIsEntity(b.Left.Type) || ClientType.CheckElementTypeIsEntity(b.Right.Type) || IsCollectionProducingExpression(b.Left) || IsCollectionProducingExpression(b.Right)) { throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString())); } return base.VisitBinary(b); }
internal override Expression VisitBinary(BinaryExpression b) { throw new NotSupportedException(Strings.ALinq_ExpressionNotSupportedInProjectionToEntity(this.type, b.ToString())); }
protected override Expression VisitBinary(BinaryExpression b) { if (b.NodeType == ExpressionType.Coalesce) { sb.Append("IsNull("); Visit(b.Left); sb.Append(","); Visit(b.Right); sb.Append(")"); } else if (b.NodeType == ExpressionType.Equal || b.NodeType == ExpressionType.NotEqual) { if (b.Left is ConstantExpression) { if (b.Right is ConstantExpression) throw new NotSupportedException("NULL == NULL not supported"); Field field = GetField(b.Right); sb.Append(Equals(field, ((ConstantExpression)b.Left).Value, b.NodeType == ExpressionType.Equal)); } else if (b.Right is ConstantExpression) { Field field = GetField(b.Left); sb.Append(Equals(field, ((ConstantExpression)b.Right).Value, b.NodeType == ExpressionType.Equal)); } else throw new NotSupportedException("Impossible to translate {0}".FormatWith(b.ToString())); } else { sb.Append("("); this.Visit(b.Left); switch (b.NodeType) { case ExpressionType.And: case ExpressionType.AndAlso: sb.Append(b.Type.UnNullify() == typeof(bool) ? " AND " : " & "); break; case ExpressionType.Or: case ExpressionType.OrElse: sb.Append(b.Type.UnNullify() == typeof(bool) ? " OR " : " | "); break; case ExpressionType.ExclusiveOr: sb.Append(" ^ "); break; case ExpressionType.LessThan: sb.Append(" < "); break; case ExpressionType.LessThanOrEqual: sb.Append(" <= "); break; case ExpressionType.GreaterThan: sb.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: sb.Append(" >= "); break; case ExpressionType.Add: case ExpressionType.AddChecked: sb.Append(" + "); break; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: sb.Append(" - "); break; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: sb.Append(" * "); break; case ExpressionType.Divide: sb.Append(" / "); break; case ExpressionType.Modulo: sb.Append(" % "); break; default: throw new NotSupportedException(string.Format("The binary operator {0} is not supported", b.NodeType)); } this.Visit(b.Right); sb.Append(")"); } return b; }
internal override Expression VisitBinary(BinaryExpression b) { if (CommonUtil.IsClientType(b.Left.Type) || CommonUtil.IsClientType(b.Right.Type)) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjection, this.type, b.ToString())); } return base.VisitBinary(b); }
internal override Expression VisitBinary(BinaryExpression b) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, SR.ALinqExpressionNotSupportedInProjectionToEntity, this.type, b.ToString())); }
private string TranslateBinary(BinaryExpression expression) { if (expression.Right.NodeType == ExpressionType.Constant && (((ConstantExpression)expression.Right).Value == null)) { switch (expression.NodeType) { case ExpressionType.Equal: return "(" + Translate(expression.Left) + " IS NULL)"; case ExpressionType.NotEqual: return "(" + Translate(expression.Left) + " IS NOT NULL)"; default: throw new SqlExpressionTranslatorException(expression.ToString()); } } string op; switch (expression.NodeType) { case ExpressionType.Add: case ExpressionType.AddChecked: op = "+"; break; case ExpressionType.AndAlso: op = "AND"; break; case ExpressionType.Coalesce: { string sql = _sqlDialect.SqlFunction(SqlDialect.Function.Coalesce, Translate(expression.Left), Translate(expression.Right)); return expression.Type == typeof (bool) ? TranslateTrue(sql) : sql; } case ExpressionType.Divide: op = "/"; break; case ExpressionType.Equal: op = "="; break; case ExpressionType.GreaterThan: op = ">"; break; case ExpressionType.GreaterThanOrEqual: op = ">="; break; case ExpressionType.LessThan: op = "<"; break; case ExpressionType.LessThanOrEqual: op = "<="; break; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: op = "*"; break; case ExpressionType.NotEqual: op = "<>"; break; case ExpressionType.OrElse: op = "OR"; break; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: op = "-"; break; default: throw new SqlExpressionTranslatorException(expression.ToString()); } return $"({Translate(expression.Left)} {op} {Translate(expression.Right)})"; }
// // Listing 12-36 // /// <summary> /// Performs a sanity check of constant and memberAccess /// Then it performs a different translation according to /// the type of the member to be compared with /// </summary> private Expression VisitBinaryComparison(BinaryExpression b) { // FIRST STEP // We support only a comparison between constant // and a possible Images query parameter ConstantExpression constant = (b.Left as ConstantExpression ?? b.Right as ConstantExpression); MemberExpression memberAccess = (b.Left as MemberExpression ?? b.Right as MemberExpression); // SECOND STEP // Sanity check of parameters if ((memberAccess == null) || (constant == null)) { throw new NotSupportedException( string.Format( "The binary operator '{0}' must compare a valid Images attribute with a constant", b.NodeType)); } // We need to get the constant value if (constant.Value == null) { throw new NotSupportedException( string.Format( "NULL constant is not supported in binary operator {0}", b.ToString())); } switch (Type.GetTypeCode(constant.Value.GetType())) { case TypeCode.String: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Double: break; default: throw new NotSupportedException( string.Format( "Constant {0} is of an unsupported type ({1})", constant.ToString(), constant.Value.GetType().Name)); } // THIRD STEP // Look for member name through Reflection // We assume that string properties in Images have the same name // in QueryParameters // We have a special check for Images members of complex types if (memberAccess.Member.ReflectedType == typeof(DateTime)) { TranslateTimeSpanComparison(b.NodeType, constant, memberAccess); return b; } else if (memberAccess.Member.ReflectedType == typeof(CameraInformation)) { TranslateCameraInformationComparison(constant, memberAccess); return b; } else if (memberAccess.Member.ReflectedType != typeof(ImageInformation)) { throw new NotSupportedException( string.Format( "Member {0} is not of type Images", memberAccess.ToString())); } TranslateStandardComparisons(b.NodeType, constant, memberAccess); return b; }
/// <summary> /// Process binary comparison operators. /// </summary> /// <param name="expression"> /// The expression to visit. /// </param> /// <returns> /// The visited expression. /// </returns> private Expression VisitBinary(BinaryExpression expression) { if (expression != null) { // special case for enums, because we send them as strings UnaryExpression enumExpression = null; ConstantExpression constantExpression = null; BinaryExpression stringCompareExpression = null; if (this.CheckEnumExpression(expression, out enumExpression, out constantExpression)) { this.Visit(this.RewriteEnumExpression(enumExpression, (ConstantExpression)expression.Right, expression.NodeType)); } // special case concat as it's OData function isn't infix else if (expression.NodeType == ExpressionType.Add && expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string)) { //rewrite addition into a call to concat, instead of duplicating generation code. this.Visit(this.RewriteStringAddition(expression)); } // special case for string comparisons emitted by the VB compiler else if (this.CheckVBStringCompareExpression(expression, out stringCompareExpression)) { this.Visit(stringCompareExpression); } else { BinaryOperatorKind operatorKind; switch (expression.NodeType) { case ExpressionType.AndAlso: case ExpressionType.And: operatorKind = BinaryOperatorKind.And; break; case ExpressionType.Or: case ExpressionType.OrElse: operatorKind = BinaryOperatorKind.Or; break; case ExpressionType.Equal: operatorKind = BinaryOperatorKind.Equal; break; case ExpressionType.NotEqual: operatorKind = BinaryOperatorKind.NotEqual; break; case ExpressionType.LessThan: operatorKind = BinaryOperatorKind.LessThan; break; case ExpressionType.LessThanOrEqual: operatorKind = BinaryOperatorKind.LessThanOrEqual; break; case ExpressionType.GreaterThan: operatorKind = BinaryOperatorKind.GreaterThan; break; case ExpressionType.GreaterThanOrEqual: operatorKind = BinaryOperatorKind.GreaterThanOrEqual; break; case ExpressionType.Add: operatorKind = BinaryOperatorKind.Add; break; case ExpressionType.Subtract: operatorKind = BinaryOperatorKind.Subtract; break; case ExpressionType.Multiply: operatorKind = BinaryOperatorKind.Multiply; break; case ExpressionType.Divide: operatorKind = BinaryOperatorKind.Divide; break; case ExpressionType.Modulo: operatorKind = BinaryOperatorKind.Modulo; break; default: throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, "The operator '{0}' is not supported in the 'Where' Mobile Services query expression '{1}'.", expression.NodeType, expression.ToString())); } var node = new BinaryOperatorNode(operatorKind, null, null); this.filterExpression.Push(node); this.Visit(expression.Left); this.Visit(expression.Right); this.SetChildren(node); } } return expression; }
/// <summary> /// Deal with a special case for an index redirection where we are looking for /// an integer or some simply type. There is only one very special case where this /// shows up. Unlikely to be used by physics, actually. :-) The second case we /// handle is dealing with != for two object compares. /// </summary> /// <param name="expression"></param> /// <returns></returns> protected override Expression VisitBinary(BinaryExpression expression) { // // If we are comparing a "new" against a null, then we don't support that. // if (expression.Left.IsNull() || expression.Right.IsNull()) { Expression nonNull = expression.Left.IsNull() ? expression.Right : expression.Left; if (nonNull.NodeType == ExpressionType.New) { throw new InvalidOperationException(string.Format("Doing a null comparison to a temporary object created in the query is very likely to generate incorrect code - not supported ({0})", expression.ToString())); } } // If this is an array index, then... if (expression.NodeType == ExpressionType.ArrayIndex && expression.IsLeafType()) { var rootExpr = expression.Left as MemberExpression; if (rootExpr != null) { return Expression.ArrayIndex(VisitExpressionImplemented(rootExpr), expression.Right); } } // If this is a comparison, and these are objects that have indicies (in whatever we are looping through)... if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { // Are we pointing to something we can deal with? var indexLeft = ExtractIndexReference(expression.Left); if (indexLeft != null) { var indexRight = ExtractIndexReference(expression.Right); if (indexRight != null) { if (expression.NodeType == ExpressionType.NotEqual) { return Expression.NotEqual(indexLeft, indexRight); } else { return Expression.Equal(indexLeft, indexRight); } } } } return base.VisitBinary(expression); }
internal override Expression VisitBinary(BinaryExpression b) { if ((ClientTypeUtil.TypeOrElementTypeIsEntity(b.Left.Type) || ClientTypeUtil.TypeOrElementTypeIsEntity(b.Right.Type)) || (ProjectionAnalyzer.IsCollectionProducingExpression(b.Left) || ProjectionAnalyzer.IsCollectionProducingExpression(b.Right))) { throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_ExpressionNotSupportedInProjection(this.type, b.ToString())); } return base.VisitBinary(b); }
/// <summary> /// Process binary comparison operators. /// </summary> /// <param name="expression"> /// The expression to visit. /// </param> /// <returns> /// The visited expression. /// </returns> private Expression VisitBinary(BinaryExpression expression) { if (expression != null) { // special case for enums, because we send them as strings UnaryExpression enumExpression = null; ConstantExpression constantExpression = null; if (this.CheckEnumExpression(expression, out enumExpression, out constantExpression)) { this.Visit(this.RewriteEnumExpression(enumExpression, (ConstantExpression)expression.Right, expression.NodeType)); } // special case concat as it's OData function isn't infix else if (expression.NodeType == ExpressionType.Add && expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string)) { //rewrite addition into a call to concat, instead of duplicating generation code. this.Visit(this.RewriteStringAddition(expression)); } else { this.filter.Append("("); this.Visit(expression.Left); switch (expression.NodeType) { case ExpressionType.AndAlso: this.filter.Append(" and "); break; case ExpressionType.OrElse: this.filter.Append(" or "); break; case ExpressionType.Equal: this.filter.Append(" eq "); break; case ExpressionType.NotEqual: this.filter.Append(" ne "); break; case ExpressionType.LessThan: this.filter.Append(" lt "); break; case ExpressionType.LessThanOrEqual: this.filter.Append(" le "); break; case ExpressionType.GreaterThan: this.filter.Append(" gt "); break; case ExpressionType.GreaterThanOrEqual: this.filter.Append(" ge "); break; case ExpressionType.Add: this.filter.Append(" add "); break; case ExpressionType.Subtract: this.filter.Append(" sub "); break; case ExpressionType.Multiply: this.filter.Append(" mul "); break; case ExpressionType.Divide: this.filter.Append(" div "); break; case ExpressionType.Modulo: this.filter.Append(" mod "); break; default: throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, Resources.FilterBuildingExpressionVisitor_OperatorUnsupported, expression.NodeType, expression.ToString())); } this.Visit(expression.Right); this.filter.Append(")"); } } return expression; }
private static CriteriaOperator ProcessBinaryExpression(BinaryExpression expression, ParameterOption option) { switch (expression.NodeType) { case ExpressionType.AndAlso: return ProcessAndExpression(expression, option); case ExpressionType.OrElse: return ProcessOrExpression(expression, option); case ExpressionType.Equal: case ExpressionType.NotEqual: case ExpressionType.GreaterThan: case ExpressionType.GreaterThanOrEqual: case ExpressionType.LessThan: case ExpressionType.LessThanOrEqual: if (IsMemberExpression(expression.Right)) return ProcessMemberExpression(expression, option); else return ProcessSimpleExpression(expression, option); default: throw new Exception("Unhandled binary expression: " + expression.NodeType + ", " + expression.ToString()); } }
/// <summary> /// Process binary comparison operators. /// </summary> /// <param name="expression">The expression to visit.</param> /// <returns>The visited expression.</returns> protected override Expression VisitBinary(BinaryExpression expression) { if (expression != null) { // Special case concat as it's OData function isn't infix if (expression.NodeType == ExpressionType.Add && expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string)) { this.filter.Append("concat("); this.Visit(expression.Left); this.filter.Append(","); this.Visit(expression.Right); this.filter.Append(")"); } else { this.filter.Append("("); this.Visit(expression.Left); switch (expression.NodeType) { case ExpressionType.AndAlso: this.filter.Append(" and "); break; case ExpressionType.OrElse: this.filter.Append(" or "); break; case ExpressionType.Equal: this.filter.Append(" eq "); break; case ExpressionType.NotEqual: this.filter.Append(" ne "); break; case ExpressionType.LessThan: this.filter.Append(" lt "); break; case ExpressionType.LessThanOrEqual: this.filter.Append(" le "); break; case ExpressionType.GreaterThan: this.filter.Append(" gt "); break; case ExpressionType.GreaterThanOrEqual: this.filter.Append(" ge "); break; case ExpressionType.Add: this.filter.Append(" add "); break; case ExpressionType.Subtract: this.filter.Append(" sub "); break; case ExpressionType.Multiply: this.filter.Append(" mul "); break; case ExpressionType.Divide: this.filter.Append(" div "); break; case ExpressionType.Modulo: this.filter.Append(" mod "); break; default: throw new NotSupportedException( string.Format( CultureInfo.InvariantCulture, Resources.FilterBuildingExpressionVisitor_VisitOperator_Unsupported, expression.NodeType, expression.ToString())); } this.Visit(expression.Right); this.filter.Append(")"); } this.MarkVisited(); } return expression; }
private static string ExtractOperator(BinaryExpression binary) { string op = Regex.Match(binary.ToString(), " (==|=|!=|<=|>=|<|>) ").Groups[1].Value; if (op == "==" ||op =="=") return "should equal"; if (op == "!=") return "should not equal"; if (op == "<=") return "should be less than or equal to"; if (op == "<") return "should be less than"; if (op == ">=") return "should be greater than or equal to"; if (op == ">") return "should be greater than"; return "should " + op; }