示例#1
0
        /*
         * /// <summary>
         * /// Retrieves the data from the source.
         * /// </summary>
         * /// <param name="context">
         * ///     The context.
         * /// </param>
         * /// <param name="query">
         * ///     The query expression. Can be <c>null</c>.
         * /// </param>
         * /// <returns>
         * /// A task returning the data set.
         * /// </returns>
         * public async Task<DataSet> GetDataAsync(IExecutionContext context, IQuery query)
         * {
         *
         *  var leftRows = await context.MaterializeAsync(await this.GetDataAsync(context, this.left, query, query.GetFilter(context), Enumerable.Empty<OrderByExpression>()).ConfigureAwait(false)).ConfigureAwait(false);
         *
         *  if (leftRows.Count == 0)
         *  {
         *      return DataSet.Empty();
         *  }
         *
         *  var sortOrders = new List<OrderByExpression>();
         *  var filter = await this.CreateJoinFilterAsync(context, leftRows, sortOrders);
         *  var rightRows = await context.MaterializeAsync(await this.GetDataAsync(context, this.right, query, filter, sortOrders).ConfigureAwait(false));
         *
         *  if (rightRows.Count == 0)
         *  {
         *      return this.isInnerJoin ? DataSet.Empty() : DataSet.FromEnumerable(rightRows);
         *  }
         *
         *  var joinFilter = this.GetFilter(context);
         *
         *  return null;
         * }
         */

        /// <summary>
        /// Creates the join filter.
        /// </summary>
        /// <param name="context">
        /// The execution context.
        /// </param>
        /// <param name="leftRows">
        /// The left rows.
        /// </param>
        /// <param name="sortOrders">
        /// Will be filled with the sort orders for this join.
        /// </param>
        /// <returns>
        /// A task containing the the filter expression.
        /// </returns>
        private Task <Expression> CreateJoinFilterAsync(IExecutionContext context, IAsyncReadOnlyCollection <Row> leftRows, ICollection <OrderByExpression> sortOrders)
        {
            var filter = (Expression)null; // await this.GetFilter(context, null).ToRangedExpressionAsync(leftRows, this.right.Aliases);

            return(Task.FromResult(new GenericVisitor
            {
                (GenericVisitor visitor, BinaryExpression node) =>
                {
                    if (node.NodeType != ExpressionType.And && node.NodeType != ExpressionType.AndAlso)
                    {
                        return null;
                    }

                    Expression leftSide, rightSide;

                    if (((leftSide = visitor.Visit(node.Left)) as ConstantExpression)?.Value?.Equals(true) ?? false)
                    {
                        return visitor.Visit(node.Right);
                    }

                    if (((rightSide = visitor.Visit(node.Right)) as ConstantExpression)?.Value?.Equals(true) ?? false)
                    {
                        return visitor.Visit(node.Left);
                    }

                    return Expression.MakeBinary(ExpressionType.AndAlso, leftSide, rightSide);
                },
                (RangeExpression node) =>
                node.Type == typeof(bool) && object.Equals(node.Min, false) && object.Equals(node.Max, true)
                                   ? (Expression)Expression.Constant(true)
                                   : node,
                (CompareExpression node) =>
                {
                    var field = node.Left as SourceFieldExpression;
                    var range = node.Right as RangeExpression;

                    if (field == null || range == null)
                    {
                        return null;
                    }

                    switch (node.CompareType)
                    {
                    case ExpressionType.GreaterThan:
                    case ExpressionType.GreaterThanOrEqual:
                    case ExpressionType.LessThan:
                    case ExpressionType.LessThanOrEqual:
                        sortOrders.Add(
                            new OrderByExpression(
                                CustomExpression.MakeSourceField(field.SourceName, field.FieldName),
                                node.CompareType == ExpressionType.GreaterThan || node.CompareType == ExpressionType.GreaterThanOrEqual));
                        break;
                    }

                    return Expression.AndAlso(
                        CustomExpression.MakeCompare(ExpressionType.GreaterThanOrEqual, field, Expression.Constant(range.Min, range.Type)),
                        CustomExpression.MakeCompare(ExpressionType.LessThanOrEqual, field, Expression.Constant(range.Max, range.Type)));
                },
            }.Visit(filter)));
        }
        /// <summary>
        /// Moves field expressions in comparisons to the left.
        /// </summary>
        /// <typeparam name="T">
        /// The type of the expression.
        /// </typeparam>
        /// <param name="expression">
        /// The expression.
        /// </param>
        /// <param name="source">
        /// The source for which the fields should be moved to the left.
        /// </param>
        /// <returns>
        /// The <see cref="Expression"/>.
        /// </returns>
        public static T MoveFieldsToTheLeft <T>(this T expression, DataSource source)
            where T : Expression
        {
            return((T) new GenericVisitor
            {
                (CompareExpression node) =>
                {
                    if (!node.Right.ContainsField(source))
                    {
                        return null;
                    }

                    var opposite = ExpressionExtensions.InvertComparison(node.CompareType);

                    return opposite != null?CustomExpression.MakeCompare(opposite.Value, node.Right, node.Left) : null;
                },
            }.Visit(expression));
        }
