private SqlExpression OptimizeCompareTo( SqlBinaryExpression sqlBinaryExpression, int intValue, CaseExpression caseExpression) { var testLeft = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Left; var testRight = ((SqlBinaryExpression)caseExpression.WhenClauses[0].Test).Right; var operatorType = sqlBinaryExpression.Right is SqlConstantExpression ? sqlBinaryExpression.OperatorType : sqlBinaryExpression.OperatorType switch { ExpressionType.GreaterThan => ExpressionType.LessThan, ExpressionType.GreaterThanOrEqual => ExpressionType.LessThanOrEqual, ExpressionType.LessThan => ExpressionType.GreaterThan, ExpressionType.LessThanOrEqual => ExpressionType.GreaterThanOrEqual, _ => sqlBinaryExpression.OperatorType }; switch (operatorType) { // CompareTo(a, b) != 0 -> a != b // CompareTo(a, b) != 1 -> a <= b // CompareTo(a, b) != -1 -> a >= b case ExpressionType.NotEqual: return((SqlExpression)Visit(intValue switch { 0 => _sqlExpressionFactory.NotEqual(testLeft, testRight), 1 => _sqlExpressionFactory.LessThanOrEqual(testLeft, testRight), _ => _sqlExpressionFactory.GreaterThanOrEqual(testLeft, testRight), }));
public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments) { if (method == IPAddressParse) { return(_sqlExpressionFactory.Convert(arguments[0], typeof(IPAddress), _sqlExpressionFactory.FindMapping(typeof(IPAddress)))); } if (method == PhysicalAddressParse) { return(_sqlExpressionFactory.Convert(arguments[0], typeof(PhysicalAddress), _sqlExpressionFactory.FindMapping(typeof(PhysicalAddress)))); } if (method.DeclaringType != typeof(NpgsqlNetworkExtensions)) { return(null); } return(method.Name switch { nameof(NpgsqlNetworkExtensions.LessThan) => _sqlExpressionFactory.LessThan(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.LessThanOrEqual) => _sqlExpressionFactory.LessThanOrEqual(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.GreaterThanOrEqual) => _sqlExpressionFactory.GreaterThanOrEqual(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.GreaterThan) => _sqlExpressionFactory.GreaterThan(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.ContainedBy) => BoolReturningOnTwoNetworkTypes("<<"), nameof(NpgsqlNetworkExtensions.ContainedByOrEqual) => BoolReturningOnTwoNetworkTypes("<<="), nameof(NpgsqlNetworkExtensions.Contains) => BoolReturningOnTwoNetworkTypes(">>"), nameof(NpgsqlNetworkExtensions.ContainsOrEqual) => BoolReturningOnTwoNetworkTypes(">>="), nameof(NpgsqlNetworkExtensions.ContainsOrContainedBy) => BoolReturningOnTwoNetworkTypes("&&"), // TODO: Hack, see #1118 nameof(NpgsqlNetworkExtensions.BitwiseNot) => new SqlUnaryExpression(ExpressionType.Negate, arguments[1], arguments[1].Type, arguments[1].TypeMapping), nameof(NpgsqlNetworkExtensions.BitwiseAnd) => _sqlExpressionFactory.And(arguments[1], arguments[2]), nameof(NpgsqlNetworkExtensions.BitwiseOr) => _sqlExpressionFactory.Or(arguments[1], arguments[2]), // Add/Subtract accept inet + int, so we can't use the default type mapping inference logic which assumes // same-typed operands nameof(NpgsqlNetworkExtensions.Add) => new SqlBinaryExpression( ExpressionType.Add, _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[1]), _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[2]), arguments[1].Type, arguments[1].TypeMapping), nameof(NpgsqlNetworkExtensions.Subtract) when arguments[2].Type == typeof(int)
/// <inheritdoc/> public virtual SqlExpression?Translate( SqlExpression?instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(method, nameof(method)); Check.NotNull(arguments, nameof(arguments)); Check.NotNull(logger, nameof(logger)); if (_methodInfoDatePartMapping.TryGetValue(method, out var value)) { var start = _sqlExpressionFactory.GreaterThanOrEqual(arguments[0], arguments[1]); var end = _sqlExpressionFactory.LessThanOrEqual(arguments[0], arguments[2]); return(_sqlExpressionFactory.AndAlso(start, end)); } return(null); }