示例#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)));
        }
示例#2
0
        protected internal override Node VisitSelectFromStatement(SelectFromStatement node)
        {
            node = (SelectFromStatement)base.VisitSelectFromStatement(node);

            if (node.Groupings.Any())
            {
                var groupQuery     = GroupQueryVisitor.GetGroupQuery(node, this.data);
                var groupFactories = this.GetGroupValueFactory(groupQuery.Expressions.Concat(new[]
                {
                    new AliasedSqlExpression(groupQuery.Having, "$having"),
                }).Concat(groupQuery.OrderBy.Select((o, i) => new AliasedSqlExpression(o.Expression, $"$order{i}"))).Where(e => e.Expression != null));
                var plan   = this.CreateSelectQueryPlan(groupQuery.RowSelect);
                var fields = node.Expressions.Select(f => f.Expression is WildcardSqlExpression ? "*" : f.Alias);
                var orders = groupQuery.OrderBy.Select((o, i) => new OrderByExpression(CustomExpression.MakeSourceField(null, $"$order{i}", true), o.Ascending));
                var having = groupQuery.Having == null ? null : CustomExpression.MakeSourceField(null, "$having", true, typeof(bool));

                var aliases = groupQuery.Expressions;

                this.data.SetQueryPlan(node, new SelectGroupByQueryPlan(plan, groupFactories, groupQuery.Groupings, aliases, having, orders, fields));
            }
            else
            {
                this.data.SetQueryPlan(node, this.CreateSelectQueryPlan(node));
            }

            return(node);
        }