protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression) { var parentSearchCondition = _isSearchCondition; bool resultCondition; switch (sqlUnaryExpression.OperatorType) { case ExpressionType.Not: _isSearchCondition = true; resultCondition = true; break; case ExpressionType.Convert: case ExpressionType.Negate: _isSearchCondition = false; resultCondition = false; break; default: _isSearchCondition = false; resultCondition = true; break; } var operand = (SqlExpression)Visit(sqlUnaryExpression.Operand); _isSearchCondition = parentSearchCondition; return(ApplyConversion(sqlUnaryExpression.Update(operand), condition: resultCondition)); }
protected override Expression VisitSqlUnary(SqlUnaryExpression sqlUnaryExpression) { var parentSearchCondition = _isSearchCondition; bool resultCondition; switch (sqlUnaryExpression.OperatorType) { case ExpressionType.Not: _isSearchCondition = true; resultCondition = true; break; case ExpressionType.Convert: case ExpressionType.Negate: _isSearchCondition = false; resultCondition = false; break; case ExpressionType.Equal: case ExpressionType.NotEqual: _isSearchCondition = false; resultCondition = true; break; default: throw new InvalidOperationException("Unknown operator type encountered in SqlUnaryExpression."); } var operand = (SqlExpression)Visit(sqlUnaryExpression.Operand); _isSearchCondition = parentSearchCondition; return(ApplyConversion(sqlUnaryExpression.Update(operand), condition: resultCondition)); }
private SqlUnaryExpression VisitSqlUnaryExpression(SqlUnaryExpression sqlUnaryExpression) { var newOperand = (SqlExpression)Visit(sqlUnaryExpression.Operand); // IsNull/IsNotNull if (sqlUnaryExpression.OperatorType == ExpressionType.Equal || sqlUnaryExpression.OperatorType == ExpressionType.NotEqual) { _isNullable = false; } return(sqlUnaryExpression.Update(newOperand)); }
private Expression VisitSqlUnaryExpression(SqlUnaryExpression sqlUnaryExpression) { if (sqlUnaryExpression.OperatorType == ExpressionType.Not) { return(VisitNot(sqlUnaryExpression)); } // NULL IS NULL -> true // non_nullablee_constant IS NULL -> false if (sqlUnaryExpression.OperatorType == ExpressionType.Equal && sqlUnaryExpression.Operand is SqlConstantExpression innerConstantNull1) { return(_sqlExpressionFactory.Constant(innerConstantNull1.Value == null, sqlUnaryExpression.TypeMapping)); } // NULL IS NOT NULL -> false // non_nullablee_constant IS NOT NULL -> true if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual && sqlUnaryExpression.Operand is SqlConstantExpression innerConstantNull2) { return(_sqlExpressionFactory.Constant(innerConstantNull2.Value != null, sqlUnaryExpression.TypeMapping)); } if (sqlUnaryExpression.Operand is SqlUnaryExpression innerUnary) { // (!a) IS NULL <==> a IS NULL if (sqlUnaryExpression.OperatorType == ExpressionType.Equal && innerUnary.OperatorType == ExpressionType.Not) { return(Visit(_sqlExpressionFactory.IsNull(innerUnary.Operand))); } // (!a) IS NOT NULL <==> a IS NOT NULL if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual && innerUnary.OperatorType == ExpressionType.Not) { return(Visit(_sqlExpressionFactory.IsNotNull(innerUnary.Operand))); } } var newOperand = (SqlExpression)Visit(sqlUnaryExpression.Operand); return(sqlUnaryExpression.Update(newOperand)); }
protected override Expression VisitSqlUnary(SqlUnaryExpression sqlCastExpression) { _isNullable = false; var canOptimize = _canOptimize; _canOptimize = false; var newOperand = (SqlExpression)Visit(sqlCastExpression.Operand); // result of IsNull/IsNotNull can never be null if (sqlCastExpression.OperatorType == ExpressionType.Equal || sqlCastExpression.OperatorType == ExpressionType.NotEqual) { _isNullable = false; } _canOptimize = canOptimize; return(sqlCastExpression.Update(newOperand)); }
private Expression VisitSqlUnaryExpression(SqlUnaryExpression sqlUnaryExpression) { // !(true) -> false // !(false) -> true if (sqlUnaryExpression.OperatorType == ExpressionType.Not && sqlUnaryExpression.Operand is SqlConstantExpression innerConstantBool && innerConstantBool.Value is bool value) { return(value ? _sqlExpressionFactory.Constant(false, sqlUnaryExpression.TypeMapping) : _sqlExpressionFactory.Constant(true, sqlUnaryExpression.TypeMapping)); } // NULL IS NULL -> true // non_nullablee_constant IS NULL -> false if (sqlUnaryExpression.OperatorType == ExpressionType.Equal && sqlUnaryExpression.Operand is SqlConstantExpression innerConstantNull1) { return(_sqlExpressionFactory.Constant(innerConstantNull1.Value == null, sqlUnaryExpression.TypeMapping)); } // NULL IS NOT NULL -> false // non_nullablee_constant IS NOT NULL -> true if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual && sqlUnaryExpression.Operand is SqlConstantExpression innerConstantNull2) { return(_sqlExpressionFactory.Constant(innerConstantNull2.Value != null, sqlUnaryExpression.TypeMapping)); } if (sqlUnaryExpression.Operand is SqlUnaryExpression innerUnary) { if (sqlUnaryExpression.OperatorType == ExpressionType.Not) { // !(!a) -> a if (innerUnary.OperatorType == ExpressionType.Not) { return(Visit(innerUnary.Operand)); } if (innerUnary.OperatorType == ExpressionType.Equal) { //!(a IS NULL) -> a IS NOT NULL return(Visit(_sqlExpressionFactory.IsNotNull(innerUnary.Operand))); } //!(a IS NOT NULL) -> a IS NULL if (innerUnary.OperatorType == ExpressionType.NotEqual) { return(Visit(_sqlExpressionFactory.IsNull(innerUnary.Operand))); } } // (!a) IS NULL <==> a IS NULL if (sqlUnaryExpression.OperatorType == ExpressionType.Equal && innerUnary.OperatorType == ExpressionType.Not) { return(Visit(_sqlExpressionFactory.IsNull(innerUnary.Operand))); } // (!a) IS NOT NULL <==> a IS NOT NULL if (sqlUnaryExpression.OperatorType == ExpressionType.NotEqual && innerUnary.OperatorType == ExpressionType.Not) { return(Visit(_sqlExpressionFactory.IsNotNull(innerUnary.Operand))); } } if (sqlUnaryExpression.Operand is SqlBinaryExpression innerBinary) { // De Morgan's if (innerBinary.OperatorType == ExpressionType.AndAlso || innerBinary.OperatorType == ExpressionType.OrElse) { var newLeft = (SqlExpression)Visit(_sqlExpressionFactory.Not(innerBinary.Left)); var newRight = (SqlExpression)Visit(_sqlExpressionFactory.Not(innerBinary.Right)); return(innerBinary.OperatorType == ExpressionType.AndAlso ? _sqlExpressionFactory.OrElse(newLeft, newRight) : _sqlExpressionFactory.AndAlso(newLeft, newRight)); } // note that those optimizations are only valid in 2-value logic // they are safe to do here because null semantics removes possibility of nulls in the tree // however if we decide to do "partial" null semantics (that doesn't distinguish between NULL and FALSE, e.g. for predicates) // we need to be extra careful here if (TryNegate(innerBinary.OperatorType, out var negated)) { return(Visit( _sqlExpressionFactory.MakeBinary( negated, innerBinary.Left, innerBinary.Right, innerBinary.TypeMapping))); } } var newOperand = (SqlExpression)Visit(sqlUnaryExpression.Operand); return(sqlUnaryExpression.Update(newOperand)); }
protected override Expression VisitSqlUnary(SqlUnaryExpression sqlCastExpression) { var op = Visit(sqlCastExpression.Operand) as SqlExpression; return(sqlCastExpression.Update(op)); }
protected override Expression VisitSqlUnary(SqlUnaryExpression x) { return(x?.Update(x.Operand.VisitNode(this))); }