private Tuple <int, bool> GetCompareMode(DbExpressionKind kind)
        {
            switch (kind)
            {
            case DbExpressionKind.Equals:
                return(Tuple.Create(0, true));

            case DbExpressionKind.NotEquals:
                return(Tuple.Create(0, false));

            case DbExpressionKind.GreaterThan:
                return(Tuple.Create(1, true));

            case DbExpressionKind.GreaterThanOrEquals:
                return(Tuple.Create(-1, false));

            case DbExpressionKind.LessThan:
                return(Tuple.Create(-1, true));

            case DbExpressionKind.LessThanOrEquals:
                return(Tuple.Create(1, false));
            }

            throw new InvalidOperationException(
                      "The ExpressionKind cannot be " + kind.ToString());
        }
Beispiel #2
0
        internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument)
            : base(kind, resultType)
        {
            DebugCheck.NotNull(argument);

            _argument = argument;
        }
Beispiel #3
0
        // <summary>
        // Helper method for FlattenAssociativeExpression.
        // Creates a flat list of the associative arguments and appends to the given argument list.
        // For example, for ((A1 + (A2 - A3)) + A4) it will add A1, (A2 - A3), A4 to the list.
        // Only 'unfolds' the given expression if it is of the given expression kind.
        // </summary>
        private static void ExtractAssociativeArguments(
            DbExpressionKind expressionKind, List <DbExpression> argumentList, DbExpression expression)
        {
            if (expression.ExpressionKind != expressionKind)
            {
                argumentList.Add(expression);
                return;
            }

            //All associative expressions are binary, thus we must be dealing with a DbBinaryExpresson or
            // a DbArithmeticExpression with 2 arguments.
            var binaryExpression = expression as DbBinaryExpression;

            if (binaryExpression != null)
            {
                ExtractAssociativeArguments(expressionKind, argumentList, binaryExpression.Left);
                ExtractAssociativeArguments(expressionKind, argumentList, binaryExpression.Right);
                return;
            }

            var arithExpression = (DbArithmeticExpression)expression;

            ExtractAssociativeArguments(expressionKind, argumentList, arithExpression.Arguments[0]);
            ExtractAssociativeArguments(expressionKind, argumentList, arithExpression.Arguments[1]);
        }
        // <summary>
        // Uses a stack to non-recursively traverse a given tree structure and retrieve the leaf nodes.
        // </summary>
        // <param name="root"> The node that represents the root of the tree. </param>
        // <param name="kind"> Expressions not of this kind are considered leaves. </param>
        // <param name="getChildNodes">
        // A function that traverses the tree by retrieving the <b>immediate</b> descendants of a (non-leaf) node.
        // </param>
        // <returns> An enumerable containing the leaf nodes. </returns>
        public static IEnumerable <DbExpression> GetLeafNodes(
            this DbExpression root,
            DbExpressionKind kind,
            Func <DbExpression, IEnumerable <DbExpression> > getChildNodes)
        {
            DebugCheck.NotNull(getChildNodes);

            var nodes = new Stack <DbExpression>();

            nodes.Push(root);

            while (nodes.Count > 0)
            {
                var current = nodes.Pop();
                if (current.ExpressionKind != kind)
                {
                    yield return(current);
                }
                else
                {
                    foreach (var node in getChildNodes(current).Reverse())
                    {
                        nodes.Push(node);
                    }
                }
            }
        }
 private static Mock<DbExpression> CreateMockExpression(DbExpressionKind kind)
 {
     var mockRoot = new Mock<DbExpression>();
     mockRoot.Setup(m => m.ExpressionKind).Returns(kind);
     
     return mockRoot;
 }
        public static string GetOperator(DbExpressionKind expressionKind)
        {
            switch (expressionKind)
            {
            case DbExpressionKind.Equals: return("=");

            case DbExpressionKind.LessThan: return("<");

            case DbExpressionKind.GreaterThan: return(">");

            case DbExpressionKind.LessThanOrEquals: return("<=");

            case DbExpressionKind.GreaterThanOrEquals: return(">=");

            case DbExpressionKind.NotEquals: return("!=");

            case DbExpressionKind.LeftOuterJoin: return("LEFT OUTER JOIN");

            case DbExpressionKind.InnerJoin: return("INNER JOIN");

            case DbExpressionKind.CrossJoin: return("CROSS JOIN");

            case DbExpressionKind.FullOuterJoin: return("OUTER JOIN");
            }
            throw new NotSupportedException("expression kind not supported");
        }
 private DbExpression TransformIntersectOrExcept(
     DbExpression left,
     DbExpression right,
     DbExpressionKind expressionKind)
 {
     return(this.TransformIntersectOrExcept(left, right, expressionKind, (IList <DbPropertyExpression>)null, (string)null));
 }
        internal DbArithmeticExpression(DbExpressionKind kind, TypeUsage numericResultType, DbExpressionList args)
            : base(kind, numericResultType)
        {
            Debug.Assert(TypeSemantics.IsNumericType(numericResultType), "DbArithmeticExpression result type must be numeric");

            Debug.Assert(
                DbExpressionKind.Divide == kind ||
                DbExpressionKind.Minus == kind ||
                DbExpressionKind.Modulo == kind ||
                DbExpressionKind.Multiply == kind ||
                DbExpressionKind.Plus == kind ||
                DbExpressionKind.UnaryMinus == kind,
                "Invalid DbExpressionKind used in DbArithmeticExpression: " + Enum.GetName(typeof(DbExpressionKind), kind)
                );

            Debug.Assert(args != null, "DbArithmeticExpression arguments cannot be null");

            Debug.Assert(
                (DbExpressionKind.UnaryMinus == kind && 1 == args.Count) ||
                2 == args.Count,
                "Incorrect number of arguments specified to DbArithmeticExpression"
                );

            this._args = args;
        }
 public JoinExpression(InputExpression left, DbExpressionKind joinType, InputExpression right, VisitedExpression condition)
 {
     _left      = left;
     _joinType  = joinType;
     _right     = right;
     _condition = condition;
 }
