private void FlattenSubQuery(SubQueryExpression subQueryExpression, MainFromClause fromClause,
		                             QueryModel queryModel)
		{
			// Create a new client-side select for the outer
			// TODO - don't like calling GetGenericArguments here...
			var clientSideSelect = new ClientSideSelect(new NonAggregatingGroupBySelectRewriter().Visit(queryModel.SelectClause.Selector, subQueryExpression.Type.GetGenericArguments()[0], queryModel.MainFromClause));

			// Replace the outer select clause...
			queryModel.SelectClause = subQueryExpression.QueryModel.SelectClause;

			MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;

			CopyFromClauseData(innerMainFromClause, fromClause);

			foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
			{
				queryModel.BodyClauses.Add(bodyClause);
			}

			// Move the result operator up 
			if (queryModel.ResultOperators.Count != 0)
			{
				throw new NotImplementedException();
			}

			queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]));
			queryModel.ResultOperators.Add(clientSideSelect);
		}
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			ContainsAggregateMethods =
				new GroupByAggregateDetectionVisitor().Visit(expression.QueryModel.SelectClause.Selector);

			return expression;
		}
		private void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause,
		                             QueryModel queryModel)
		{
			// Move the result operator up 
			if (queryModel.ResultOperators.Count != 0)
			{
				throw new NotImplementedException();
			}

			var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0];

			// Replace the outer select clause...
			queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel));

			queryModel.SelectClause.TransformExpressions(
				s =>
				new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap
					(s));

			MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
			CopyFromClauseData(innerMainFromClause, fromClause);

			foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses)
			{
				queryModel.BodyClauses.Add(bodyClause);
			}

			queryModel.ResultOperators.Add(groupBy);
		}
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1
                && typeof(ValueFromSequenceResultOperatorBase).IsAssignableFrom(expression.QueryModel.ResultOperators[0].GetType()))
            {
                ContainsAggregateMethods = true;
            }

            return base.VisitSubQueryExpression(expression);
        }
        public void ReplacesTreePart_InSubQueries()
        {
            var replacedNode    = ExpressionHelper.CreateQueryable <Cook> ().Expression;
            var replacementNode = Expression.Constant(null, typeof(Cook[]));

            var subQueryMainFromClause = new MainFromClause("c", typeof(Cook), replacedNode);
            var subQuery = ExpressionHelper.CreateQueryModel(subQueryMainFromClause);

            var tree = new SubQueryExpression(subQuery);

            ReplacingExpressionTreeVisitor.Replace(replacedNode, replacementNode, tree);

            Assert.That(subQueryMainFromClause.FromExpression, Is.SameAs(replacementNode));
        }
        protected override Expression VisitSubquery(SubQueryExpression subquery)
        {
            if (subquery.Query is SelectExpression select)
            {
                Debug.Assert(select.Columns.Count == 1 || subquery is ExistsExpression);
                foreach (var column in select.Columns)
                {
                    MarkColumnAsUsed(select.Alias, column.Name);
                }
            }
            Expression result = base.VisitSubquery(subquery);

            return(result);
        }
Exemple #7
0
            protected override Expression VisitSubQuery(SubQueryExpression expression)
            {
                var queryModel = expression.QueryModel;

                var newQueryModel = new QueryModel(queryModel.MainFromClause, queryModel.SelectClause);

                ShallowCopy(queryModel, newQueryModel);

                _mapping.Add(queryModel, newQueryModel);

                queryModel.TransformExpressions(Visit);

                return(expression);
            }
