コード例 #1
0
 public override HqlTreeNode BuildHql(System.Reflection.MethodInfo method, Expression targetObject, System.Collections.ObjectModel.ReadOnlyCollection <Expression> arguments,
                                      HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
 {
     return(treeBuilder.LessThan(
                visitor.Visit(arguments[0]).AsExpression(),
                visitor.Visit(arguments[1]).AsExpression()));
 }
コード例 #2
0
        protected HqlTreeNode VisitBinaryExpression(BinaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.Equal)
            {
                return(TranslateEqualityComparison(expression));
            }
            if (expression.NodeType == ExpressionType.NotEqual)
            {
                return(TranslateInequalityComparison(expression));
            }

            var lhs = VisitExpression(expression.Left).AsExpression();
            var rhs = VisitExpression(expression.Right).AsExpression();

            switch (expression.NodeType)
            {
            case ExpressionType.And:
                return(_hqlTreeBuilder.BitwiseAnd(lhs, rhs));

            case ExpressionType.AndAlso:
                return(_hqlTreeBuilder.BooleanAnd(lhs.ToBooleanExpression(), rhs.ToBooleanExpression()));

            case ExpressionType.Or:
                return(_hqlTreeBuilder.BitwiseOr(lhs, rhs));

            case ExpressionType.OrElse:
                return(_hqlTreeBuilder.BooleanOr(lhs.ToBooleanExpression(), rhs.ToBooleanExpression()));

            case ExpressionType.Add:
                if (expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string))
                {
                    return(_hqlTreeBuilder.MethodCall("concat", lhs, rhs));
                }
                return(_hqlTreeBuilder.Add(lhs, rhs));

            case ExpressionType.Subtract:
                return(_hqlTreeBuilder.Subtract(lhs, rhs));

            case ExpressionType.Multiply:
                return(_hqlTreeBuilder.Multiply(lhs, rhs));

            case ExpressionType.Divide:
                return(_hqlTreeBuilder.Divide(lhs, rhs));

            case ExpressionType.Modulo:
                return(_hqlTreeBuilder.MethodCall("mod", lhs, rhs));

            case ExpressionType.LessThan:
                return(_hqlTreeBuilder.LessThan(lhs, rhs));

            case ExpressionType.LessThanOrEqual:
                return(_hqlTreeBuilder.LessThanOrEqual(lhs, rhs));

            case ExpressionType.GreaterThan:
                return(_hqlTreeBuilder.GreaterThan(lhs, rhs));

            case ExpressionType.GreaterThanOrEqual:
                return(_hqlTreeBuilder.GreaterThanOrEqual(lhs, rhs));

            case ExpressionType.Coalesce:
                return(_hqlTreeBuilder.Coalesce(lhs.ToArithmeticExpression(), rhs.ToArithmeticExpression()));
            }

            throw new InvalidOperationException();
        }