Beispiel #10
0
        public bool IsCompatible(DbExpressionKind expressionKind)
        {
            switch (expressionKind)
            {
            case DbExpressionKind.Filter:
                return(Where == null && Columns.Count == 0);

            case DbExpressionKind.Project:
                return(Columns.Count == 0);

            case DbExpressionKind.Limit:
                return(Limit == null);

            case DbExpressionKind.Skip:
                return(Skip == null);

            case DbExpressionKind.Sort:
                return(Columns.Count == 0 &&
                       GroupBy == null &&
                       OrderBy == null);

            case DbExpressionKind.GroupBy:
                return(Columns.Count == 0 &&
                       GroupBy == null &&
                       OrderBy == null &&
                       Limit == null);
            }
            throw new InvalidOperationException();
        }
        internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument)
            : base(kind, resultType)
        {
            Debug.Assert(argument != null, "DbUnaryExpression.Argument cannot be null");

            this._argument = argument;
        }
        private Expression CreateComparison(Expression left, Expression right, DbExpressionKind kind)
        {
            if (left.Type == typeof(string) && right.Type == typeof(string))
            {
                return CreateStringComparison(left, right, kind);
            }

            switch (kind)
            {
                case DbExpressionKind.Equals:
                    return Expression.Equal(left, right);

                case DbExpressionKind.NotEquals:
                    return Expression.NotEqual(left, right);

                case DbExpressionKind.GreaterThan:
                    return Expression.GreaterThan(left, right);

                case DbExpressionKind.GreaterThanOrEquals:
                    return Expression.GreaterThanOrEqual(left, right);

                case DbExpressionKind.LessThan:
                    return Expression.LessThan(left, right);

                case DbExpressionKind.LessThanOrEquals:
                    return Expression.LessThanOrEqual(left, right);

                default:
                    throw new InvalidOperationException(
                        "The ExpressionKind cannot be " + kind.ToString());
            }
        }
        internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument)
            : base(kind, resultType)
        {
            DebugCheck.NotNull(argument);

            _argument = argument;
        }
        internal DbUnaryExpression(DbExpressionKind kind, TypeUsage resultType, DbExpression argument)
            : base(kind, resultType)
        {
            Debug.Assert(argument != null, "DbUnaryExpression.Argument cannot be null");

            _argument = argument;
        }
        private SqlFragment HandleJoinExpression(DbExpressionBinding left, DbExpressionBinding right,
                                                 DbExpressionKind joinType, DbExpression joinCondition)
        {
            JoinFragment join = new JoinFragment();

            join.JoinType = Metadata.GetOperator(joinType);

            join.Left = VisitInputExpression(left.Expression, left.VariableName, left.VariableType);
            join.Left = WrapJoinInputIfNecessary(join.Left, false);

            join.Right = VisitInputExpression(right.Expression, right.VariableName, right.VariableType);
            join.Right = WrapJoinInputIfNecessary(join.Right, true);

            if (join.Right is SelectStatement)
            {
                SelectStatement select = join.Right as SelectStatement;
                if (select.IsWrapped)
                {
                    select.Name = right.VariableName;
                }
            }

            // now handle the ON case
            if (joinCondition != null)
            {
                join.Condition = joinCondition.Accept(this);
            }
            return(join);
        }
        // <summary>
        // Uses a stack to non-recursively traverse a given tree structure and retrieve the leaf nodes.
        // </summary>
        // <param name="root"> The node that represents the root of the tree. </param>
        // <param name="kind"> Expressions not of this kind are considered leaves. </param>
        // <param name="getChildNodes">
        // A function that traverses the tree by retrieving the <b>immediate</b> descendants of a (non-leaf) node.
        // </param>
        // <returns> An enumerable containing the leaf nodes. </returns>
        public static IEnumerable<DbExpression> GetLeafNodes(
            this DbExpression root,
            DbExpressionKind kind,
            Func<DbExpression, IEnumerable<DbExpression>> getChildNodes)
        {
            DebugCheck.NotNull(getChildNodes);

            var nodes = new Stack<DbExpression>();
            nodes.Push(root);

            while (nodes.Count > 0)
            {
                var current = nodes.Pop();
                if (current.ExpressionKind != kind)
                {
                    yield return current;
                }
                else
                {
                    foreach (var node in getChildNodes(current).Reverse())
                    {
                        nodes.Push(node);
                    }
                }
            }
        }
        private Expression CreateComparison(Expression left, Expression right, DbExpressionKind kind)
        {
            if (left.Type == typeof(string) && right.Type == typeof(string))
            {
                return(CreateStringComparison(left, right, kind));
            }

            switch (kind)
            {
            case DbExpressionKind.Equals:
                return(Expression.Equal(left, right));

            case DbExpressionKind.NotEquals:
                return(Expression.NotEqual(left, right));

            case DbExpressionKind.GreaterThan:
                return(Expression.GreaterThan(left, right));

            case DbExpressionKind.GreaterThanOrEquals:
                return(Expression.GreaterThanOrEqual(left, right));

            case DbExpressionKind.LessThan:
                return(Expression.LessThan(left, right));

            case DbExpressionKind.LessThanOrEquals:
                return(Expression.LessThanOrEqual(left, right));

            default:
                throw new InvalidOperationException(
                          "The ExpressionKind cannot be " + kind.ToString());
            }
        }