Exemple #8
0
        private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel)
        {
            // we can not flattern subquery if outer query has body clauses.
            var subQueryModel          = subQueryExpression.QueryModel;
            var subQueryMainFromClause = subQueryModel.MainFromClause;

            if (queryModel.BodyClauses.Count == 0)
            {
                foreach (var resultOperator in subQueryModel.ResultOperators)
                {
                    queryModel.ResultOperators.Add(resultOperator);
                }

                foreach (var bodyClause in subQueryModel.BodyClauses)
                {
                    queryModel.BodyClauses.Add(bodyClause);
                }

                var visitor1 = new PagingRewriterSelectClauseVisitor(queryModel.MainFromClause);
                queryModel.SelectClause.TransformExpressions(visitor1.Swap);
            }
            else
            {
                var cro = new ContainsResultOperator(new QuerySourceReferenceExpression(subQueryMainFromClause));

                var newSubQueryModel = subQueryModel.Clone();
                newSubQueryModel.ResultOperators.Add(cro);
                newSubQueryModel.ResultTypeOverride = typeof(bool);

                var where = new WhereClause(new SubQueryExpression(newSubQueryModel));
                queryModel.BodyClauses.Add(where);

                if (!queryModel.BodyClauses.OfType <OrderByClause>().Any())
                {
                    var orderByClauses = subQueryModel.BodyClauses.OfType <OrderByClause>();
                    foreach (var orderByClause in orderByClauses)
                    {
                        queryModel.BodyClauses.Add(orderByClause);
                    }
                }
            }

            // Point all query source references to the outer from clause
            var visitor2 = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryMainFromClause);

            queryModel.TransformExpressions(visitor2.Swap);

            // Replace the outer query source
            queryModel.MainFromClause = subQueryMainFromClause;
        }
Exemple #9
0
        public void GetResolvedExpression_WithSubQueries()
        {
            var parameterExpression = Expression.Parameter(typeof(int), "i");
            var subQueryExpression  = new SubQueryExpression(ExpressionHelper.CreateQueryModel_Int());

            subQueryExpression.QueryModel.SelectClause.Selector = parameterExpression;

            var result = (SubQueryExpression)_expressionResolver.GetResolvedExpression(subQueryExpression, parameterExpression, ClauseGenerationContext);

            var subQuerySelector = result.QueryModel.SelectClause.Selector;

            Assert.That(subQuerySelector, Is.InstanceOf(typeof(QuerySourceReferenceExpression)));
            Assert.That(((QuerySourceReferenceExpression)subQuerySelector).ReferencedQuerySource, Is.SameAs(SourceClause));
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
        {
            if (_reachable)
            {
                return(subQueryExpression);
            }

            _originGroupByQueryModel
                = subQueryExpression.QueryModel.ResultOperators
                  .Any(ro => ro is GroupResultOperator)
                    ? subQueryExpression.QueryModel
                    : _originGroupByQueryModel;

            return(base.VisitSubQuery(subQueryExpression));
        }
        public static IQuerySource GetOriginalSource(MainFromClause from)
        {
            if (from.ItemType.IsGrouping())
            {
                return(from);
            }
            SubQueryExpression sqe = from.FromExpression as SubQueryExpression;

            while (sqe != null)
            {
                from = sqe.QueryModel.MainFromClause;
                sqe  = from.FromExpression as SubQueryExpression;
            }
            return(from);
        }
Exemple #12
0
        /// <summary>
        ///     This is an internal API that supports the Entity Framework Core infrastructure and not subject to
        ///     the same compatibility standards as public APIs. It may be changed or removed without notice in
        ///     any release. You should only use it directly in your code with extreme caution and knowing that
        ///     doing so can result in application failures when updating to a new Entity Framework Core release.
        /// </summary>
        protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
        {
            if (subQueryExpression.QueryModel.ResultOperators.LastOrDefault() is FirstResultOperator first &&
                first.ReturnDefaultWhenEmpty &&
                !subQueryExpression.Type.IsNullableType())
            {
                var result = Expression.Coalesce(
                    Expression.Convert(subQueryExpression, subQueryExpression.Type.MakeNullable()),
                    Expression.Constant(subQueryExpression.Type.GetDefaultValue()));

                return(result);
            }

            return(base.VisitSubQuery(subQueryExpression));
        }
Exemple #13
0
        public static Result CreateProjector(
            string name,
            FromClauseBase fromClause,
            SubQueryExpression sqe,
            QueryParts parts)
        {
            var result = new Result {
                QuerySource = fromClause, Name = name, Type = fromClause.ItemType
            };
            var method    = ProjectionMethod.Method.GetGenericMethodDefinition().MakeGenericMethod(fromClause.ItemType);
            var instancer = (Func <string, object>)method.Invoke(null, new object[] { sqe, parts });

            result.Instancer = value => instancer(value.ToString());
            return(result);
        }
Exemple #14
0
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            Check.NotNull(expression, nameof(expression));

            var queryModelVisitor = (RelationalQueryModelVisitor)CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(expression.QueryModel);

            if (_querySource != null)
            {
                QueryModelVisitor.RegisterSubQueryVisitor(_querySource, queryModelVisitor);
            }

            return(queryModelVisitor.Expression);
        }
        private bool TryHandleAllAny(SubQueryExpression subquery, Expression predicate, string keyword)
        {
            var last  = _currentMode;
            var part1 = subquery.QueryModel.MainFromClause.FromExpression;

            if (predicate == null)
            {
                return(false);
            }


            HandleAllAnyEvery(keyword, part1, predicate);
            _currentMode = last;
            return(true);
        }
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var visitor = new FSQueryModelVisitor();

            visitor.VisitQueryModel(expression.QueryModel);

            QueryParts.Merge(visitor.QueryParts);

            Offset = visitor.Offset;
            Limit  = visitor.Limit;

            IsCountQuery = visitor.IsCountQuery;

            return(visitor.Expression);
        }
        protected override Expression VisitConstant(ConstantExpression constantExpression)
        {
            if (_store != null && constantExpression.IsEntityQueryable())
            {
                var type       = ((IQueryable)constantExpression.Value).ElementType;
                var entityType = _queryCompilationContext.Model.FindEntityType(type)?.RootType();

                if (entityType != null && _store.Dictionary.TryGetValue(type, out var lambda))
                {
                    Expression newExpression = constantExpression;

                    var parameterizedFilter
                        = (LambdaExpression)_queryModelGenerator
                          .ExtractParameters(
                              _queryCompilationContext.Logger,
                              lambda,
                              new Parameters(this.ContextParameters),
                              parameterize: false,
                              generateContextAccessors: true);

                    var oldParameterExpression = parameterizedFilter.Parameters[0];
                    var newParameterExpression = Expression.Parameter(type, oldParameterExpression.Name);

                    var predicateExpression
                        = ReplacingExpressionVisitor
                          .Replace(
                              oldParameterExpression,
                              newParameterExpression,
                              parameterizedFilter.Body);

                    var whereExpression
                        = Expression.Call(
                              _whereMethod.MakeGenericMethod(type),
                              newExpression,
                              Expression.Lambda(
                                  predicateExpression,
                                  newParameterExpression));

                    var subQueryModel = _queryModelGenerator.ParseQuery(whereExpression);

                    newExpression = new SubQueryExpression(subQueryModel);

                    return(newExpression);
                }
            }

            return(base.VisitConstant(constantExpression));
        }