コード例 #3
0
        protected HqlTreeNode VisitBinaryExpression(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).AsExpression();
            var rhs = VisitExpression(expression.Right).AsExpression();

            switch (expression.NodeType)
            {
            case ExpressionType.Equal:
                // Need to check for boolean equality
                if (lhs is HqlBooleanExpression || rhs is HqlBooleanExpression)
                {
                    return(ResolveBooleanEquality(expression, lhs, rhs, (l, r) => _hqlTreeBuilder.Equality(l, r)));
                }

                // Check for nulls on left or right.
                if (expression.Right is ConstantExpression && expression.Right.Type.IsNullableOrReference() && ((ConstantExpression)expression.Right).Value == null)
                {
                    return(_hqlTreeBuilder.IsNull(lhs));
                }

                if (expression.Left is ConstantExpression && expression.Left.Type.IsNullableOrReference() && ((ConstantExpression)expression.Left).Value == null)
                {
                    return(_hqlTreeBuilder.IsNull(rhs));
                }

                // Nothing was null, use standard equality.
                return(_hqlTreeBuilder.Equality(lhs, rhs));

            case ExpressionType.NotEqual:
                // Need to check for boolean in-equality
                if (lhs is HqlBooleanExpression || rhs is HqlBooleanExpression)
                {
                    return(ResolveBooleanEquality(expression, lhs, rhs, (l, r) => _hqlTreeBuilder.Inequality(l, r)));
                }

                // Check for nulls on left or right.
                if (expression.Right is ConstantExpression && expression.Right.Type.IsNullableOrReference() && ((ConstantExpression)expression.Right).Value == null)
                {
                    return(_hqlTreeBuilder.IsNotNull(lhs));
                }

                if (expression.Left is ConstantExpression && expression.Left.Type.IsNullableOrReference() && ((ConstantExpression)expression.Left).Value == null)
                {
                    return(_hqlTreeBuilder.IsNotNull(rhs));
                }

                // Nothing was null, use standard inequality.
                return(_hqlTreeBuilder.Inequality(lhs, rhs));

            case ExpressionType.And:
                return(_hqlTreeBuilder.BitwiseAnd(lhs, rhs));

            case ExpressionType.AndAlso:
                return(_hqlTreeBuilder.BooleanAnd(lhs.AsBooleanExpression(), rhs.AsBooleanExpression()));

            case ExpressionType.Or:
                return(_hqlTreeBuilder.BitwiseOr(lhs, rhs));

            case ExpressionType.OrElse:
                return(_hqlTreeBuilder.BooleanOr(lhs.AsBooleanExpression(), rhs.AsBooleanExpression()));

            case ExpressionType.Add:
                if (expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string))
                {
                    return(_hqlTreeBuilder.MethodCall("concat", lhs, rhs));
                }
                return(_hqlTreeBuilder.Add(lhs, rhs));

            case ExpressionType.Subtract:
                return(_hqlTreeBuilder.Subtract(lhs, rhs));

            case ExpressionType.Multiply:
                return(_hqlTreeBuilder.Multiply(lhs, rhs));

            case ExpressionType.Divide:
                return(_hqlTreeBuilder.Divide(lhs, rhs));

            case ExpressionType.Modulo:
                return(_hqlTreeBuilder.MethodCall("mod", lhs, rhs));

            case ExpressionType.LessThan:
                return(_hqlTreeBuilder.LessThan(lhs, rhs));

            case ExpressionType.LessThanOrEqual:
                return(_hqlTreeBuilder.LessThanOrEqual(lhs, rhs));

            case ExpressionType.GreaterThan:
                return(_hqlTreeBuilder.GreaterThan(lhs, rhs));

            case ExpressionType.GreaterThanOrEqual:
                return(_hqlTreeBuilder.GreaterThanOrEqual(lhs, rhs));

            case ExpressionType.Coalesce:
                return(_hqlTreeBuilder.Coalesce(lhs, rhs));
            }

            throw new InvalidOperationException();
        }