Beispiel #18
0
        /// <summary>
        /// Determine if the owner expression can add its unique sql to the input's
        /// SqlSelectStatement
        /// </summary>
        /// <param name="result">The SqlSelectStatement of the input to the relational node.</param>
        /// <param name="expressionKind">The kind of the expression node(not the input's)</param>
        /// <returns></returns>
        private static bool IsCompatible(SqlSelectStatement result, DbExpressionKind expressionKind)
        {
            switch (expressionKind)
            {
            case DbExpressionKind.Distinct:
                return(result.Top.IsEmpty
                       // The projection after distinct may not project all
                       // columns used in the Order By
                       // Improvement: Consider getting rid of the Order By instead
                       && result.OrderBy.IsEmpty);

            case DbExpressionKind.Filter:
                return(result.Select.IsEmpty &&
                       result.Where.IsEmpty &&
                       result.GroupBy.IsEmpty &&
                       result.Top.IsEmpty);

            case DbExpressionKind.GroupBy:
                return(result.Select.IsEmpty &&
                       result.GroupBy.IsEmpty &&
                       result.OrderBy.IsEmpty &&
                       result.Top.IsEmpty);

            case DbExpressionKind.Limit:
                return(result.Top.TopCount == null);

            case DbExpressionKind.Element:
                return(result.Top.TopCount == null);

            case DbExpressionKind.Project:
                // Allow a Project to be compatible with an OrderBy
                // Otherwise we won't be able to sort an input, and project out only
                // a subset of the input columns
                return(result.Select.IsEmpty &&
                       result.GroupBy.IsEmpty
                       // If distinct is specified, the projection may affect
                       // the cardinality of the results, thus a new statement must be started.
                       && !result.IsDistinct);

            case DbExpressionKind.Skip:
                return(result.Top.SkipCount == null);

            case DbExpressionKind.Sort:
                return(result.Select.IsEmpty &&
                       result.GroupBy.IsEmpty &&
                       result.OrderBy.IsEmpty
                       // A Project may be on the top of the Sort, and if so, it would need
                       // to be in the same statement as the Sort (see comment above for the Project case).
                       // A Distinct in the same statement would prevent that, and therefore if Distinct is present,
                       // we need to start a new statement.
                       && !result.IsDistinct);

            //return result.OrderBy.IsEmpty;

            default:
                Debug.Assert(false);
                throw new InvalidOperationException(String.Empty);
            }
        }
        private static Mock <DbExpression> CreateMockExpression(DbExpressionKind kind)
        {
            var mockRoot = new Mock <DbExpression>();

            mockRoot.Setup(m => m.ExpressionKind).Returns(kind);

            return(mockRoot);
        }