Exemple #18
0
            protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
            {
                this.resultOperators.AddRange(
                    expression.QueryModel.ResultOperators
                    .Where(r => rewrittenTypes.Any(t => t.IsAssignableFrom(r.GetType()))));

                this.resultOperators.ForEach(f => expression.QueryModel.ResultOperators.Remove(f));
                this.evaluationType = expression.QueryModel.SelectClause.GetOutputDataInfo();

                if (expression.QueryModel.ResultOperators.Count == 0)
                {
                    return(expression.QueryModel.MainFromClause.FromExpression);
                }

                return(base.VisitSubQueryExpression(expression));
            }
Exemple #19
0
            protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
            {
                if (_translateToSql)
                {
                    var sqlExpression = _sqlTranslatingExpressionVisitorFactory.Create(
                        _queryModelVisitor,
                        _selectExpression,
                        inProjection: true)
                                        .Visit(subQueryExpression);
                    _sqlMapping[subQueryExpression] = sqlExpression;

                    return(subQueryExpression);
                }

                return(BindSqlToValueBuffer(_sqlMapping[subQueryExpression], subQueryExpression.Type));
            }
Exemple #20
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var operators = expression.QueryModel.ResultOperators;

            if (operators.Count == 1 && operators[0] is ContainsResultOperator)
            {
                var op = (ContainsResultOperator)operators[0];

                var field   = expression.QueryModel.MainFromClause.FromExpression;
                var pattern = op.Item;

                return(Expression.MakeBinary(ExpressionType.Equal, field, pattern));
            }

            return(base.VisitSubQueryExpression(expression));
        }
        protected override Expression VisitSubQuery(SubQueryExpression subQuery)
        {
            if (subQuery.QueryModel.ResultOperators.All(p => p is AnyResultOperator))
            {
                var query = new QueryAggregator();

                var modelVisitor = new InfluxDBQueryVisitor(_context.Clone(query));
                modelVisitor.VisitQueryModel(subQuery.QueryModel);

                _context.QueryAggregator.AddSubQueries(query);

                return(subQuery);
            }

            return(base.VisitSubQuery(subQuery));
        }
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            var sqParts = new SubqueryParts(Query, expression.QueryModel.SelectClause.Selector, Query.Context);
            var sq      = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, sqParts);

            if (!Query.CanQueryInMemory)
            {
                Query.AddSelectPart(
                    null,
                    "(" + sq.BuildSqlString(true) + ")",
                    null,
                    expression.QueryModel.ResultTypeOverride ?? expression.QueryModel.SelectClause.Selector.Type,
                    null);
            }
            return(expression);
        }
            protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
            {
                resultOperators.AddRange(
                    expression.QueryModel.ResultOperators
                    .Where(r => rewrittenTypes.Any(t => t.IsInstanceOfType(r))));

                resultOperators.ForEach(f => expression.QueryModel.ResultOperators.Remove(f));
                evaluationType = expression.QueryModel.SelectClause.GetOutputDataInfo();

                if (expression.QueryModel.ResultOperators.Count == 0 && expression.QueryModel.BodyClauses.Count == 0)
                {
                    return(expression.QueryModel.MainFromClause.FromExpression);
                }

                return(base.VisitSubQueryExpression(expression));
            }