コード例 #4
0
        protected HqlTreeNode VisitBinaryExpression(BinaryExpression expression)
        {
            var lhs = VisitExpression(expression.Left).AsExpression();
            var rhs = VisitExpression(expression.Right).AsExpression();

            switch (expression.NodeType)
            {
            case ExpressionType.Equal:
                // Need to check for boolean equality
                if (lhs is HqlBooleanExpression || rhs is HqlBooleanExpression)
                {
                    lhs =
                        _hqlTreeBuilder.Case(
                            new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(1)) },
                            _hqlTreeBuilder.Constant(0));

                    rhs =
                        _hqlTreeBuilder.Case(
                            new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) },
                            _hqlTreeBuilder.Constant(0));

                    return(_hqlTreeBuilder.Equality(lhs, rhs));
                }

                // Also check for nullability
                if (expression.Left.Type.IsNullableOrReference() || expression.Right.Type.IsNullableOrReference())
                {
                    // TODO - yuck.  This clone is needed because the AST tree nodes are not immutable,
                    // and sharing nodes between multiple branches will cause issues in the hqlSqlWalker phase -
                    // a node, x, gets visited during the walk and updated to refer to a real property.  Later in
                    // the walk, x get revisited (since we copied it here), but now the type doesn't match what
                    // the parser expects.  So we can't share.  Implementing Clone() on HqlTreeNode would be better
                    // that doing a full visit of the Expression tree.  Allowing shared nodes in the AST would be better
                    // still, but might be more work
                    var lhs2 = VisitExpression(expression.Left).AsExpression();
                    var rhs2 = VisitExpression(expression.Right).AsExpression();

                    return(_hqlTreeBuilder.BooleanOr(
                               _hqlTreeBuilder.BooleanAnd(
                                   _hqlTreeBuilder.IsNull(lhs),
                                   _hqlTreeBuilder.IsNull(rhs)),
                               _hqlTreeBuilder.Equality(lhs2, rhs2)
                               ));
                }

                return(_hqlTreeBuilder.Equality(lhs, rhs));

            case ExpressionType.NotEqual:
                // Need to check for boolean in-equality
                if (lhs is HqlBooleanExpression || rhs is HqlBooleanExpression)
                {
                    lhs =
                        _hqlTreeBuilder.Case(
                            new [] { _hqlTreeBuilder.When(lhs, _hqlTreeBuilder.Constant(1)) },
                            _hqlTreeBuilder.Constant(0));

                    rhs =
                        _hqlTreeBuilder.Case(
                            new [] { _hqlTreeBuilder.When(rhs, _hqlTreeBuilder.Constant(1)) },
                            _hqlTreeBuilder.Constant(0));

                    return(_hqlTreeBuilder.Inequality(lhs, rhs));
                }

                // Also check for nullability
                if (expression.Left.Type.IsNullableOrReference() || expression.Right.Type.IsNullableOrReference())
                {
                    var lhs2 = VisitExpression(expression.Left).AsExpression();
                    var rhs2 = VisitExpression(expression.Right).AsExpression();
                    var lhs3 = VisitExpression(expression.Left).AsExpression();
                    var rhs3 = VisitExpression(expression.Right).AsExpression();

                    return
                        (_hqlTreeBuilder.BooleanOr(
                             _hqlTreeBuilder.BooleanOr(
                                 _hqlTreeBuilder.BooleanAnd(
                                     _hqlTreeBuilder.IsNull(lhs),
                                     _hqlTreeBuilder.IsNotNull(rhs)),
                                 _hqlTreeBuilder.BooleanAnd(
                                     _hqlTreeBuilder.IsNotNull(lhs2),
                                     _hqlTreeBuilder.IsNull(rhs2))
                                 ),
                             _hqlTreeBuilder.Inequality(lhs3, rhs3)));
                }

                return(_hqlTreeBuilder.Inequality(lhs, rhs));

            case ExpressionType.And:
                return(_hqlTreeBuilder.BitwiseAnd(lhs, rhs));

            case ExpressionType.AndAlso:
                return(_hqlTreeBuilder.BooleanAnd(lhs.AsBooleanExpression(), rhs.AsBooleanExpression()));

            case ExpressionType.Or:
                return(_hqlTreeBuilder.BitwiseOr(lhs, rhs));

            case ExpressionType.OrElse:
                return(_hqlTreeBuilder.BooleanOr(lhs.AsBooleanExpression(), rhs.AsBooleanExpression()));

            case ExpressionType.Add:
                return(_hqlTreeBuilder.Add(lhs, rhs));

            case ExpressionType.Subtract:
                return(_hqlTreeBuilder.Subtract(lhs, rhs));

            case ExpressionType.Multiply:
                return(_hqlTreeBuilder.Multiply(lhs, rhs));

            case ExpressionType.Divide:
                return(_hqlTreeBuilder.Divide(lhs, rhs));

            case ExpressionType.LessThan:
                return(_hqlTreeBuilder.LessThan(lhs, rhs));

            case ExpressionType.LessThanOrEqual:
                return(_hqlTreeBuilder.LessThanOrEqual(lhs, rhs));

            case ExpressionType.GreaterThan:
                return(_hqlTreeBuilder.GreaterThan(lhs, rhs));

            case ExpressionType.GreaterThanOrEqual:
                return(_hqlTreeBuilder.GreaterThanOrEqual(lhs, rhs));
            }

            throw new InvalidOperationException();
        }