Beispiel #20
0
 internal static void CheckExpressionKind(DbExpressionKind kind)
 {
     if (kind < DbExpressionKind.All || DbExpressionKindHelper.Last < kind)
     {
         string name = typeof(DbExpressionKind).Name;
         throw new ArgumentOutOfRangeException(name, Strings.ADP_InvalidEnumerationValue((object)name, (object)((int)kind).ToString((IFormatProvider)CultureInfo.InvariantCulture)));
     }
 }
        internal DbIsOfExpression(DbExpressionKind isOfKind, TypeUsage booleanResultType, DbExpression argument, TypeUsage isOfType)
            : base(isOfKind, booleanResultType, argument)
        {
            Debug.Assert(DbExpressionKind.IsOf == this.ExpressionKind || DbExpressionKind.IsOfOnly == this.ExpressionKind, string.Format(CultureInfo.InvariantCulture, "Invalid DbExpressionKind used in DbIsOfExpression: {0}", Enum.GetName(typeof(DbExpressionKind), this.ExpressionKind)));
            Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbIsOfExpression requires a Boolean result type");

            this._ofType = isOfType;
        }
 internal DbComparisonExpression(
     DbExpressionKind kind,
     TypeUsage booleanResultType,
     DbExpression left,
     DbExpression right)
     : base(kind, booleanResultType, left, right)
 {
 }
 internal DbArithmeticExpression(
     DbExpressionKind kind,
     TypeUsage numericResultType,
     DbExpressionList args)
     : base(kind, numericResultType, true)
 {
     this._args = args;
 }
        internal DbBinaryExpression(DbExpressionKind kind, TypeUsage type, DbExpression left, DbExpression right)
            : base(kind, type)
        {
            DebugCheck.NotNull(left);
            DebugCheck.NotNull(right);

            _left = left;
            _right = right;
        }
 public CombinedProjectionExpression(DbExpressionKind setOperator, List <VisitedExpression> list)
 {
     _setOperator = setOperator == DbExpressionKind.UnionAll
         ? "UNION ALL"
         : setOperator == DbExpressionKind.Except
             ? "EXCEPT"
             : "INTERSECT";
     _list = list;
 }
 internal static void CheckExpressionKind(DbExpressionKind kind)
 {
     // Add new valid DbExpressionKind values to this method as well as the enum itself.
     // DbExpressionKind is a contiguous enum from All = 0 through View
     if ((kind < DbExpressionKind.All) || (DbExpressionKind.Lambda < kind))
     {
         throw EntityUtil.InvalidEnumerationValue(typeof(DbExpressionKind), (int)kind);
     }
 }
        internal DbBinaryExpression(DbExpressionKind kind, TypeUsage type, DbExpression left, DbExpression right)
            : base(kind, type)
        {
            Debug.Assert(left != null, "DbBinaryExpression.Left cannot be null");
            Debug.Assert(right != null, "DbBinaryExpression.Right cannot be null");

            this._left  = left;
            this._right = right;
        }
        internal DbBinaryExpression(DbExpressionKind kind, TypeUsage type, DbExpression left, DbExpression right)
            : base(kind, type)
        {
            DebugCheck.NotNull(left);
            DebugCheck.NotNull(right);

            _left  = left;
            _right = right;
        }
Beispiel #29
0
 internal DbOfTypeExpression(
     DbExpressionKind ofTypeKind,
     TypeUsage collectionResultType,
     DbExpression argument,
     TypeUsage type)
     : base(ofTypeKind, collectionResultType, argument)
 {
     this._ofType = type;
 }
        internal DbBinaryExpression(DbExpressionKind kind, TypeUsage type, DbExpression left, DbExpression right)
            : base(kind, type)
        {
            Debug.Assert(left != null, "DbBinaryExpression.Left cannot be null");
            Debug.Assert(right != null, "DbBinaryExpression.Right cannot be null");

            _left = left;
            _right = right;
        }
Beispiel #31
0
 internal DbIsOfExpression(
     DbExpressionKind isOfKind,
     TypeUsage booleanResultType,
     DbExpression argument,
     TypeUsage isOfType)
     : base(isOfKind, booleanResultType, argument)
 {
     this._ofType = isOfType;
 }