Exemple #24
0
        /// <summary>
        ///     Visit a subquery.
        /// </summary>
        /// <param name="expression"> The subquery expression. </param>
        /// <returns>
        ///     A compiled query expression fragment representing the input subquery expression.
        /// </returns>
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            var queryModelVisitor = CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(expression.QueryModel);

            var subExpression = queryModelVisitor.Expression;

            if (subExpression.Type != expression.Type)
            {
                var subQueryExpressionTypeInfo = expression.Type.GetTypeInfo();

                if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(expression.Type.GetTypeInfo()))
                {
                    subExpression
                        = Expression.Call(
                              QueryModelVisitor.LinqOperatorProvider.ToQueryable
                              .MakeGenericMethod(expression.Type.GetSequenceType()),
                              subExpression,
                              EntityQueryModelVisitor.QueryContextParameter);
                }
                else if (subQueryExpressionTypeInfo.IsGenericType)
                {
                    var genericTypeDefinition = subQueryExpressionTypeInfo.GetGenericTypeDefinition();

                    if (genericTypeDefinition == typeof(IOrderedEnumerable <>))
                    {
                        subExpression
                            = Expression.Call(
                                  QueryModelVisitor.LinqOperatorProvider.ToOrdered
                                  .MakeGenericMethod(expression.Type.GetSequenceType()),
                                  subExpression);
                    }
                    else if (genericTypeDefinition == typeof(IEnumerable <>))
                    {
                        subExpression
                            = Expression.Call(
                                  QueryModelVisitor.LinqOperatorProvider.ToEnumerable
                                  .MakeGenericMethod(expression.Type.GetSequenceType()),
                                  subExpression);
                    }
                }
            }

            return(subExpression);
        }
        /// <summary>
        ///     This API supports the Entity Framework Core infrastructure and is not intended to be used
        ///     directly from your code. This API may change or be removed in future releases.
        /// </summary>
        protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
        {
            if (_queryCompilationContext.CorrelatedSubqueryMetadataMap.TryGetValue(subQueryExpression.QueryModel.MainFromClause, out var correlatedSubqueryMetadata))
            {
                var parentQsre = new QuerySourceReferenceExpression(correlatedSubqueryMetadata.ParentQuerySource);
                var result     = Rewrite(
                    correlatedSubqueryMetadata.Index,
                    subQueryExpression.QueryModel,
                    correlatedSubqueryMetadata.CollectionNavigation,
                    correlatedSubqueryMetadata.TrackingQuery,
                    parentQsre);

                return(result);
            }

            return(base.VisitSubQuery(subQueryExpression));
        }
