/* * /// <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))); }
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); }