Beispiel #32
0
 internal DbQuantifierExpression(
     DbExpressionKind kind,
     TypeUsage booleanResultType,
     DbExpressionBinding input,
     DbExpression predicate)
     : base(kind, booleanResultType, true)
 {
     this._input     = input;
     this._predicate = predicate;
 }
Beispiel #33
0
        internal DbApplyExpression(DbExpressionKind applyKind, TypeUsage resultRowCollectionTypeUsage, DbExpressionBinding input, DbExpressionBinding apply)
            : base(applyKind, resultRowCollectionTypeUsage)
        {
            Debug.Assert(input != null, "DbApplyExpression input cannot be null");
            Debug.Assert(input != null, "DbApplyExpression apply cannot be null");
            Debug.Assert(DbExpressionKind.CrossApply == applyKind || DbExpressionKind.OuterApply == applyKind, "Invalid DbExpressionKind for DbApplyExpression");

            _input = input;
            _apply = apply;
        }
Beispiel #34
0
 internal DbBinaryExpression(
     DbExpressionKind kind,
     TypeUsage type,
     DbExpression left,
     DbExpression right)
     : base(kind, type, true)
 {
     this._left  = left;
     this._right = right;
 }
 internal DbApplyExpression(
     DbExpressionKind applyKind,
     TypeUsage resultRowCollectionTypeUsage,
     DbExpressionBinding input,
     DbExpressionBinding apply)
     : base(applyKind, resultRowCollectionTypeUsage, true)
 {
     this._input = input;
     this._apply = apply;
 }