Exemple #26
0
        public void Replaces_SubQueryExpressions_WithCorrectCloneContext()
        {
            var subQueryModel    = ExpressionHelper.CreateQueryModel <Cook> ();
            var referencedClause = ExpressionHelper.CreateMainFromClause_Int();

            subQueryModel.SelectClause.Selector = new QuerySourceReferenceExpression(referencedClause);
            var expression = new SubQueryExpression(subQueryModel);

            var newReferenceExpression = new QuerySourceReferenceExpression(ExpressionHelper.CreateMainFromClause_Int());

            _querySourceMapping.AddMapping(referencedClause, newReferenceExpression);

            var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning(expression, _querySourceMapping);
            var newSubQuerySelectClause = ((SubQueryExpression)result).QueryModel.SelectClause;

            Assert.That(newSubQuerySelectClause.Selector, Is.SameAs(newReferenceExpression));
        }
Exemple #27
0
        private static Func <string, T> ProjectMapping <T>(SubQueryExpression sqe, QueryParts parts, SubqueryParts subquery)
        {
            var ssd = SelectSubqueryData.Create(parts, subquery);

            var projector = ProjectorBuildingExpressionTreeVisitor <T> .BuildProjector(sqe.QueryModel);

            //TODO TextReader/string !?
            Func <string, T> result = value =>
            {
                var items = PostgresRecordConverter.ParseRecord(value);
                var rom   = ssd.ProcessRow(null, items);
                var res   = projector(rom);
                return(res);
            };

            return(result);
        }
        protected Expression VisitSubQueryExpression(SubQueryExpression node)
        {
            var        paramGeneric = parameterExpressionArray.Where(p => p.Type.GetGenericArguments().Count() == 1);
            Expression param        = node.QueryModel.MainFromClause.FromExpression;

            if (param is QuerySourceReferenceExpression)
            {
                node.QueryModel.MainFromClause.FromExpression = paramGeneric.First();
            }

            QueryModelVisitor queryModelVisitor = new QueryModelVisitor(dbContext, queryContext);

            queryModelVisitor.VisitQueryModel(node.QueryModel);
            MainParametrExpression = queryModelVisitor.MainParamerExpression;
            queryModelVisitor.MainParamerExpression = null;
            return(queryModelVisitor.expression);
        }
        private void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause,
                                     QueryModel queryModel)
        {
            // Replace the outer select clause...
            queryModel.SelectClause.TransformExpressions(GroupBySelectClauseVisitor.Visit);

            MainFromClause innerMainFromClause = subQueryExpression.QueryModel.MainFromClause;
            CopyFromClauseData(innerMainFromClause, fromClause);

            // Move the result operator up 
            if (queryModel.ResultOperators.Count != 0)
            {
                throw new NotImplementedException();
            }

            queryModel.ResultOperators.Add(subQueryExpression.QueryModel.ResultOperators[0]);
        }