示例#3
0
        /// <summary>
        /// The ranges to join filter.
        /// </summary>
        /// <param name="filter">
        /// The filter.
        /// </param>
        /// <returns>
        /// The <see cref="Expression"/>.
        /// </returns>
        private static Expression RangesToJoinFilter(Expression filter)
        {
            return(GenericVisitor.Visit(
                       (CompareExpression node) =>
            {
                var field = node.Left as SourceFieldExpression;
                var range = node.Right as RangeExpression;

                if (field == null || range == null)
                {
                    return null;
                }

                switch (node.CompareType)
                {
                case ExpressionType.Equal:

                    return Expression.AndAlso(
                        CustomExpression.MakeCompare(ExpressionType.GreaterThanOrEqual, field, Expression.Constant(range.Min, range.Type)),
                        CustomExpression.MakeCompare(ExpressionType.LessThanOrEqual, field, Expression.Constant(range.Max, range.Type)));

                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:

                    return CustomExpression.MakeCompare(node.CompareType, field, Expression.Constant(range.Min, range.Type));

                case ExpressionType.LessThan:
                case ExpressionType.LessThanOrEqual:

                    return CustomExpression.MakeCompare(node.CompareType, field, Expression.Constant(range.Max, range.Type));

                case ExpressionType.NotEqual:

                    return Expression.Constant(true);

                default:
                    return null;
                }
            },
                       filter));
        }
示例#4
0
        /// <summary>
        /// The ranges to join filter.
        /// </summary>
        /// <param name="filter">
        /// The filter.
        /// </param>
        /// <returns>
        /// The <see cref="Expression"/>.
        /// </returns>
        private static Expression RangesToJoinFilter(Expression filter)
        {
            return(GenericVisitor.Visit(
                       (CompareExpression node) =>
            {
                var rightRange = node.Right as RangeExpression;

                if (rightRange == null)
                {
                    var leftRange = node.Left as RangeExpression;

                    if (leftRange == null)
                    {
                        return null;
                    }

                    switch (node.CompareType)
                    {
                    case ExpressionType.Equal:

                        return Expression.AndAlso(
                            CustomExpression.MakeCompare(ExpressionType.GreaterThanOrEqual, leftRange.MinExpression, node.Right),
                            CustomExpression.MakeCompare(ExpressionType.LessThanOrEqual, leftRange.MaxExpression, node.Right));

                    case ExpressionType.GreaterThan:
                    case ExpressionType.GreaterThanOrEqual:

                        return CustomExpression.MakeCompare(node.CompareType, leftRange.MinExpression, node.Right);

                    case ExpressionType.LessThan:
                    case ExpressionType.LessThanOrEqual:

                        return CustomExpression.MakeCompare(node.CompareType, leftRange.MaxExpression, node.Right);

                    case ExpressionType.NotEqual:

                        return Expression.Constant(true);

                    default:
                        return null;
                    }
                }

                switch (node.CompareType)
                {
                case ExpressionType.Equal:

                    return Expression.AndAlso(
                        CustomExpression.MakeCompare(ExpressionType.GreaterThanOrEqual, node.Left, rightRange.MinExpression),
                        CustomExpression.MakeCompare(ExpressionType.LessThanOrEqual, node.Left, rightRange.MaxExpression));

                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:

                    return CustomExpression.MakeCompare(node.CompareType, node.Left, rightRange.MinExpression);

                case ExpressionType.LessThan:
                case ExpressionType.LessThanOrEqual:

                    return CustomExpression.MakeCompare(node.CompareType, node.Left, rightRange.MaxExpression);

                case ExpressionType.NotEqual:

                    return Expression.Constant(true);

                default:
                    return null;
                }
            },
                       filter));
        }
示例#5
0
 /// <summary>
 /// Generates an expression for the '&lt;&gt;' operator.
 /// </summary>
 /// <param name="first">
 /// The first argument.
 /// </param>
 /// <param name="second">
 /// The second argument.
 /// </param>
 /// <returns>
 /// The generated expression.
 /// </returns>
 private static Expression GenerateNotEqual(Expression first, Expression second)
 {
     return(CustomExpression.MakeCompare(ExpressionType.NotEqual, first, second));
 }
示例#6
0
 /// <summary>
 /// Generates an expression for the '&lt;' operator.
 /// </summary>
 /// <param name="first">
 /// The first argument.
 /// </param>
 /// <param name="second">
 /// The second argument.
 /// </param>
 /// <returns>
 /// The generated expression.
 /// </returns>
 private static Expression GenerateLessThan(Expression first, Expression second)
 {
     return(CustomExpression.MakeCompare(ExpressionType.LessThan, first, second));
 }