Beispiel #36
0
        internal DbQuantifierExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpressionBinding input, DbExpression predicate)
            : base(kind, booleanResultType)
        {
            Debug.Assert(input != null, "DbQuantifierExpression input cannot be null");
            Debug.Assert(predicate != null, "DbQuantifierExpression predicate cannot be null");
            Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression must have a Boolean result type");
            Debug.Assert(TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression predicate must have a Boolean result type");

            this._input     = input;
            this._predicate = predicate;
        }
Beispiel #37
0
 internal DbJoinExpression(
     DbExpressionKind joinKind,
     TypeUsage collectionOfRowResultType,
     DbExpressionBinding left,
     DbExpressionBinding right,
     DbExpression condition)
     : base(joinKind, collectionOfRowResultType, true)
 {
     this._left      = left;
     this._right     = right;
     this._condition = condition;
 }
        private Expression CreateStringComparison(Expression left, Expression right, DbExpressionKind kind)
        {
            var method = Expression.Call(null, StringFunctions.CompareTo, left, right);
            var mode = GetCompareMode(kind);

            Expression res = Expression.Equal(method, Expression.Constant(mode.Item1));

            if (!mode.Item2)
            {
                res = Expression.Not(res);
            }

            return res;
        }
        /// <summary>
        /// Creates a flat list of the associative arguments.
        /// For example, for ((A1 + (A2 - A3)) + A4) it will create A1, (A2 - A3), A4
        /// Only 'unfolds' the given arguments that are of the given expression kind.        
        /// </summary>
        /// <param name="expressionKind"></param>
        /// <param name="arguments"></param>
        /// <returns></returns>
        internal static IEnumerable<DbExpression> FlattenAssociativeExpression(
            DbExpressionKind expressionKind, params DbExpression[] arguments)
        {
            if (!_associativeExpressionKinds.Contains(expressionKind))
            {
                return arguments;
            }

            var outputArguments = new List<DbExpression>();
            foreach (var argument in arguments)
            {
                ExtractAssociativeArguments(expressionKind, outputArguments, argument);
            }
            return outputArguments;
        }
        /// <summary>
        /// Helper method for FlattenAssociativeExpression.
        /// Creates a flat list of the associative arguments and appends to the given argument list.
        /// For example, for ((A1 + (A2 - A3)) + A4) it will add A1, (A2 - A3), A4 to the list.
        /// Only 'unfolds' the given expression if it is of the given expression kind.
        /// </summary>
        /// <param name="expressionKind"></param>
        /// <param name="argumentList"></param>
        /// <param name="expression"></param>
        private static void ExtractAssociativeArguments(
            DbExpressionKind expressionKind, List<DbExpression> argumentList, DbExpression expression)
        {
            if (expression.ExpressionKind != expressionKind)
            {
                argumentList.Add(expression);
                return;
            }

            //All associative expressions are binary, thus we must be dealing with a DbBinaryExpresson or 
            // a DbArithmeticExpression with 2 arguments.
            var binaryExpression = expression as DbBinaryExpression;
            if (binaryExpression != null)
            {
                ExtractAssociativeArguments(expressionKind, argumentList, binaryExpression.Left);
                ExtractAssociativeArguments(expressionKind, argumentList, binaryExpression.Right);
                return;
            }

            var arithExpression = (DbArithmeticExpression)expression;
            ExtractAssociativeArguments(expressionKind, argumentList, arithExpression.Arguments[0]);
            ExtractAssociativeArguments(expressionKind, argumentList, arithExpression.Arguments[1]);
        }
 /// <summary>
 /// Constructs a new pattern that will match an expression with the specified <see cref="DbExpressionKind"/>.
 /// </summary>
 internal static Func<DbExpression, bool> MatchKind(DbExpressionKind kindToMatch)
 {
     return (e => e.ExpressionKind == kindToMatch);
 }
            private static Mock<DbIsNullExpression> CreatNullExpression(
                Mock<DbPropertyExpression> mockLeftArgumentExpression,
                DbExpressionKind kind)
            {
                var mockLeftExpression = new Mock<DbIsNullExpression>();
                mockLeftExpression.Setup(m => m.ExpressionKind).Returns(kind);
                mockLeftExpression.Setup(m => m.Argument).Returns(mockLeftArgumentExpression.Object);

                return mockLeftExpression;
            }
 public CombinedProjectionExpression(VisitedExpression first, DbExpressionKind setOperator, VisitedExpression second)
 {
     _first = first;
     _setOperator = setOperator == DbExpressionKind.UnionAll ? "UNION ALL" : setOperator == DbExpressionKind.Except ? "EXCEPT" : "INTERSECT";
     _second = second;
 }
 /// <summary>
 /// This method is invoked when tranforming <see cref="DbIntersectExpression"/> and <see cref="DbExceptExpression"/> by doing comparison over all input columns.
 /// <see cref="TransformIntersectOrExcept(DbExpression left, DbExpression right, DbExpressionKind expressionKind, IList<DbPropertyExpression> sortExpressionsOverLeft, string sortExpressionsBindingVariableName)"/>
 /// </summary>
 /// <param name="left"></param>
 /// <param name="right"></param>
 /// <param name="expressionKind"></param>
 /// <returns></returns>
 private DbExpression TransformIntersectOrExcept(DbExpression left, DbExpression right, DbExpressionKind expressionKind)
 {
     return TransformIntersectOrExcept(left, right, expressionKind, null, null);
 }
Beispiel #45
0
 public JoinExpression(InputExpression left, DbExpressionKind joinType, InputExpression right, VisitedExpression condition)
 {
     _left = left;
     _joinType = joinType;
     _right = right;
     _condition = condition;
 }
Beispiel #46
0
 public NegatableBooleanExpression(DbExpressionKind booleanOperator, VisitedExpression left, VisitedExpression right)
 {
     _booleanOperator = booleanOperator;
     _left = left;
     _right = right;
 }
        private static Mock<DbBinaryExpression> CreateMockBinaryExpression(
            Mock<DbPropertyExpression> mockLeftExpression,
            Mock<DbPropertyExpression> mockRightExpression,
            DbExpressionKind kind)
        {
            SetupMockArguments(mockLeftExpression, mockRightExpression);

            var mockBinaryExpression = new Mock<DbBinaryExpression>();
            mockBinaryExpression.Setup(m => m.ExpressionKind).Returns(kind);
            mockBinaryExpression.Setup(m => m.Left).Returns(mockLeftExpression.Object);
            mockBinaryExpression.Setup(m => m.Right).Returns(mockRightExpression.Object);

            return mockBinaryExpression;
        }
        private static Mock<DbExpression> CreateMockDbArgumentExpression(
            PrimitiveTypeKind typeKind,
            DbExpressionKind expressionKind,
            bool? isUnicode)
        {
            var mockEdmType = new Mock<PrimitiveType>();
            mockEdmType.Setup(m => m.BuiltInTypeKind).Returns(BuiltInTypeKind.PrimitiveType);
            mockEdmType.Setup(m => m.PrimitiveTypeKind).Returns(typeKind);

            var mockTypeUsage = new Mock<TypeUsage>();
            mockTypeUsage.Setup(m => m.EdmType).Returns(mockEdmType.Object);

            if (isUnicode.HasValue)
            {
                var mockFacet = new Mock<Facet>();
                mockFacet.Setup(m => m.Value).Returns(isUnicode.Value);
                mockFacet.Setup(m => m.Identity).Returns(DbProviderManifest.UnicodeFacetName);

                mockTypeUsage.Setup(m => m.Facets).Returns(
                    new ReadOnlyMetadataCollection<Facet>(
                        new MetadataCollection<Facet>
                            {
                                mockFacet.Object
                            }));
            }
            else
            {
                mockTypeUsage.Setup(m => m.Facets).Returns(new ReadOnlyMetadataCollection<Facet>(new MetadataCollection<Facet>()));
            }

            var mockExpression = new Mock<DbExpression>();
            mockExpression.Setup(m => m.ResultType).Returns(mockTypeUsage.Object);
            mockExpression.Setup(m => m.ExpressionKind).Returns(expressionKind);

            return mockExpression;
        }
        private SqlFragment HandleJoinExpression(DbExpressionBinding left, DbExpressionBinding right, 
            DbExpressionKind joinType, DbExpression joinCondition)
        {
            JoinFragment join = new JoinFragment();
            join.JoinType = Metadata.GetOperator(joinType);

            join.Left = VisitInputExpression(left.Expression, left.VariableName, left.VariableType);
            WrapJoinInputIfNecessary(join.Left, false);
            join.Right = VisitInputExpression(right.Expression, right.VariableName, right.VariableType);
            WrapJoinInputIfNecessary(join.Right, true);

            // now handle the ON case
            if (joinCondition != null)
                join.Condition = joinCondition.Accept(this);
            return join;
        }
        /// <summary>
        /// This method is used for translating <see cref="DbIntersectExpression"/> and <see cref="DbExceptExpression"/>,
        /// and for translating the "Except" part of <see cref="DbSkipExpression"/>.
        /// into the follwoing expression:
        /// 
        /// A INTERSECT B, A EXCEPT B
        /// 
        /// (DISTINCT)
        ///  |
        /// FILTER
        ///  |
        ///  | - Input: A
        ///  | - Predicate:(NOT)
        ///                 |
        ///                 ANY 
        ///                 |
        ///                 | - Input: B
        ///                 | - Predicate:  (B.b1 = A.a1 or (B.b1 is null and A.a1 is null))
        ///                             AND (B.b2 = A.a2 or (B.b2 is null and A.a2 is null))
        ///                             AND ... 
        ///                             AND (B.bn = A.an or (B.bn is null and A.an is null)))
        ///
        /// Here, A corresponds to right and B to left. 
        /// (NOT) is present when transforming Except
        /// for the purpose of translating <see cref="DbExceptExpression"/> or <see cref="DbSkipExpression"/>.   
        /// (DISTINCT) is present when transforming for the purpose of translating 
        /// <see cref="DbExceptExpression"/> or <see cref="DbIntersectExpression"/>.  
        /// 
        /// For <see cref="DbSkipExpression"/>, the input to ANY is caped with project which projects out only 
        /// the columns represented in the sortExpressionsOverLeft list and only these are used in the predicate.
        /// This is because we want to support skip over input with non-equal comarable columns and we have no way to recognize these.
        /// </summary>
        /// <param name="left"></param>
        /// <param name="right"></param>
        /// <param name="expressionKind"></param>
        /// <param name="sortExpressionsOverLeft">note that this list gets destroyed by this method</param>
        /// <param name="sortExpressionsBindingVariableName"></param>
        /// <returns></returns>
        private DbExpression TransformIntersectOrExcept(
            DbExpression left, DbExpression right, DbExpressionKind expressionKind, IList<DbPropertyExpression> sortExpressionsOverLeft,
            string sortExpressionsBindingVariableName)
        {
            var negate = (expressionKind == DbExpressionKind.Except) || (expressionKind == DbExpressionKind.Skip);
            var distinct = (expressionKind == DbExpressionKind.Except) || (expressionKind == DbExpressionKind.Intersect);

            var leftInputBinding = left.Bind();
            var rightInputBinding = right.Bind();

            IList<DbPropertyExpression> leftFlattenedProperties = new List<DbPropertyExpression>();
            IList<DbPropertyExpression> rightFlattenedProperties = new List<DbPropertyExpression>();

            FlattenProperties(leftInputBinding.Variable, leftFlattenedProperties);
            FlattenProperties(rightInputBinding.Variable, rightFlattenedProperties);

            //For Skip, we need to ignore any columns that are not in the original sort list. We can recognize these by comparing the left flattened properties and
            // the properties in the list sortExpressionsOverLeft
            // If any such columns exist, we need to add an additional project, to keep the rest of the columns from being projected, as if any among these
            // are non equal comparable, SQL Server 2000 throws.
            if (expressionKind == DbExpressionKind.Skip)
            {
                if (RemoveNonSortProperties(
                    leftFlattenedProperties, rightFlattenedProperties, sortExpressionsOverLeft, leftInputBinding.VariableName,
                    sortExpressionsBindingVariableName))
                {
                    rightInputBinding = CapWithProject(rightInputBinding, rightFlattenedProperties);
                }
            }

            Debug.Assert(
                leftFlattenedProperties.Count == rightFlattenedProperties.Count,
                "The left and the right input to INTERSECT or EXCEPT have a different number of properties");
            Debug.Assert(leftFlattenedProperties.Count != 0, "The inputs to INTERSECT or EXCEPT have no properties");

            //Build the predicate for the quantifier:
            //   (B.b1 = A.a1 or (B.b1 is null and A.a1 is null))
            //      AND (B.b2 = A.a2 or (B.b2 is null and A.a2 is null))
            //      AND ... 
            //      AND (B.bn = A.an or (B.bn is null and A.an is null)))
            DbExpression existsPredicate = null;

            for (var i = 0; i < leftFlattenedProperties.Count; i++)
            {
                //A.ai == B.bi
                DbExpression equalsExpression = leftFlattenedProperties[i].Equal(rightFlattenedProperties[i]);

                //A.ai is null AND B.bi is null
                DbExpression leftIsNullExpression = leftFlattenedProperties[i].IsNull();
                DbExpression rightIsNullExpression = rightFlattenedProperties[i].IsNull();
                DbExpression bothNullExpression = leftIsNullExpression.And(rightIsNullExpression);

                DbExpression orExpression = equalsExpression.Or(bothNullExpression);

                if (i == 0)
                {
                    existsPredicate = orExpression;
                }
                else
                {
                    existsPredicate = existsPredicate.And(orExpression);
                }
            }

            //Build the quantifier
            DbExpression quantifierExpression = rightInputBinding.Any(existsPredicate);

            DbExpression filterPredicate;

            //Negate if needed
            if (negate)
            {
                filterPredicate = quantifierExpression.Not();
            }
            else
            {
                filterPredicate = quantifierExpression;
            }

            //Build the filter
            DbExpression result = leftInputBinding.Filter(filterPredicate);

            //Apply distinct in needed
            if (distinct)
            {
                result = result.Distinct();
            }

            return result;
        }
 public SelectStatement WrapIfNotCompatible(SelectStatement select, DbExpressionKind expressionKind)
 {
     if (select.IsCompatible(expressionKind)) return select;
     SelectStatement newSelect = new SelectStatement();
     select.Wrap(scope);
     newSelect.From = select;
     return newSelect;
 }
 private void VisitExprKind(DbExpressionKind kind)
 {
     _key.Append('[');
     _key.Append(_exprKindNames[(int)kind]);
     _key.Append(']');
 }
        private Tuple<int, bool> GetCompareMode(DbExpressionKind kind)
        {
            switch (kind)
            {
                case DbExpressionKind.Equals:
                    return Tuple.Create(0, true);
                case DbExpressionKind.NotEquals:
                    return Tuple.Create(0, false);
                case DbExpressionKind.GreaterThan:
                    return Tuple.Create(1, true);
                case DbExpressionKind.GreaterThanOrEquals:
                    return Tuple.Create(-1, false);
                case DbExpressionKind.LessThan:
                    return Tuple.Create(-1, true);
                case DbExpressionKind.LessThanOrEquals:
                    return Tuple.Create(1, false);
            }

            throw new InvalidOperationException(
                "The ExpressionKind cannot be " + kind.ToString());
        }
 public bool IsCompatible(DbExpressionKind expressionKind)
 {
   switch (expressionKind)
   {
     case DbExpressionKind.Filter:
       return Where == null && Columns.Count == 0;
     case DbExpressionKind.Project:
       return Columns.Count == 0;
     case DbExpressionKind.Limit:
       return Limit == null;
     case DbExpressionKind.Skip:
       return Skip == null;
     case DbExpressionKind.Sort:
       return Columns.Count == 0 &&
           GroupBy == null &&
           OrderBy == null;
     case DbExpressionKind.GroupBy:
       return Columns.Count == 0 &&
           GroupBy == null &&
           OrderBy == null &&
           Limit == null;
   }
   throw new InvalidOperationException();
 }
        private static Mock<DbPropertyExpression> CreateMockArgumentExpression(DbExpressionKind kind)
        {
            var mockLeftExpression = new Mock<DbPropertyExpression>();
            mockLeftExpression.Setup(m => m.ExpressionKind).Returns(kind);

            return mockLeftExpression;
        }
Beispiel #56
0
 public CombinedProjectionExpression(DbExpressionKind setOperator, List<VisitedExpression> list)
 {
     _setOperator = setOperator == DbExpressionKind.UnionAll ? "UNION ALL" : setOperator == DbExpressionKind.Except ? "EXCEPT" : "INTERSECT";
     _list = list;
 }