public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var subQueryExpression = fromClause.FromExpression as SubQueryExpression; if (subQueryExpression != null) FlattenSubQuery(subQueryExpression, fromClause, queryModel, index + 1); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public void SetUp () { _detailSource = ExpressionHelper.CreateQueryable<Kitchen>(); _sectorSource = ExpressionHelper.CreateQueryable<Restaurant>(); var query = from s1 in ExpressionHelper.CreateQueryable<Cook>() from sd in (from sector in _sectorSource where sector.ID > 10 select sector.SubKitchen) from s2 in s1.Assistants where sd.Name == "Maths" select new NonTransformedTuple<Cook, Kitchen> (s1, sd); _queryModel = ExpressionHelper.ParseQuery (query); _mainFromClause = _queryModel.MainFromClause; _additionalFromClause1 = (AdditionalFromClause) _queryModel.BodyClauses[0]; _additionalFromClause2 = (AdditionalFromClause) _queryModel.BodyClauses[1]; _whereClause = (WhereClause) _queryModel.BodyClauses[2]; _selectClause = _queryModel.SelectClause; var subQueryExpressionA = (SubQueryExpression) _additionalFromClause1.FromExpression; _innerMainFromClauseA = subQueryExpressionA.QueryModel.MainFromClause; _innerWhereClauseA = (WhereClause) subQueryExpressionA.QueryModel.BodyClauses[0]; _visitor = new SubQueryFromClauseFlattener(); }
public virtual void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { ArgumentUtility.CheckNotNull ("fromClause", fromClause); ArgumentUtility.CheckNotNull ("queryModel", queryModel); // nothing to do here }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var subQuery = fromClause.FromExpression as SubQueryExpression; if (subQuery == null) return; var subQueryModel = subQuery.QueryModel; if (!IsLeftJoin(subQueryModel)) return; var mainFromClause = subQueryModel.MainFromClause; var restrictions = subQueryModel.BodyClauses .OfType<WhereClause>() .Select(w => new NhWithClause(w.Predicate)); var join = new NhJoinClause(mainFromClause.ItemName, mainFromClause.ItemType, mainFromClause.FromExpression, restrictions); var innerSelectorMapping = new QuerySourceMapping(); innerSelectorMapping.AddMapping(fromClause, subQueryModel.SelectClause.Selector); queryModel.TransformExpressions(ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerSelectorMapping, false)); queryModel.BodyClauses.RemoveAt(index); queryModel.BodyClauses.Insert(index, @join); InsertBodyClauses(subQueryModel.BodyClauses.Where(b => !(b is WhereClause)), queryModel, index + 1); var innerBodyClauseMapping = new QuerySourceMapping(); innerBodyClauseMapping.AddMapping(mainFromClause, new QuerySourceReferenceExpression(@join)); queryModel.TransformExpressions(ex => ReferenceReplacingExpressionTreeVisitor.ReplaceClauseReferences(ex, innerBodyClauseMapping, false)); }
/// <summary> /// Clones this clause, registering its clone with the <paramref name="cloneContext"/>. /// </summary> /// <param name="cloneContext">The clones of all query source clauses are registered with this <see cref="CloneContext"/>.</param> /// <returns>A clone of this clause.</returns> public virtual AdditionalFromClause Clone (CloneContext cloneContext) { ArgumentUtility.CheckNotNull ("cloneContext", cloneContext); var clone = new AdditionalFromClause (ItemName, ItemType, FromExpression); cloneContext.QuerySourceMapping.AddMapping (this, new QuerySourceReferenceExpression (clone)); return clone; }
public void Initialize () { var fromExpression = ExpressionHelper.CreateExpression (); var fromClause = new AdditionalFromClause ("s", typeof (Cook), fromExpression); Assert.That (fromClause.ItemName, Is.EqualTo ("s")); Assert.That (fromClause.ItemType, Is.SameAs (typeof (Cook))); Assert.That (fromClause.FromExpression, Is.SameAs (fromExpression)); }
protected override void ModifyFetchQueryModel(QueryModel fetchQueryModel) { ArgumentUtility.CheckNotNull<QueryModel>("fetchQueryModel", fetchQueryModel); System.Linq.Expressions.MemberExpression fromExpression = System.Linq.Expressions.Expression.MakeMemberAccess(new QuerySourceReferenceExpression(fetchQueryModel.MainFromClause), base.RelationMember); AdditionalFromClause additionalFromClause = new AdditionalFromClause(fetchQueryModel.GetNewName("#fetch"), this._relatedObjectType, fromExpression); fetchQueryModel.BodyClauses.Add(additionalFromClause); QuerySourceReferenceExpression selector = new QuerySourceReferenceExpression(additionalFromClause); SelectClause selectClause = new SelectClause(selector); fetchQueryModel.SelectClause = selectClause; }
public override void VisitAdditionalFromClause (AdditionalFromClause fromClause, QueryModel queryModel, int index) { ArgumentUtility.CheckNotNull ("fromClause", fromClause); ArgumentUtility.CheckNotNull ("queryModel", queryModel); var subQueryExpression = fromClause.FromExpression as SubQueryExpression; if (subQueryExpression != null) FlattenSubQuery (subQueryExpression, fromClause, queryModel, index + 1); base.VisitAdditionalFromClause (fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var luceneExpression = new LuceneIndexExpression(); luceneExpression.AttachIndex(fromClause.ItemType.GetContractId()); luceneExpression.Append(fromClause.ItemType.GetContractId()); _queryParts.AddFromPart(luceneExpression); fromClause.ItemName = "EventInternal"; base.VisitAdditionalFromClause(fromClause, queryModel, index); }
/// <summary> /// Modifies the given query model for fetching, adding an <see cref="AdditionalFromClause"/> and changing the <see cref="SelectClause.Selector"/> to /// retrieve the result of the <see cref="AdditionalFromClause"/>. /// For example, a fetch request such as <c>FetchMany (x => x.Orders)</c> will be transformed into a <see cref="AdditionalFromClause"/> selecting /// <c>y.Orders</c> (where <c>y</c> is what the query model originally selected) and a <see cref="SelectClause"/> selecting the result of the /// <see cref="AdditionalFromClause"/>. /// This method is called by <see cref="FetchRequestBase.CreateFetchQueryModel"/> in the process of creating the new fetch query model. /// </summary> protected override void ModifyFetchQueryModel (QueryModel fetchQueryModel) { ArgumentUtility.CheckNotNull ("fetchQueryModel", fetchQueryModel); var fromExpression = Expression.MakeMemberAccess (new QuerySourceReferenceExpression (fetchQueryModel.MainFromClause), RelationMember); var memberFromClause = new AdditionalFromClause (fetchQueryModel.GetNewName ("#fetch"), _relatedObjectType, fromExpression); fetchQueryModel.BodyClauses.Add (memberFromClause); var newSelector = new QuerySourceReferenceExpression (memberFromClause); var newSelectClause = new SelectClause (newSelector); fetchQueryModel.SelectClause = newSelectClause; }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { if (_type.IsAssignableFrom(fromClause.ItemType)) { if (_querySource == null) { _querySource = fromClause; return; } } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public void CopyFromSource () { var fromExpression = ExpressionHelper.CreateExpression (); var fromClause = new AdditionalFromClause ("s", typeof (Cook), fromExpression); var newExpression = ExpressionHelper.CreateExpression (); var sourceStub = MockRepository.GenerateStub<IFromClause>(); sourceStub.Stub (_ => _.ItemName).Return ("newItemName"); sourceStub.Stub (_ => _.ItemType).Return (typeof (Kitchen)); sourceStub.Stub (_ => _.FromExpression).Return (newExpression); fromClause.CopyFromSource (sourceStub); Assert.That (fromClause.ItemName, Is.EqualTo ("newItemName")); Assert.That (fromClause.ItemType, Is.SameAs (typeof (Kitchen))); Assert.That (fromClause.FromExpression, Is.SameAs (newExpression)); }
public void VisitAdditionalFromClause_ThrowsOnResultOperator () { var queryModel = ExpressionHelper.CreateQueryModel<Cook> (); queryModel.ResultOperators.Add (new DistinctResultOperator ()); var clause = new AdditionalFromClause ("x", typeof (Cook), new SubQueryExpression (queryModel)); _visitor.VisitAdditionalFromClause (clause, _queryModel, 0); }
public void VisitAdditionalFromClause_ThrowsOnOrderBy () { var queryModel = ExpressionHelper.CreateQueryModel<Cook> (); var orderByClause = new OrderByClause (); orderByClause.Orderings.Add (new Ordering (Expression.Constant (0), OrderingDirection.Asc)); queryModel.BodyClauses.Add (orderByClause); var clause = new AdditionalFromClause ("x", typeof (Cook), new SubQueryExpression (queryModel)); _visitor.VisitAdditionalFromClause (clause, _queryModel, 0); }
public void AddJoin(AdditionalFromClause join) { AdditionalJoins.Add(join); }
/// <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> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) => fromClause.TransformExpressions(TransformingVisitor.Visit);
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var querySourceName = VisitorParameters.QuerySourceNamer.GetName(fromClause); var joinClause = fromClause as NhJoinClause; if (joinClause != null) { VisitNhJoinClause(querySourceName, joinClause); } else if (fromClause.FromExpression is MemberExpression) { // It's a join _hqlTree.AddFromClause( _hqlTree.TreeBuilder.Join( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(), _hqlTree.TreeBuilder.Alias(querySourceName))); } else { // TODO - exact same code as in MainFromClause; refactor this out _hqlTree.AddFromClause( _hqlTree.TreeBuilder.Range( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters), _hqlTree.TreeBuilder.Alias(querySourceName))); } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
/// <summary> /// Visit an AdditionalFromClause referencing a previous group join clause /// </summary> /// <param name="fromClause">AdditionalFromClause being visited</param> /// <param name="subQuery">SubQueryExpression being visited</param> /// <param name="querySourceReference">QuerySourceReferenceExpression that is the MainFromClause of the SubQuery</param> /// <returns>N1QlFromQueryPart to be added to the QueryPartsAggregator. JoinType is defaulted to INNER UNNEST.</returns> private bool VisitSubQuerySourceReferenceExpression(AdditionalFromClause fromClause, SubQueryExpression subQuery, QuerySourceReferenceExpression querySourceReference) { var unclaimedJoin = _unclaimedGroupJoins.FirstOrDefault( p => p.GroupJoinClause == querySourceReference.ReferencedQuerySource); if (unclaimedJoin != null) { // this additional from clause is for a previous group join // if not, then it isn't supported and we'll let the method return false so an exception is thrown var fromPart = ParseJoinClause(unclaimedJoin.JoinClause); if (subQuery.QueryModel.ResultOperators.OfType<DefaultIfEmptyResultOperator>().Any()) { fromPart.JoinType = "LEFT JOIN"; // TODO Handle where clauses applied to the inner sequence before the join // Currently they are filtered after the join is complete instead of before by N1QL } // Be sure that any reference to the subquery gets the join clause extent name _queryGenerationContext.ExtentNameProvider.LinkExtents(unclaimedJoin.JoinClause, fromClause); _unclaimedGroupJoins.Remove(unclaimedJoin); _queryPartsAggregator.AddFromPart(fromPart); return true; } return false; }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { QueryParts.AddJoin(fromClause); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { throw new NotSupportedException("Additional from clauses not supported"); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { var querySourceName = VisitorParameters.QuerySourceNamer.GetName(fromClause); if (fromClause is NhJoinClause) { if (((NhJoinClause)fromClause).IsInner) { _hqlTree.AddFromClause( _hqlTree.TreeBuilder.Join( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(), _hqlTree.TreeBuilder.Alias(querySourceName))); } else { _hqlTree.AddFromClause( _hqlTree.TreeBuilder.LeftJoin( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(), _hqlTree.TreeBuilder.Alias(querySourceName))); } } else if (fromClause.FromExpression is MemberExpression) { var member = (MemberExpression)fromClause.FromExpression; if (member.Expression is QuerySourceReferenceExpression) { // It's a join _hqlTree.AddFromClause( _hqlTree.TreeBuilder.Join( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(), _hqlTree.TreeBuilder.Alias(querySourceName))); } else { // What's this? throw new NotSupportedException(); } } else { // TODO - exact same code as in MainFromClause; refactor this out _hqlTree.AddFromClause( _hqlTree.TreeBuilder.Range( HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters), _hqlTree.TreeBuilder.Alias(querySourceName))); } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { EnsureNotArraySubquery(); var handled = false; switch (fromClause.FromExpression.NodeType) { case ExpressionType.MemberAccess: // Unnest operation var fromPart = VisitMemberFromExpression(fromClause, fromClause.FromExpression as MemberExpression); _queryPartsAggregator.AddFromPart(fromPart); handled = true; break; case SubQueryExpression.ExpressionType: // Might be an unnest or a join to another bucket handled = VisitSubQueryFromExpression(fromClause, fromClause.FromExpression as SubQueryExpression); break; } if (!handled) { throw new NotSupportedException("N1QL Does Not Support This Type Of From Clause"); } base.VisitAdditionalFromClause(fromClause, queryModel, index); }
public void SetUp () { _additionalFromClause = ExpressionHelper.CreateAdditionalFromClause(); _cloneContext = new CloneContext (new QuerySourceMapping ()); }
/// <summary> /// Additional from clauses attached to the top here. /// </summary> /// <param name="fromClause"></param> /// <param name="queryModel"></param> /// <param name="index"></param> public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _qmContextStack.Peek().AddFromItem(fromClause); _exprVisitor.Visit(fromClause.FromExpression); base.VisitAdditionalFromClause(fromClause, queryModel, index); }
/// <summary> /// Visit an AdditionalFromClause referencing a member /// </summary> /// <param name="fromClause">AdditionalFromClause being visited</param> /// <param name="expression">MemberExpression being referenced</param> /// <returns>N1QlFromQueryPart to be added to the QueryPartsAggregator. JoinType is defaulted to INNER UNNEST.</returns> private N1QlFromQueryPart VisitMemberFromExpression(AdditionalFromClause fromClause, MemberExpression expression) { // This case represents an unnest operation return new N1QlFromQueryPart() { Source = GetN1QlExpression(expression), ItemName = GetExtentName(fromClause), JoinType = "INNER UNNEST" }; }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { base.VisitAdditionalFromClause(fromClause, queryModel, index); }
protected override QueryModel ApplyNodeSpecificSemantics (QueryModel queryModel, ClauseGenerationContext clauseGenerationContext) { ArgumentUtility.CheckNotNull ("queryModel", queryModel); var resolvedCollectionSelector = GetResolvedCollectionSelector (clauseGenerationContext); var clause = new AdditionalFromClause (ResultSelector.Parameters[1].Name, ResultSelector.Parameters[1].Type, resolvedCollectionSelector); queryModel.BodyClauses.Add (clause); clauseGenerationContext.AddContextInfo (this, clause); var selectClause = queryModel.SelectClause; selectClause.Selector = GetResolvedResultSelector (clauseGenerationContext); return queryModel; }
public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel, int index) { _namer.Add(fromClause); }
internal FromClauseBase TryToSimplifyAdditionalFrom(AdditionalFromClause additionalFrom) { FromClauseBase from = additionalFrom; var sqe = from.FromExpression as SubQueryExpression; if (sqe != null) { var subquery = SubqueryGeneratorQueryModelVisitor.ParseSubquery(sqe.QueryModel, this, ContextName, Context.Select()); if (subquery.Joins.Count > 0 || subquery.ResultOperators.Any(it => it is CastResultOperator == false && it is DefaultIfEmptyResultOperator == false) || subquery.AdditionalJoins.Count > 0) return from; return TryToSimplifyMainFrom(sqe.QueryModel.MainFromClause); } return from; }
/// <summary> /// Visits an AdditionalFromClause that is executing a subquery /// </summary> /// <param name="fromClause">AdditionalFromClause being visited</param> /// <param name="subQuery">Subquery being executed by the AdditionalFromClause</param> /// <returns>True if handled</returns> private bool VisitSubQueryFromExpression(AdditionalFromClause fromClause, SubQueryExpression subQuery) { var mainFromExpression = subQuery.QueryModel.MainFromClause.FromExpression; switch (mainFromExpression.NodeType) { case QuerySourceReferenceExpression.ExpressionType: // Joining to another bucket using a previous group join operation return VisitSubQuerySourceReferenceExpression(fromClause, subQuery, mainFromExpression as QuerySourceReferenceExpression); case ExpressionType.MemberAccess: // Unnest operation var fromPart = VisitMemberFromExpression(fromClause, mainFromExpression as MemberExpression); if (subQuery.QueryModel.ResultOperators.OfType<DefaultIfEmptyResultOperator>().Any()) { fromPart.JoinType = "OUTER UNNEST"; } _queryPartsAggregator.AddFromPart(fromPart); // be sure the subquery clauses use the same extent name _queryGenerationContext.ExtentNameProvider.LinkExtents(fromClause, subQuery.QueryModel.MainFromClause); // Apply where filters in the subquery to the main query VisitBodyClauses(subQuery.QueryModel.BodyClauses, subQuery.QueryModel); return true; } return false; }