private HqlTreeNode TranslateEqualityComparison(BinaryExpression expression) { var lhs = VisitExpression(expression.Left).ToArithmeticExpression(); var rhs = VisitExpression(expression.Right).ToArithmeticExpression(); // Check for nulls on left or right. if (VisitorUtil.IsNullConstant(expression.Right)) { rhs = null; } if (VisitorUtil.IsNullConstant(expression.Left)) { lhs = null; } if (lhs == null && rhs == null) { return(_hqlTreeBuilder.True()); } if (lhs == null) { return(_hqlTreeBuilder.IsNull(rhs)); } if (rhs == null) { return(_hqlTreeBuilder.IsNull((lhs))); } var lhsNullable = IsNullable(lhs); var rhsNullable = IsNullable(rhs); var equality = _hqlTreeBuilder.Equality(lhs, rhs); if (!lhsNullable || !rhsNullable) { return(equality); } var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression(); var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression(); return(_hqlTreeBuilder.BooleanOr( equality, _hqlTreeBuilder.BooleanAnd( _hqlTreeBuilder.IsNull(lhs2), _hqlTreeBuilder.IsNull(rhs2)))); }
protected override Expression VisitMethodCall(MethodCallExpression expression) { if (expression.Method.Name == nameof(LinqExtensionMethods.MappedAs) && expression.Method.DeclaringType == typeof(LinqExtensionMethods)) { var rawParameter = Visit(expression.Arguments[0]); var parameter = rawParameter as ConstantExpression; var type = expression.Arguments[1] as ConstantExpression; if (parameter == null) { throw new HibernateException( $"{nameof(LinqExtensionMethods.MappedAs)} must be called on an expression which can be evaluated as " + $"{nameof(ConstantExpression)}. It was call on {rawParameter?.GetType().Name ?? "null"} instead."); } if (type == null) { throw new HibernateException( $"{nameof(LinqExtensionMethods.MappedAs)} type must be supplied as {nameof(ConstantExpression)}. " + $"It was {expression.Arguments[1]?.GetType().Name ?? "null"} instead."); } _parameters[parameter].Type = (IType)type.Value; return(parameter); } var method = expression.Method.IsGenericMethod ? expression.Method.GetGenericMethodDefinition() : expression.Method; if (_pagingMethods.Contains(method) && !_sessionFactory.Dialect.SupportsVariableLimit) { //TODO: find a way to make this code cleaner var query = Visit(expression.Arguments[0]); var arg = expression.Arguments[1]; if (query == expression.Arguments[0]) { return(expression); } return(Expression.Call(null, expression.Method, query, arg)); } if (VisitorUtil.IsDynamicComponentDictionaryGetter(expression, _sessionFactory)) { return(expression); } return(base.VisitMethodCall(expression)); }
private static bool IsConstructionToNullComparison(Expression expression) { var testExpression = expression as BinaryExpression; if (testExpression != null) { if ((IsConstruction(testExpression.Left) && VisitorUtil.IsNullConstant(testExpression.Right)) || (IsConstruction(testExpression.Right) && VisitorUtil.IsNullConstant(testExpression.Left))) { return(true); } } return(false); }
protected override Expression VisitConditional(ConditionalExpression expression) { var testExpression = Visit(expression.Test); bool testExprResult; if (VisitorUtil.IsBooleanConstant(testExpression, out testExprResult)) { if (testExprResult) { return(Visit(expression.IfTrue)); } return(Visit(expression.IfFalse)); } return(base.VisitConditional(expression)); }
protected override Expression VisitBinary(BinaryExpression expression) { var result = base.VisitBinary(expression); if (expression.NodeType == ExpressionType.AndAlso) { HandleBinaryOperation((a, b) => a.AndAlso(b)); } else if (expression.NodeType == ExpressionType.OrElse) { HandleBinaryOperation((a, b) => a.OrElse(b)); } else if (expression.NodeType == ExpressionType.NotEqual && VisitorUtil.IsNullConstant(expression.Right)) { // Discard result from right null. Left is visited first, so it's below right on the stack. _values.Pop(); HandleUnaryOperation(pvs => pvs.IsNotNull()); } else if (expression.NodeType == ExpressionType.NotEqual && VisitorUtil.IsNullConstant(expression.Left)) { // Discard result from left null. var right = _values.Pop(); _values.Pop(); // Discard left. _values.Push(right); HandleUnaryOperation(pvs => pvs.IsNotNull()); } else if (expression.NodeType == ExpressionType.Equal && VisitorUtil.IsNullConstant(expression.Right)) { // Discard result from right null. Left is visited first, so it's below right on the stack. _values.Pop(); HandleUnaryOperation(pvs => pvs.IsNull()); } else if (expression.NodeType == ExpressionType.Equal && VisitorUtil.IsNullConstant(expression.Left)) { // Discard result from left null. var right = _values.Pop(); _values.Pop(); // Discard left. _values.Push(right); HandleUnaryOperation(pvs => pvs.IsNull()); } else if (expression.NodeType == ExpressionType.Coalesce) { HandleBinaryOperation((a, b) => a.Coalesce(b)); } else if (expression.NodeType == ExpressionType.Add || expression.NodeType == ExpressionType.AddChecked) { HandleBinaryOperation((a, b) => a.Add(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Divide) { HandleBinaryOperation((a, b) => a.Divide(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Modulo) { HandleBinaryOperation((a, b) => a.Modulo(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Multiply || expression.NodeType == ExpressionType.MultiplyChecked) { HandleBinaryOperation((a, b) => a.Multiply(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Power) { HandleBinaryOperation((a, b) => a.Power(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Subtract || expression.NodeType == ExpressionType.SubtractChecked) { HandleBinaryOperation((a, b) => a.Subtract(b, expression.Type)); } else if (expression.NodeType == ExpressionType.And) { HandleBinaryOperation((a, b) => a.And(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Or) { HandleBinaryOperation((a, b) => a.Or(b, expression.Type)); } else if (expression.NodeType == ExpressionType.ExclusiveOr) { HandleBinaryOperation((a, b) => a.ExclusiveOr(b, expression.Type)); } else if (expression.NodeType == ExpressionType.LeftShift) { HandleBinaryOperation((a, b) => a.LeftShift(b, expression.Type)); } else if (expression.NodeType == ExpressionType.RightShift) { HandleBinaryOperation((a, b) => a.RightShift(b, expression.Type)); } else if (expression.NodeType == ExpressionType.Equal) { HandleBinaryOperation((a, b) => a.Equal(b)); } else if (expression.NodeType == ExpressionType.NotEqual) { HandleBinaryOperation((a, b) => a.NotEqual(b)); } else if (expression.NodeType == ExpressionType.GreaterThanOrEqual) { HandleBinaryOperation((a, b) => a.GreaterThanOrEqual(b)); } else if (expression.NodeType == ExpressionType.GreaterThan) { HandleBinaryOperation((a, b) => a.GreaterThan(b)); } else if (expression.NodeType == ExpressionType.LessThan) { HandleBinaryOperation((a, b) => a.LessThan(b)); } else if (expression.NodeType == ExpressionType.LessThanOrEqual) { HandleBinaryOperation((a, b) => a.LessThanOrEqual(b)); } return(result); }
private HqlTreeNode TranslateInequalityComparison(BinaryExpression expression) { var lhs = VisitExpression(expression.Left).ToArithmeticExpression(); var rhs = VisitExpression(expression.Right).ToArithmeticExpression(); // Check for nulls on left or right. if (VisitorUtil.IsNullConstant(expression.Right)) { rhs = null; } if (VisitorUtil.IsNullConstant(expression.Left)) { lhs = null; } if (lhs == null && rhs == null) { return(_hqlTreeBuilder.False()); } if (lhs == null) { return(_hqlTreeBuilder.IsNotNull(rhs)); } if (rhs == null) { return(_hqlTreeBuilder.IsNotNull(lhs)); } var lhsNullable = IsNullable(lhs); var rhsNullable = IsNullable(rhs); var inequality = _hqlTreeBuilder.Inequality(lhs, rhs); if (!lhsNullable && !rhsNullable) { return(inequality); } var lhs2 = VisitExpression(expression.Left).ToArithmeticExpression(); var rhs2 = VisitExpression(expression.Right).ToArithmeticExpression(); HqlBooleanExpression booleanExpression; if (lhsNullable && rhsNullable) { booleanExpression = _hqlTreeBuilder.Inequality( _hqlTreeBuilder.IsNull(lhs2).ToArithmeticExpression(), _hqlTreeBuilder.IsNull(rhs2).ToArithmeticExpression()); } else if (lhsNullable) { booleanExpression = _hqlTreeBuilder.IsNull(lhs2); } else { booleanExpression = _hqlTreeBuilder.IsNull(rhs2); } return(_hqlTreeBuilder.BooleanOr(inequality, booleanExpression)); }