コード例 #5
0
        protected HqlTreeNode VisitBinaryExpression(BinaryExpression expression)
        {
            // There are some cases where we do not want to add a sql cast:
            // - When comparing numeric types that do not have their own operator (e.g. short == short)
            // - When comparing a member expression with a parameter of similar type (e.g. o.Short == intParameter)
            var leftType  = GetExpressionType(expression.Left);
            var rightType = GetExpressionType(expression.Right);

            if (leftType != null && leftType == rightType)
            {
                _notCastableExpressions[expression.Left]  = leftType;
                _notCastableExpressions[expression.Right] = rightType;
            }

            if (expression.NodeType == ExpressionType.Equal)
            {
                return(TranslateEqualityComparison(expression));
            }
            if (expression.NodeType == ExpressionType.NotEqual)
            {
                return(TranslateInequalityComparison(expression));
            }

            _nullableExpressionDetector.SearchForNotNullMemberChecks(expression);

            var lhs = VisitExpression(expression.Left).AsExpression();
            var rhs = VisitExpression(expression.Right).AsExpression();

            switch (expression.NodeType)
            {
            case ExpressionType.And:
                return(_hqlTreeBuilder.BitwiseAnd(lhs, rhs));

            case ExpressionType.AndAlso:
                return(_hqlTreeBuilder.BooleanAnd(lhs.ToBooleanExpression(), rhs.ToBooleanExpression()));

            case ExpressionType.Or:
                return(_hqlTreeBuilder.BitwiseOr(lhs, rhs));

            case ExpressionType.OrElse:
                return(_hqlTreeBuilder.BooleanOr(lhs.ToBooleanExpression(), rhs.ToBooleanExpression()));

            case ExpressionType.Add:
                if (expression.Left.Type == typeof(string) && expression.Right.Type == typeof(string))
                {
                    return(_hqlTreeBuilder.MethodCall("concat", lhs, rhs));
                }
                return(_hqlTreeBuilder.Add(lhs, rhs));

            case ExpressionType.Subtract:
                return(_hqlTreeBuilder.Subtract(lhs, rhs));

            case ExpressionType.Multiply:
                return(_hqlTreeBuilder.Multiply(lhs, rhs));

            case ExpressionType.Divide:
                return(_hqlTreeBuilder.Divide(lhs, rhs));

            case ExpressionType.Modulo:
                return(_hqlTreeBuilder.MethodCall("mod", lhs, rhs));

            case ExpressionType.LessThan:
                return(_hqlTreeBuilder.LessThan(lhs, rhs));

            case ExpressionType.LessThanOrEqual:
                return(_hqlTreeBuilder.LessThanOrEqual(lhs, rhs));

            case ExpressionType.GreaterThan:
                return(_hqlTreeBuilder.GreaterThan(lhs, rhs));

            case ExpressionType.GreaterThanOrEqual:
                return(_hqlTreeBuilder.GreaterThanOrEqual(lhs, rhs));

            case ExpressionType.Coalesce:
                return(_hqlTreeBuilder.Coalesce(lhs.ToArithmeticExpression(), rhs.ToArithmeticExpression()));
            }

            throw new InvalidOperationException();
        }
コード例 #6
0
 public override HqlTreeNode BuildHql(MethodInfo method, System.Linq.Expressions.Expression targetObject, ReadOnlyCollection <System.Linq.Expressions.Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
 {
     return(treeBuilder.LessThan(
                visitor.Visit(targetObject).AsExpression(),
                visitor.Visit(arguments[0]).AsExpression()));
 }