protected override Expression VisitBinaryExpression(BinaryExpression expression) { // handle special cases if (expression.NodeType == ExpressionType.Equal) { if (HandleAddressOrIdEquals(expression.Left, expression.Right)) { return(expression); } } if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { if (HandleEqualsNotEquals(expression)) { return(expression); } var leftPropertyHint = GetPropertyHint(expression.Left); var rightPropertyHint = GetPropertyHint(expression.Right); var leftIsAddress = leftPropertyHint != null && (leftPropertyHint.MappingType == PropertyMappingType.Address || leftPropertyHint.MappingType == PropertyMappingType.Id); var rightIsAddress = rightPropertyHint != null && (rightPropertyHint.MappingType == PropertyMappingType.Address || rightPropertyHint.MappingType == PropertyMappingType.Id); //handle checking for nulls (bug 5416) /* * if (rightPropertyHint == null && expression.Right.NodeType == ExpressionType.Constant) * { * var constantExpression = expression.Right as ConstantExpression; * var value = constantExpression.Value; * var defValue = expression.Left.Type.GetDefaultValue(); * if ((value == null && defValue == null) || (value != null && value.Equals(defValue))) * { * if (leftIsAddress) * { * var querySourceReferenceExpression = * ((MemberExpression) expression.Left).Expression as QuerySourceReferenceExpression; * var varname = querySourceReferenceExpression.ReferencedQuerySource.ItemName; * * var filter = expression.NodeType == ExpressionType.NotEqual * ? "( bound(?{0}))" * : "(!bound(?{0}))"; * _filterWriter.AppendFormat(filter, varname); * return expression; * } * else * { * string varname = null; * QueryBuilder.StartOptional(); * var convertedExpression = VisitExpression(expression.Left); * QueryBuilder.EndOptional(); * if (convertedExpression is SelectVariableNameExpression) * { * varname = (convertedExpression as SelectVariableNameExpression).Name; * } * if (varname != null) * { * string filter; * if (expression.Left.Type.IsValueType && defValue != null) * { * filter = expression.NodeType == ExpressionType.NotEqual * ? "(bound(?{0}) && (?{0} != {1}))" * : "(!bound(?{0}) || (?{0} = {1}))"; * } * else * { * filter = expression.NodeType == ExpressionType.NotEqual * ? "( bound(?{0}))" * : "(!bound(?{0}))"; * } * if (defValue != null) * { * _filterWriter.AppendFormat(filter, varname, * _filterWriter.MakeSparqlConstant(defValue)); * } * else * { * _filterWriter.AppendFormat(filter, varname); * } * return expression; * } * } * } * } * * if (leftIsAddress && expression.Right.NodeType == ExpressionType.Constant) * { * var querySourceReferenceExpression = ((MemberExpression)expression.Left).Expression as QuerySourceReferenceExpression; * var varname = querySourceReferenceExpression.ReferencedQuerySource.ItemName; * * var constantExpression = expression.Right as ConstantExpression; * var value = constantExpression.Value.ToString(); * * var filter = expression.NodeType == ExpressionType.Equal * ? "( sameTerm(?{0}, <{1}>))" * : "(!sameTerm(?{0}, <{1}>))"; * * _filterWriter.AppendFormat(filter, varname, MakeResourceAddress(GetPropertyInfo(expression.Right), value)); * return expression; * } * * if (rightIsAddress && expression.Left.NodeType == ExpressionType.Constant) * { * var querySourceReferenceExpression = * ((MemberExpression) expression.Right).Expression as QuerySourceReferenceExpression; * var varname = querySourceReferenceExpression.ReferencedQuerySource.ItemName; * var constantExpression = expression.Left as ConstantExpression; * var value = constantExpression.Value.ToString(); * var filter = expression.NodeType == ExpressionType.Equal * ? "(sameTerm(<{0}>,?{1}))" * : "(!sameTerm(?{0}, <{1}>))"; * _filterWriter.AppendFormat(filter, MakeResourceAddress(GetPropertyInfo(expression.Left), value), varname); * } */ if (leftIsAddress && rightIsAddress) { // Comparing two resource addresses - use the sameTerm function rather then simple equality _filterWriter.Append(expression.NodeType == ExpressionType.Equal ? "(sameTerm(" : "(!sameTerm("); _filterWriter.VisitExpression(expression.Left); _filterWriter.Append(","); _filterWriter.VisitExpression(expression.Right); _filterWriter.Append("))"); return(expression); } } var mce = expression.Left as MethodCallExpression; if (mce != null && mce.Method.Name.Equals("Compare")) { //handle compare (bug 5441) HandleCompareExpression(mce, expression.NodeType); return(expression); } // Process operators that translate to SPARQL functions switch (expression.NodeType) { case ExpressionType.Or: _filterWriter.WriteFunction(BrightstarDB.Query.BrightstarFunctionFactory.BrightstarFunctionsNamespace, BrightstarDB.Query.BrightstarFunctionFactory.BitOr, expression.Left, expression.Right); return(expression); case ExpressionType.And: _filterWriter.WriteFunction(BrightstarDB.Query.BrightstarFunctionFactory.BrightstarFunctionsNamespace, BrightstarDB.Query.BrightstarFunctionFactory.BitAnd, expression.Left, expression.Right); return(expression); } // Process in-fix operator _filterWriter.Append('('); _filterWriter.VisitExpression(expression.Left); switch (expression.NodeType) { case ExpressionType.Add: case ExpressionType.AddChecked: _filterWriter.Append(" + "); break; case ExpressionType.AndAlso: _filterWriter.Append(" && "); break; case ExpressionType.Divide: _filterWriter.Append(" / "); break; case ExpressionType.Equal: _filterWriter.Append(" = "); break; case ExpressionType.GreaterThan: _filterWriter.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: _filterWriter.Append(" >= "); break; case ExpressionType.LessThan: _filterWriter.Append(" < "); break; case ExpressionType.LessThanOrEqual: _filterWriter.Append(" <= "); break; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: _filterWriter.Append(" * "); break; case ExpressionType.NotEqual: _filterWriter.Append(" != "); break; case ExpressionType.OrElse: _filterWriter.Append(" || "); break; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: _filterWriter.Append(" - "); break; default: base.VisitBinaryExpression(expression); break; } _filterWriter.VisitExpression(expression.Right); _filterWriter.Append(')'); return(expression); }
private Expression HandleBinaryExpression(BinaryExpression expression) { // handle special cases if (expression.NodeType == ExpressionType.Equal) { if (HandleAddressOrIdEquals(expression.Left, expression.Right)) { return(expression); } } if (expression.NodeType == ExpressionType.Equal || expression.NodeType == ExpressionType.NotEqual) { if (HandleEqualsNotEquals(expression)) { return(expression); } var leftPropertyHint = GetPropertyHint(expression.Left); var rightPropertyHint = GetPropertyHint(expression.Right); var leftIsAddress = leftPropertyHint != null && (leftPropertyHint.MappingType == PropertyMappingType.Address || leftPropertyHint.MappingType == PropertyMappingType.Id); var rightIsAddress = rightPropertyHint != null && (rightPropertyHint.MappingType == PropertyMappingType.Address || rightPropertyHint.MappingType == PropertyMappingType.Id); if (leftIsAddress && rightIsAddress) { // Comparing two resource addresses - use the sameTerm function rather then simple equality _filterWriter.Append(expression.NodeType == ExpressionType.Equal ? "(sameTerm(" : "(!sameTerm("); _filterWriter.VisitExpression(expression.Left); _filterWriter.Append(","); _filterWriter.VisitExpression(expression.Right); _filterWriter.Append("))"); return(expression); } } var mce = expression.Left as MethodCallExpression; if (mce != null && mce.Method.Name.Equals("Compare")) { //handle compare (bug 5441) HandleCompareExpression(mce, expression.NodeType); return(expression); } // Process operators that translate to SPARQL functions switch (expression.NodeType) { case ExpressionType.Or: _filterWriter.WriteFunction(BrightstarFunctionFactory.BrightstarFunctionsNamespace, BrightstarFunctionFactory.BitOr, expression.Left, expression.Right); return(expression); case ExpressionType.And: _filterWriter.WriteFunction(BrightstarFunctionFactory.BrightstarFunctionsNamespace, BrightstarFunctionFactory.BitAnd, expression.Left, expression.Right); return(expression); } // Process in-fix operator if (_optimizeFilter) { switch (expression.NodeType) { case ExpressionType.Equal: QueryBuilder.StartBgpGroup(); AppendOptimisedEqualityExpression(expression.Left, expression.Right); QueryBuilder.EndBgpGroup(); break; case ExpressionType.NotEqual: QueryBuilder.StartMinus(); AppendOptimisedEqualityExpression(expression.Left, expression.Right); QueryBuilder.EndMinus(); break; case ExpressionType.OrElse: _inBooleanExpression = true; QueryBuilder.StartBgpGroup(); VisitExpression(expression.Left); QueryBuilder.EndBgpGroup(); QueryBuilder.Union(); QueryBuilder.StartBgpGroup(); VisitExpression(expression.Right); QueryBuilder.EndBgpGroup(); _inBooleanExpression = false; break; case ExpressionType.AndAlso: _inBooleanExpression = true; VisitExpression(expression.Left); VisitExpression(expression.Right); _inBooleanExpression = false; break; default: throw new NotSupportedException(); } } else { _filterWriter.Append('('); _filterWriter.VisitExpression(expression.Left); switch (expression.NodeType) { case ExpressionType.Add: case ExpressionType.AddChecked: _filterWriter.Append(" + "); break; case ExpressionType.AndAlso: _filterWriter.Append(" && "); break; case ExpressionType.Divide: _filterWriter.Append(" / "); break; case ExpressionType.Equal: _filterWriter.Append(" = "); break; case ExpressionType.GreaterThan: _filterWriter.Append(" > "); break; case ExpressionType.GreaterThanOrEqual: _filterWriter.Append(" >= "); break; case ExpressionType.LessThan: _filterWriter.Append(" < "); break; case ExpressionType.LessThanOrEqual: _filterWriter.Append(" <= "); break; case ExpressionType.Multiply: case ExpressionType.MultiplyChecked: _filterWriter.Append(" * "); break; case ExpressionType.NotEqual: _filterWriter.Append(" != "); break; case ExpressionType.OrElse: _filterWriter.Append(" || "); break; case ExpressionType.Subtract: case ExpressionType.SubtractChecked: _filterWriter.Append(" - "); break; default: base.VisitBinaryExpression(expression); break; } _filterWriter.VisitExpression(expression.Right); _filterWriter.Append(')'); } return(expression); }