Exemple #30
0
        protected virtual Expression VisitSubquery(SubQueryExpression subquery)
        {
            switch (subquery.NodeType)
            {
            case (ExpressionType)DbExpressionType.Scalar:
                return(VisitScalar((ScalarExpression)subquery));

            case (ExpressionType)DbExpressionType.Exists:
                return(VisitExists((ExistsExpression)subquery));

            case (ExpressionType)DbExpressionType.In:
                return(VisitIn((InExpression)subquery));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Exemple #31
0
        private static bool IsInExpression(SubQueryExpression expression)
        {
            var queryModel = expression.QueryModel;

            if (queryModel.BodyClauses.Count != 0)
            {
                return(false);
            }
            if (queryModel.ResultOperators.Count != 1)
            {
                return(false);
            }
            if (!(queryModel.ResultOperators[0] is ContainsResultOperator))
            {
                return(false);
            }
            return(queryModel.MainFromClause.FromExpression is ConstantExpression);
        }
Exemple #32
0
        private static ReqlExpr ResolveExtensionExpression(ReqlExpr reqlExpr, SubQueryExpression expression)
        {
            var subQueryVisitors = new List <ISubQueryVisitor>
            {
                new AnySubQueryVisitor(),
                new AllSubQueryVisitor(),
                new FirstAndLastSubQueryVisitor()
            };

            var subQueryVisitor = subQueryVisitors.FirstOrDefault(x => x.CanVisit(expression.QueryModel));

            if (subQueryVisitor == null)
            {
                throw new NotSupportedException("subqueries not allowed .");
            }

            return(subQueryVisitor.Visit(reqlExpr, expression.QueryModel));
        }
        public void IsSupportedStandardExpression_False()
        {
            var extensionExpression = new TestExtensionExpression(Expression.Constant(0));

            Assert.That(ExpressionTreeVisitor.IsSupportedStandardExpression(extensionExpression), Is.False);

            var unknownExpression = new UnknownExpression(typeof(int));

            Assert.That(ExpressionTreeVisitor.IsSupportedStandardExpression(unknownExpression), Is.False);

            var querySourceReferenceExpression = new QuerySourceReferenceExpression(ExpressionHelper.CreateMainFromClause_Int());

            Assert.That(ExpressionTreeVisitor.IsSupportedStandardExpression(querySourceReferenceExpression), Is.False);

            var subQueryExpression = new SubQueryExpression(ExpressionHelper.CreateQueryModel <Cook>());

            Assert.That(ExpressionTreeVisitor.IsSupportedStandardExpression(subQueryExpression), Is.False);
        }
        protected override Expression VisitSubQuery(SubQueryExpression expression)
        {
            // If the sub query's main (and only) from clause is one of our aggregating group bys, then swap it
            GroupJoinClause groupJoin = LocateGroupJoinQuerySource(expression.QueryModel);

            if (groupJoin != null)
            {
                Expression innerSelector = new SwapQuerySourceVisitor(groupJoin.JoinClause, expression.QueryModel.MainFromClause).
                                           Swap(groupJoin.JoinClause.InnerKeySelector);

                expression.QueryModel.MainFromClause.FromExpression = groupJoin.JoinClause.InnerSequence;

                // TODO - this only works if the key selectors are not composite.  Needs improvement...
                expression.QueryModel.BodyClauses.Add(new WhereClause(Expression.Equal(innerSelector, groupJoin.JoinClause.OuterKeySelector)));
            }

            return(expression);
        }
Exemple #35
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression subQueryExpression)
        {
            var queryModelVisitor = CreateQueryModelVisitor();

            queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel);

            var subExpression = queryModelVisitor.Expression;

            var streamedSequenceInfo
                = subQueryExpression.QueryModel.GetOutputDataInfo() as StreamedSequenceInfo;

            if (streamedSequenceInfo == null)
            {
                return(subExpression);
            }

            var typeInfo = subQueryExpression.Type.GetTypeInfo();

            if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(typeInfo))
            {
                subExpression
                    = Expression.Call(
                          QueryModelVisitor.LinqOperatorProvider.AsQueryable
                          .MakeGenericMethod(streamedSequenceInfo.ResultItemType),
                          subExpression);
            }
            else if (typeInfo.IsGenericType &&
                     typeInfo.GetGenericTypeDefinition() == typeof(IOrderedEnumerable <>))
            {
                var elementType
                    = subExpression.Type.TryGetElementType(typeof(IOrderedAsyncEnumerable <>));

                if (elementType != null)
                {
                    subExpression
                        = Expression.Call(
                              QueryModelVisitor.LinqOperatorProvider.AsQueryable
                              .MakeGenericMethod(streamedSequenceInfo.ResultItemType),
                              subExpression);
                }
            }

            return(Expression.Convert(subExpression, subQueryExpression.Type));
        }
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			// If the sub query's main (and only) from clause is one of our aggregating group bys, then swap it
			GroupJoinClause groupJoin = LocateGroupJoinQuerySource(expression.QueryModel);

			if (groupJoin != null)
			{
				Expression innerSelector = new SwapQuerySourceVisitor(groupJoin.JoinClause, expression.QueryModel.MainFromClause).
					Swap(groupJoin.JoinClause.InnerKeySelector);

				expression.QueryModel.MainFromClause.FromExpression = groupJoin.JoinClause.InnerSequence;


				// TODO - this only works if the key selectors are not composite.  Needs improvement...
				expression.QueryModel.BodyClauses.Add(new WhereClause(Expression.Equal(innerSelector, groupJoin.JoinClause.OuterKeySelector)));
			}

			return expression;
		}
        protected override Expression VisitSubQueryExpression(SubQueryExpression subQuery)
        {
            if ((subQuery.QueryModel.BodyClauses.Count == 0) &&
                ((subQuery.QueryModel.ResultOperators.Count == 0) || (subQuery.QueryModel.ResultOperators.Count == 1 && subQuery.QueryModel.ResultOperators[0] is CacheableResultOperator))
                )
            {
                var selectQuerySource =
                    subQuery.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression;

                if (selectQuerySource != null && selectQuerySource.ReferencedQuerySource == subQuery.QueryModel.MainFromClause)
                {
                    if (subQuery.QueryModel.ResultOperators.Count == 1)
                    {
                        _model.ResultOperators.Add(subQuery.QueryModel.ResultOperators[0]);
                    }

                    return subQuery.QueryModel.MainFromClause.FromExpression;
                }
            }

            return base.VisitSubQueryExpression(subQuery);
        }
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1)
            {
                ResultOperatorBase resultOperator = expression.QueryModel.ResultOperators[0];

                if (resultOperator is AverageResultOperator)
                {
                    return new AverageExpression(expression.QueryModel.SelectClause.Selector);
                }
                else if (resultOperator is MinResultOperator)
                {
                    return new MinExpression(expression.QueryModel.SelectClause.Selector);
                }
                else if (resultOperator is MaxResultOperator)
                {
                    return new MaxExpression(expression.QueryModel.SelectClause.Selector);
                }
                else if (resultOperator is CountResultOperator)
                {
                    return new CountExpression();
                }
                else if (resultOperator is SumResultOperator)
                {
                    return new SumExpression(expression.QueryModel.SelectClause.Selector);                    
                }
                else
                {
                    throw new NotImplementedException();
                }
            }
            else
            {
                return base.VisitSubQueryExpression(expression);
            }
        }
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			MergeAggregatingResultsRewriter.ReWrite(expression.QueryModel);
			return expression;
		}
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			VisitExpression(expression.QueryModel.SelectClause.Selector);
			return expression;
		}
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			expression.QueryModel.TransformExpressions(VisitExpression);
			return base.VisitSubQueryExpression(expression);
		}
		protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
		{
			// TODO - is this safe?  All we are extracting is the select clause from the sub-query.  Assumes that everything
			// else in the subquery has been removed.  If there were two subqueries, one aggregating & one not, this may not be a 
			// valid assumption.  Should probably be passed a list of aggregating subqueries that we are flattening so that we can check...
			return GroupBySelectClauseRewriter.ReWrite(expression.QueryModel.SelectClause.Selector, _groupBy, _model);
		}
            protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
            {
                this.resultOperators.AddRange(
                    expression.QueryModel.ResultOperators
                        .Where(r => rewrittenTypes.Any(t => t.IsAssignableFrom(r.GetType()))));

                this.resultOperators.ForEach(f => expression.QueryModel.ResultOperators.Remove(f));
                this.evaluationType = expression.QueryModel.SelectClause.GetOutputDataInfo();

                if (expression.QueryModel.ResultOperators.Count == 0)
                {
                    return expression.QueryModel.MainFromClause.FromExpression;
                }

                return base.VisitSubQueryExpression(expression);
            }
        protected HqlTreeNode VisitSubQueryExpression(SubQueryExpression expression)
        {
            ExpressionToHqlTranslationResults query = QueryModelVisitor.GenerateHqlQuery(expression.QueryModel, _parameters, false);

            return query.Statement;
        }
		private Expression CreateAggregate(Expression fromClauseExpression, LambdaExpression body, Func<Expression,Expression> aggregateFactory, Func<ResultOperatorBase> resultOperatorFactory)
		{
            // TODO - need generated name here
			var fromClause = new MainFromClause("x2", body.Parameters[0].Type, fromClauseExpression);
			var selectClause = body.Body;
			selectClause = ReplacingExpressionTreeVisitor.Replace(body.Parameters[0],
			                                                      new QuerySourceReferenceExpression(
			                                                      	fromClause), selectClause);
			var queryModel = new QueryModel(fromClause,
			                                new SelectClause(aggregateFactory(selectClause)));

            // TODO - this sucks, but we use it to get the Type of the SubQueryExpression correct
            queryModel.ResultOperators.Add(resultOperatorFactory());

			var subQuery = new SubQueryExpression(queryModel);

			queryModel.ResultOperators.Clear();

			return subQuery;
		}