protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { ContainsAggregateMethods = new GroupByAggregateDetectionVisitor().Visit(expression.QueryModel.SelectClause.Selector); return expression; }
private void FlattenSubQuery(SubQueryExpression subQueryExpression, 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; // Replace the outer from clause... queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause; 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 subQuery) { var hasBodyClauses = subQuery.QueryModel.BodyClauses.Count > 0; if(hasBodyClauses) { return base.VisitSubQueryExpression(subQuery); } var resultOperators = subQuery.QueryModel.ResultOperators; if (resultOperators.Count == 0 || HasJustAllFlattenableOperator(resultOperators)) { var selectQuerySource = subQuery.QueryModel.SelectClause.Selector as QuerySourceReferenceExpression; if (selectQuerySource != null && selectQuerySource.ReferencedQuerySource == subQuery.QueryModel.MainFromClause) { foreach (var resultOperator in resultOperators) { _model.ResultOperators.Add(resultOperator); } return subQuery.QueryModel.MainFromClause.FromExpression; } } return base.VisitSubQueryExpression(subQuery); }
public void Replaces_SubQueryExpressions () { var expression = new SubQueryExpression (ExpressionHelper.CreateQueryModel<Cook> ()); var result = CloningExpressionTreeVisitor.AdjustExpressionAfterCloning (expression, _querySourceMapping); Assert.That (((SubQueryExpression) result).QueryModel, Is.Not.SameAs (expression.QueryModel)); }
public void VisitSubQuery_ExpressionUnchanged () { var expression = new SubQueryExpression (ExpressionHelper.CreateQueryModel<Cook> ()); var result = ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences (expression, _querySourceMapping, false); Assert.That (((SubQueryExpression) result).QueryModel, Is.SameAs (expression.QueryModel)); }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) { // Create a new client-side select for the outer var clientSideSelect = CreateClientSideSelect(subQueryExpression, queryModel); var subQueryModel = subQueryExpression.QueryModel; // Replace the outer select clause... queryModel.SelectClause = subQueryModel.SelectClause; // Replace the outer from clause... queryModel.MainFromClause = subQueryModel.MainFromClause; foreach (var bodyClause in subQueryModel.BodyClauses) { queryModel.BodyClauses.Add(bodyClause); } // Move the result operator up if (queryModel.ResultOperators.Count != 0) { throw new NotImplementedException(); } queryModel.ResultOperators.Add(new NonAggregatingGroupBy((GroupResultOperator) subQueryModel.ResultOperators[0])); queryModel.ResultOperators.Add(clientSideSelect); }
protected internal override Expression VisitSubQuery (SubQueryExpression expression) { ArgumentUtility.CheckNotNull ("expression", expression); expression.QueryModel.TransformExpressions (ReplaceTransparentIdentifiers); return expression; // Note that we modifiy the (mutable) QueryModel, we return an unchanged expression }
protected override void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel, int destinationIndex) { var subQueryModel = subQueryExpression.QueryModel; MoveResultOperatorsToParent(queryModel, subQueryModel); base.FlattenSubQuery(subQueryExpression, fromClause, queryModel, destinationIndex); }
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) { ArgumentUtility.CheckNotNull ("expression", expression); var clonedQueryModel = expression.QueryModel.Clone (QuerySourceMapping); return new SubQueryExpression (clonedQueryModel); }
protected override Expression VisitSubQueryExpression(SubQueryExpression expression) { var selector = expression.QueryModel.SelectClause.Selector; var value = Expression.Parameter(typeof (Tuple), "value"); var rewriter = new SelectClauseRewriter(value, values, expressions, tuple + 1); var resultSelector = rewriter.VisitExpression(selector); var where = EnumerableHelper.GetMethod("Where", new[] {typeof (IEnumerable<>), typeof (Func<,>)}, new[] {Tuple.Type}); var select = EnumerableHelper.GetMethod("Select", new[] {typeof (IEnumerable<>), typeof (Func<,>)}, new[] {Tuple.Type, selector.Type}); var toList = EnumerableHelper.GetMethod("ToList", new[] {typeof (IEnumerable<>)}, new[] {selector.Type}); return Expression.Call(Expression.Call(toList, Expression.Call(select, Expression.Call(where, values, WherePredicate), Expression.Lambda(resultSelector, value))), "AsReadOnly", System.Type.EmptyTypes); }
private static bool CheckShortCircuitSum(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true); if (subquery.ShouldQueryInMemory) { throw new NotImplementedException("Unsupported subquery. Please provide more info about query."); //return false; } var sql = subquery.BuildSqlString(false); var cnt = queryParts.CurrentSelectIndex; var selector = expression.QueryModel.SelectClause.Selector as MemberExpression; if (selector == null) return false; var type = expression.QueryModel.ResultTypeOverride; if (type.IsNullable()) type = type.GetGenericArguments()[0]; queryParts.AddSelectPart( expression.QueryModel.MainFromClause, @"(SELECT SUM((""{1}"").""{3}"") FROM ({2}) ""{1}"") AS ""{0}""".With( "_subquery_" + cnt, expression.QueryModel.MainFromClause.ItemName, sql, selector.Member.Name), "_sum_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), type)); return true; }
protected internal override Expression VisitSubQuery (SubQueryExpression expression) { ArgumentUtility.CheckNotNull ("expression", expression); expression.QueryModel.TransformExpressions (ex => ReplaceClauseReferences (ex, _querySourceMapping, _throwOnUnmappedReferences)); return expression; }
protected override Expression VisitSubQuery(SubQueryExpression expression) { var clonedModel = expression.QueryModel.Clone(); clonedModel.TransformExpressions(Visit); return new SubQueryExpression(clonedModel); }
public void Initialization () { var queryModel = ExpressionHelper.CreateQueryModel<Cook>(); var expression = new SubQueryExpression (queryModel); Assert.That (expression.Type, Is.SameAs (typeof(IQueryable<Cook>))); Assert.That (expression.QueryModel, Is.SameAs (queryModel)); Assert.That (expression.NodeType, Is.EqualTo (SubQueryExpression.ExpressionType)); }
protected override Expression VisitSubQueryExpression(SubQueryExpression subQueryExpression) { var queryModelVisitor = CreateQueryModelVisitor(); queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel); var subExpression = queryModelVisitor.Expression; var resultItemType = queryModelVisitor.StreamedSequenceInfo?.ResultItemType ?? subExpression.Type; if (queryModelVisitor.StreamedSequenceInfo == null) { return subExpression; } if (subExpression.Type != subQueryExpression.Type) { var subQueryExpressionTypeInfo = subQueryExpression.Type.GetTypeInfo(); if (typeof(IQueryable).GetTypeInfo().IsAssignableFrom(subQueryExpressionTypeInfo)) { subExpression = Expression.Call( QueryModelVisitor.LinqOperatorProvider.ToQueryable .MakeGenericMethod(resultItemType), subExpression); } else if (subQueryExpressionTypeInfo.IsGenericType) { var genericTypeDefinition = subQueryExpressionTypeInfo.GetGenericTypeDefinition(); if (genericTypeDefinition == typeof(IOrderedEnumerable<>)) { subExpression = Expression.Call( QueryModelVisitor.LinqOperatorProvider.ToOrdered .MakeGenericMethod(resultItemType), subExpression); } else if (genericTypeDefinition == typeof(IEnumerable<>)) { subExpression = Expression.Call( QueryModelVisitor.LinqOperatorProvider.ToEnumerable .MakeGenericMethod(resultItemType), subExpression); } } } return subExpression; }
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)); }
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)); }
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); ReplacingExpressionVisitor.Replace (replacedNode, replacementNode, tree); Assert.That (subQueryMainFromClause.FromExpression, Is.SameAs (replacementNode)); }
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 ); }
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 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); } 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; }
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); }
private IWhereFragment GetWhereFragment(DocumentMapping mapping, SubQueryExpression expression) { var queryType = expression.QueryModel.MainFromClause.ItemType; if (TypeMappings.HasTypeMapping(queryType)) { var contains = expression.QueryModel.ResultOperators.OfType<ContainsResultOperator>().FirstOrDefault(); if (contains != null) { return ContainmentWhereFragment.SimpleArrayContains(_serializer, expression.QueryModel, contains); } } if (expression.QueryModel.ResultOperators.Any(x => x is AnyResultOperator)) { return new CollectionAnyContainmentWhereFragment(_serializer, expression); } throw new NotImplementedException(); }
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; }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, FromClauseBase fromClause, QueryModel queryModel, int destinationIndex) { if (!CheckFlattenable(subQueryExpression.QueryModel)) return; var mainFromClause = subQueryExpression.QueryModel.MainFromClause; CopyFromClauseData(mainFromClause, fromClause); var innerSelectorMapping = new QuerySourceMapping(); innerSelectorMapping.AddMapping(fromClause, subQueryExpression.QueryModel.SelectClause.Selector); queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerSelectorMapping, false))); InsertBodyClauses(subQueryExpression.QueryModel.BodyClauses, queryModel, destinationIndex); CopyResultOperators(subQueryExpression.QueryModel.ResultOperators, queryModel); var innerBodyClauseMapping = new QuerySourceMapping(); innerBodyClauseMapping.AddMapping(mainFromClause, new QuerySourceReferenceExpression(fromClause)); queryModel.TransformExpressions((ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerBodyClauseMapping, false))); }
private static void FlattenSubQuery(SubQueryExpression subQueryExpression, QueryModel queryModel) { // Move the result operator up if (queryModel.ResultOperators.Count != 0) { throw new NotImplementedException(); } var groupBy = (GroupResultOperator) subQueryExpression.QueryModel.ResultOperators[0]; queryModel.ResultOperators.Add(groupBy); for (int i = 0; i < queryModel.BodyClauses.Count; i++) { var clause = queryModel.BodyClauses[i]; clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel)); //all outer where clauses actually are having clauses var whereClause = clause as WhereClause; if (whereClause != null) { queryModel.BodyClauses.RemoveAt(i); queryModel.BodyClauses.Insert(i, new NhHavingClause(whereClause.Predicate)); } } foreach (var bodyClause in subQueryExpression.QueryModel.BodyClauses) { queryModel.BodyClauses.Add(bodyClause); } // Replace the outer select clause... queryModel.SelectClause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryExpression.QueryModel)); // Point all query source references to the outer from clause queryModel.TransformExpressions(s => new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryExpression.QueryModel.MainFromClause).Swap(s)); // Replace the outer query source queryModel.MainFromClause = subQueryExpression.QueryModel.MainFromClause; }
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); } 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); } } var visitor1 = new PagingRewriterSelectClauseVisitor(); queryModel.SelectClause.TransformExpressions(visitor1.Swap); // 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; }
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; if (pattern.Type.IsPrimitive) { pattern = Expression.Constant(((ConstantExpression)pattern).Value, typeof(object)); } return Expression.MakeBinary(ExpressionType.Equal, field, pattern); } return base.VisitSubQueryExpression(expression); }
private static bool CheckShortCircuitCount(SubQueryExpression expression, MainQueryParts queryParts, Action<Expression> visitExpression) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(expression.QueryModel, queryParts, true); if (subquery.ShouldQueryInMemory) { throw new NotImplementedException("Unsupported subquery. Please provide more info about query."); //return false; } var cnt = queryParts.CurrentSelectIndex; var mq = subquery.MainFrom.FromExpression as QuerySourceReferenceExpression; if (mq != null && subquery.Joins.Count == 0 && subquery.AdditionalJoins.Count == 0 && subquery.Conditions.Count == 0) { if (mq.ReferencedQuerySource.ItemType.IsGrouping()) { queryParts.AddSelectPart( expression.QueryModel.MainFromClause, "ARRAY_UPPER(\"{0}\".\"Values\", 1) AS \"_count_helper_{1}\"".With(mq.ReferencedQuerySource.ItemName, cnt), "_count_helper_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride)); return true; } } var sql = subquery.BuildSqlString(false); queryParts.AddSelectPart( expression.QueryModel.MainFromClause, @"(SELECT COUNT(""{1}"") FROM ({2}) ""{1}"") AS ""{0}"" ".With( "_subquery_" + cnt, expression.QueryModel.MainFromClause.ItemName, sql), "_count_" + cnt, expression.QueryModel.ResultTypeOverride, (_, dr) => dr.IsDBNull(cnt) ? 0 : Convert.ChangeType(dr.GetValue(cnt), expression.QueryModel.ResultTypeOverride)); return true; }
/// <summary> /// We are going after a query model - bounce this back up a level. /// </summary> /// <param name="expression"></param> /// <returns></returns> protected override System.Linq.Expressions.Expression VisitSubQuery(Remotion.Linq.Clauses.Expressions.SubQueryExpression expression) { _qmVisitor.VisitQueryModel(expression.QueryModel); return(expression); }