public void HandleResultOperator ()
    {
      var keySelector = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
      var elementSelector = Expression.Constant ("elementSelector");
      var resultOperator = new GroupResultOperator ("itemName", keySelector, elementSelector);

      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (keySelector, _context))
          .Return (keySelector);
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (elementSelector, _context))
          .Return (elementSelector);
      _stageMock.Replay();

      _handler.HandleResultOperator (resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

      _stageMock.VerifyAllExpectations();
      Assert.That (_sqlStatementBuilder.GroupByExpression, Is.SameAs (keySelector));
      
      var expectedSelectProjection = new SqlGroupingSelectExpression (
          new NamedExpression ("key", keySelector), 
          new NamedExpression ("element", elementSelector));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedSelectProjection, _sqlStatementBuilder.SelectProjection);

      Assert.That (
          _sqlStatementBuilder.DataInfo.DataType,
          Is.EqualTo (typeof (IQueryable<>).MakeGenericType (typeof (IGrouping<,>).MakeGenericType (typeof (string), typeof (string)))));
    }
Exemplo n.º 2
0
        public void HandleResultOperator()
        {
            var keySelector     = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(keySelector, _context))
            .Return(keySelector);
            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(elementSelector, _context))
            .Return(elementSelector);
            _stageMock.Replay();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

            _stageMock.VerifyAllExpectations();
            Assert.That(_sqlStatementBuilder.GroupByExpression, Is.SameAs(keySelector));

            var expectedSelectProjection = new SqlGroupingSelectExpression(
                new NamedExpression("key", keySelector),
                new NamedExpression("element", elementSelector));

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedSelectProjection, _sqlStatementBuilder.SelectProjection);

            Assert.That(
                _sqlStatementBuilder.DataInfo.DataType,
                Is.EqualTo(typeof(IQueryable <>).MakeGenericType(typeof(IGrouping <,>).MakeGenericType(typeof(string), typeof(string)))));
        }
Exemplo n.º 3
0
        private static Expression HandleGroup(
            EntityQueryModelVisitor entityQueryModelVisitor,
            GroupResultOperator groupResultOperator,
            QueryModel queryModel)
        {
            var keySelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.KeySelector,
                      queryModel.MainFromClause);

            var elementSelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.ElementSelector,
                      queryModel.MainFromClause);

            return(Expression.Call(
                       entityQueryModelVisitor.LinqOperatorProvider.GroupBy
                       .MakeGenericMethod(
                           typeof(QuerySourceScope),
                           groupResultOperator.KeySelector.Type,
                           groupResultOperator.ElementSelector.Type),
                       entityQueryModelVisitor.CreateScope(
                           entityQueryModelVisitor.Expression,
                           entityQueryModelVisitor.StreamedSequenceInfo.ResultItemType,
                           queryModel.MainFromClause),
                       Expression.Lambda(keySelector, EntityQueryModelVisitor.QuerySourceScopeParameter),
                       Expression.Lambda(elementSelector, EntityQueryModelVisitor.QuerySourceScopeParameter)));
        }
Exemplo n.º 4
0
        public static bool IsGroupingKeyOf(this MemberExpression expression, GroupResultOperator groupBy)
        {
            if (!expression.IsGroupingKey())
            {
                return(false);
            }

            var querySource = expression.Expression as QuerySourceReferenceExpression;

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

            var fromClause = querySource.ReferencedQuerySource as MainFromClause;

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

            var query = fromClause.FromExpression as SubQueryExpression;

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

            return(query.QueryModel.ResultOperators.Contains(groupBy));
        }
Exemplo n.º 5
0
        public void SetUp()
        {
            _fromClause1 = ExpressionHelper.CreateMainFromClause_Int("i", typeof(int), ExpressionHelper.CreateIntQueryable());
            _fromClause2 = ExpressionHelper.CreateMainFromClause_Int("j", typeof(int), ExpressionHelper.CreateIntQueryable());

            _keySelector     = ExpressionHelper.Resolve <int, int> (_fromClause2, j => j % 3);
            _elementSelector = ExpressionHelper.Resolve <int, string> (_fromClause1, i => i.ToString());
            _resultOperator  = new GroupResultOperator("groupings", _keySelector, _elementSelector);

            _cloneContext = new CloneContext(new QuerySourceMapping());
        }
    public void SetUp ()
    {
      _fromClause1 = ExpressionHelper.CreateMainFromClause_Int ("i", typeof (int), ExpressionHelper.CreateIntQueryable ());
      _fromClause2 = ExpressionHelper.CreateMainFromClause_Int ("j", typeof (int), ExpressionHelper.CreateIntQueryable ());

      _keySelector = ExpressionHelper.Resolve<int, int> (_fromClause2, j => j % 3);
      _elementSelector = ExpressionHelper.Resolve<int, string> (_fromClause1, i => i.ToString ());
      _resultOperator = new GroupResultOperator ("groupings", _keySelector, _elementSelector);

      _cloneContext = new CloneContext (new QuerySourceMapping ());
    }
Exemplo n.º 7
0
 public static IEnumerable <Expression> ExtractKeyExpressions(this GroupResultOperator groupResult)
 {
     if (groupResult.KeySelector is NewExpression)
     {
         return((groupResult.KeySelector as NewExpression).Arguments);
     }
     if (groupResult.KeySelector is NewArrayExpression)
     {
         return((groupResult.KeySelector as NewArrayExpression).Expressions);
     }
     return(new [] { groupResult.KeySelector });
 }
Exemplo n.º 8
0
        private static Expression HandleGroup(
            EntityQueryModelVisitor entityQueryModelVisitor,
            GroupResultOperator groupResultOperator,
            QueryModel queryModel)
        {
            var keySelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.KeySelector,
                      queryModel.MainFromClause);

            var elementSelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.ElementSelector,
                      queryModel.MainFromClause);

            var taskLiftingExpressionVisitor = new TaskLiftingExpressionVisitor();
            var asyncElementSelector         = taskLiftingExpressionVisitor.LiftTasks(elementSelector);

            var expression
                = asyncElementSelector == elementSelector
                    ? Expression.Call(
                      entityQueryModelVisitor.LinqOperatorProvider.GroupBy
                      .MakeGenericMethod(
                          entityQueryModelVisitor.Expression.Type.GetSequenceType(),
                          keySelector.Type,
                          elementSelector.Type),
                      entityQueryModelVisitor.Expression,
                      Expression.Lambda(keySelector, entityQueryModelVisitor.CurrentParameter),
                      Expression.Lambda(elementSelector, entityQueryModelVisitor.CurrentParameter))
                    : Expression.Call(
                      _groupByAsync
                      .MakeGenericMethod(
                          entityQueryModelVisitor.Expression.Type.GetSequenceType(),
                          keySelector.Type,
                          elementSelector.Type),
                      entityQueryModelVisitor.Expression,
                      Expression.Lambda(keySelector, entityQueryModelVisitor.CurrentParameter),
                      Expression.Lambda(
                          asyncElementSelector,
                          entityQueryModelVisitor.CurrentParameter,
                          taskLiftingExpressionVisitor.CancellationTokenParameter));

            entityQueryModelVisitor.CurrentParameter
                = Expression.Parameter(expression.Type.GetSequenceType(), groupResultOperator.ItemName);

            entityQueryModelVisitor.QueryCompilationContext.AddOrUpdateMapping(groupResultOperator, entityQueryModelVisitor.CurrentParameter);

            return(expression);
        }
        public void HandleResultOperator_GroupByAfterSetOperations()
        {
            _sqlStatementBuilder.SetOperationCombinedStatements.Add(SqlStatementModelObjectMother.CreateSetOperationCombinedStatement());

            var keySelector     = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

            var stage = CreateDefaultSqlPreparationStage();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, UniqueIdentifierGenerator, stage, _context);

            AssertStatementWasMovedToSubStatement(_sqlStatementBuilder);
        }
Exemplo n.º 10
0
 public static void ExtractKeyExpressions(this GroupResultOperator groupResult, IList <Expression> groupByKeys)
 {
     if (groupResult.KeySelector is NewExpression)
     {
         (groupResult.KeySelector as NewExpression).Arguments.ForEach(groupByKeys.Add);
     }
     else if (groupResult.KeySelector is NewArrayExpression)
     {
         (groupResult.KeySelector as NewArrayExpression).Expressions.ForEach(groupByKeys.Add);
     }
     else
     {
         groupByKeys.Add(groupResult.KeySelector);
     }
 }
Exemplo n.º 11
0
        protected virtual void VisitGroupResultOperator(GroupResultOperator groupResultOperator, QueryModel queryModel)
        {
            _groupingExpressionTransformerRegistry = new ExpressionTransformerRegistry();

            // Add GROUP BY clause for the grouping key
            // And add transformations for any references to the key

            if (groupResultOperator.KeySelector.NodeType == ExpressionType.New)
            {
                // Grouping by a multipart key, so add each key to the GROUP BY clause

                var newExpression = (NewExpression)groupResultOperator.KeySelector;

                foreach (var argument in newExpression.Arguments)
                {
                    _queryPartsAggregator.AddGroupByPart(GetN1QlExpression(argument));
                }

                // Use MultiKeyExpressionTransformer to remap access to the Key property

                _groupingExpressionTransformerRegistry.Register(
                    new MultiKeyExpressionTransfomer(_queryGenerationContext.GroupingQuerySource, newExpression));
            }
            else
            {
                // Grouping by a single column

                _queryPartsAggregator.AddGroupByPart(GetN1QlExpression(groupResultOperator.KeySelector));

                // Use KeyExpressionTransformer to remap access to the Key property

                _groupingExpressionTransformerRegistry.Register(
                    new KeyExpressionTransfomer(_queryGenerationContext.GroupingQuerySource, groupResultOperator.KeySelector));
            }

            // Add transformations for any references to the element selector

            if (groupResultOperator.ElementSelector.NodeType == QuerySourceReferenceExpression.ExpressionType)
            {
                _queryGenerationContext.ExtentNameProvider.LinkExtents(
                    ((QuerySourceReferenceExpression)groupResultOperator.ElementSelector).ReferencedQuerySource,
                    _queryGenerationContext.GroupingQuerySource.ReferencedQuerySource);
            }
            else
            {
                throw new NotSupportedException("Unsupported GroupResultOperator ElementSelector Type");
            }
        }
        public void HandleResultOperator_GroupByAfterTopExpression()
        {
            var topExpression = Expression.Constant("top");

            _sqlStatementBuilder.TopExpression = topExpression;

            var stage = CreateDefaultSqlPreparationStage();

            var keySelector     = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, UniqueIdentifierGenerator, stage, _context);

            AssertStatementWasMovedToSubStatement(_sqlStatementBuilder);
        }
Exemplo n.º 13
0
        private static void RemoveCostantGroupByKeys(QueryModel queryModel, GroupResultOperator groupBy)
        {
            var keys = groupBy.ExtractKeyExpressions().Where(x => !(x is ConstantExpression)).ToList();

            if (!keys.Any())
            {
                // Remove the Group By clause completely if all the keys are constant (redundant)
                queryModel.ResultOperators.Remove(groupBy);
            }
            else
            {
                // Re-write the KeySelector as an object array of the non-constant keys
                // This should be safe because we've already re-written the select clause using the original keys
                groupBy.KeySelector = Expression.NewArrayInit(typeof(object), keys.Select(x => x.Type.IsValueType ? Expression.Convert(x, typeof(object)) : x));
            }
        }
Exemplo n.º 14
0
        public void HandleResultOperator_GroupByAfterGroupBy()
        {
            var groupByExpression = Expression.Constant("group");

            _sqlStatementBuilder.GroupByExpression = groupByExpression;

            var keySelector            = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
            var elementSelector        = Expression.Constant("elementSelector");
            var resultOperator         = new GroupResultOperator("itemName", keySelector, elementSelector);
            var fakeFromExpressionInfo = new FromExpressionInfo(
                new SqlTable(new ResolvedSubStatementTableInfo("sc", _sqlStatementBuilder.GetSqlStatement()), JoinSemantics.Inner), new Ordering[0], elementSelector, null);

            var originalStatement = _sqlStatementBuilder.GetSqlStatement();
            var originalDataInfo  = _sqlStatementBuilder.DataInfo;

            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(keySelector, _context))
            .Return(keySelector);
            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(elementSelector, _context))
            .Return(elementSelector);
            _stageMock
            .Expect(
                mock => mock.PrepareFromExpression(Arg <Expression> .Is.Anything, Arg.Is(_context), Arg <Func <ITableInfo, SqlTable> > .Is.Anything))
            .Return(fakeFromExpressionInfo)
            .WhenCalled(
                mi =>
            {
                var fromExpression = (Expression)mi.Arguments[0];
                CheckExpressionMovedIntoSubStatement(fromExpression, originalStatement);
            });
            _stageMock.Replay();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

            _stageMock.VerifyAllExpectations();
            Assert.That(_sqlStatementBuilder.GroupByExpression, Is.SameAs(keySelector));
            Assert.That(_sqlStatementBuilder.SqlTables.Count, Is.EqualTo(1));
            Assert.That(_sqlStatementBuilder.SqlTables[0], Is.SameAs(fakeFromExpressionInfo.SqlTable));

            Assert.That(_sqlStatementBuilder.DataInfo, Is.Not.SameAs(originalDataInfo));
            Assert.That(
                _sqlStatementBuilder.DataInfo.DataType,
                Is.EqualTo(typeof(IQueryable <>).MakeGenericType(typeof(IGrouping <,>).MakeGenericType(typeof(string), typeof(string)))));
        }
Exemplo n.º 15
0
		public static bool IsGroupingKeyOf(this MemberExpression expression,GroupResultOperator groupBy)
		{
			if (!expression.IsGroupingKey())
			{
				return false;
			}
			
			var querySource = expression.Expression as QuerySourceReferenceExpression;
			if (querySource == null) return false;
			
			var fromClause = querySource.ReferencedQuerySource as MainFromClause;
			if (fromClause == null) return false;
			
			var query = fromClause.FromExpression as SubQueryExpression;
			if (query == null) return false;
	
			return query.QueryModel.ResultOperators.Contains(groupBy);
		}
Exemplo n.º 16
0
        protected override ResultOperatorBase CreateResultOperator(ClauseGenerationContext clauseGenerationContext)
        {
            var resolvedKeySelector = GetResolvedKeySelector(clauseGenerationContext);

            var resolvedElementSelector = GetResolvedOptionalElementSelector(clauseGenerationContext);

            if (resolvedElementSelector == null)
            {
                // supply a default element selector if none is given
                // just resolve KeySelector.Parameters[0], that's the input data flowing in from the source node
                resolvedElementSelector = Source.Resolve(KeySelector.Parameters[0], KeySelector.Parameters[0], clauseGenerationContext);
            }

            var resultOperator = new GroupResultOperator(AssociatedIdentifier, resolvedKeySelector, resolvedElementSelector);

            clauseGenerationContext.AddContextInfo(this, resultOperator);
            return(resultOperator);
        }
Exemplo n.º 17
0
        public void HandleResultOperator_DetectConstantKeysAndReplaceWithSubStatement()
        {
            var keySelector     = Expression.Constant("keySelector");
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

            var preparedConstantKeySelector = Expression.Constant("test");

            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(keySelector, _context))
            .Return(preparedConstantKeySelector);
            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(elementSelector, _context))
            .Return(elementSelector);
            _stageMock.Replay();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

            _stageMock.VerifyAllExpectations();
            Assert.That(_sqlStatementBuilder.SqlTables.Count, Is.EqualTo(2));
            Assert.That(_sqlStatementBuilder.SqlTables[1], Is.TypeOf(typeof(SqlTable)));
            Assert.That(((SqlTable)_sqlStatementBuilder.SqlTables[1]).TableInfo, Is.TypeOf(typeof(ResolvedSubStatementTableInfo)));

            var groupKeyTableTableInfo   = (ResolvedSubStatementTableInfo)((SqlTable)_sqlStatementBuilder.SqlTables[1]).TableInfo;
            var expectedSelectExpression = new NamedExpression(null, preparedConstantKeySelector);

            SqlExpressionTreeComparer.CheckAreEqualTrees(expectedSelectExpression, groupKeyTableTableInfo.SqlStatement.SelectProjection);

            var expectedStatement = new SqlStatementBuilder
            {
                DataInfo         = new StreamedSequenceInfo(typeof(IEnumerable <string>), groupKeyTableTableInfo.SqlStatement.SelectProjection),
                SelectProjection = groupKeyTableTableInfo.SqlStatement.SelectProjection
            }
            .GetSqlStatement();

            Assert.That(groupKeyTableTableInfo.SqlStatement, Is.EqualTo(expectedStatement));

            var expectedGroupGyExpression = new SqlTableReferenceExpression(_sqlStatementBuilder.SqlTables[1]);

            SqlExpressionTreeComparer.CheckAreEqualTrees(_sqlStatementBuilder.GroupByExpression, expectedGroupGyExpression);
            SqlExpressionTreeComparer.CheckAreEqualTrees(
                _sqlStatementBuilder.SelectProjection,
                SqlGroupingSelectExpression.CreateWithNames(expectedGroupGyExpression, elementSelector));
        }
		public static bool IsGroupingElementOf(this QuerySourceReferenceExpression expression, GroupResultOperator groupBy)
		{
			var fromClause = expression.ReferencedQuerySource as MainFromClause;
			if (fromClause == null) return false;

			var innerQuerySource = fromClause.FromExpression as QuerySourceReferenceExpression;
			if (innerQuerySource == null) return false;

			if (innerQuerySource.ReferencedQuerySource.ItemName != groupBy.ItemName
				|| innerQuerySource.ReferencedQuerySource.ItemType != groupBy.ItemType) return false;

			var innerFromClause = innerQuerySource.ReferencedQuerySource as MainFromClause;
			if (innerFromClause == null) return false;

			var query = innerFromClause.FromExpression as SubQueryExpression;
			if (query == null) return false;

			return query.QueryModel.ResultOperators.Contains(groupBy);
		}
Exemplo n.º 19
0
        public void HandleResultOperator_TransformSubqueriesUsedAsGroupByKeys()
        {
            var keySelector     = Expression.Constant("keySelector");
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

            var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Single();
            var preparedSubStatementKeySelector = new SqlSubStatementExpression(sqlStatement);

            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(keySelector, _context))
            .Return(preparedSubStatementKeySelector);
            _stageMock
            .Expect(mock => mock.PrepareResultOperatorItemExpression(elementSelector, _context))
            .Return(elementSelector);

            _stageMock.Replay();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

            _stageMock.VerifyAllExpectations();

            Assert.That(_sqlStatementBuilder.SqlTables.Count, Is.EqualTo(2));
            Assert.That(_sqlStatementBuilder.SqlTables[1], Is.TypeOf(typeof(SqlTable)));
            Assert.That(((SqlTable)_sqlStatementBuilder.SqlTables[1]).TableInfo, Is.TypeOf(typeof(ResolvedSubStatementTableInfo)));

            var groupKeyTableTableInfo = (ResolvedSubStatementTableInfo)((SqlTable)_sqlStatementBuilder.SqlTables[1]).TableInfo;
            var expectedStatement      = new SqlStatementBuilder(sqlStatement)
            {
                DataInfo = new StreamedSequenceInfo(typeof(IEnumerable <int>), sqlStatement.SelectProjection)
            }
            .GetSqlStatement();

            Assert.That(groupKeyTableTableInfo.SqlStatement, Is.EqualTo(expectedStatement));

            var expectedGroupGyExpression = new SqlTableReferenceExpression(_sqlStatementBuilder.SqlTables[1]);

            SqlExpressionTreeComparer.CheckAreEqualTrees(_sqlStatementBuilder.GroupByExpression, expectedGroupGyExpression);
            SqlExpressionTreeComparer.CheckAreEqualTrees(
                _sqlStatementBuilder.SelectProjection,
                SqlGroupingSelectExpression.CreateWithNames(expectedGroupGyExpression, elementSelector));
        }
Exemplo n.º 20
0
        private static Expression HandleGroup(
            EntityQueryModelVisitor entityQueryModelVisitor,
            GroupResultOperator groupResultOperator,
            QueryModel queryModel)
        {
            var sequenceType
                = entityQueryModelVisitor.Expression.Type.GetSequenceType();

            var keySelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.KeySelector,
                      queryModel.MainFromClause);

            var elementSelector
                = entityQueryModelVisitor
                  .ReplaceClauseReferences(
                      groupResultOperator.ElementSelector,
                      queryModel.MainFromClause);

            var expression
                = Expression.Call(
                      entityQueryModelVisitor.LinqOperatorProvider.GroupBy
                      .MakeGenericMethod(
                          sequenceType,
                          keySelector.Type,
                          elementSelector.Type),
                      entityQueryModelVisitor.Expression,
                      Expression.Lambda(keySelector, entityQueryModelVisitor.CurrentParameter),
                      Expression.Lambda(elementSelector, entityQueryModelVisitor.CurrentParameter));

            entityQueryModelVisitor.CurrentParameter
                = Expression.Parameter(sequenceType, groupResultOperator.ItemName);

            entityQueryModelVisitor
            .AddOrUpdateMapping(groupResultOperator, entityQueryModelVisitor.CurrentParameter);

            return(expression);
        }
		private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy)
		{
			foreach (var resultOperator in queryModel.ResultOperators.Where(resultOperator => !AcceptableOuterResultOperators.Contains(resultOperator.GetType())))
			{
				throw new NotImplementedException("Cannot use group by with the " + resultOperator.GetType().Name + " result operator.");
			}

			// Move the result operator up.
			SubQueryFromClauseFlattener.InsertResultOperators(subQueryModel.ResultOperators, queryModel);

			for (var i = 0; i < queryModel.BodyClauses.Count; i++)
			{
				var clause = queryModel.BodyClauses[i];
				clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel));

				//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 subQueryModel.BodyClauses)
				queryModel.BodyClauses.Add(bodyClause);

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

			// Point all query source references to the outer from clause
			var visitor = new SwapQuerySourceVisitor(queryModel.MainFromClause, subQueryModel.MainFromClause);
			queryModel.TransformExpressions(visitor.Swap);

			// Replace the outer query source
			queryModel.MainFromClause = subQueryModel.MainFromClause;
		}
Exemplo n.º 22
0
        public void TransformExpressions()
        {
            var oldExpression1 = ExpressionHelper.CreateExpression();
            var oldExpression2 = ExpressionHelper.CreateExpression();
            var newExpression1 = ExpressionHelper.CreateExpression();
            var newExpression2 = ExpressionHelper.CreateExpression();
            var resultOperator = new GroupResultOperator("x", oldExpression1, oldExpression2);

            resultOperator.TransformExpressions(ex =>
            {
                if (ex == oldExpression1)
                {
                    return(newExpression1);
                }
                else
                {
                    Assert.That(ex, Is.SameAs(oldExpression2));
                    return(newExpression2);
                }
            });

            Assert.That(resultOperator.KeySelector, Is.SameAs(newExpression1));
            Assert.That(resultOperator.ElementSelector, Is.SameAs(newExpression2));
        }
    public void HandleResultOperator_TransformSubqueriesUsedAsGroupByKeys ()
    {
      var keySelector = Expression.Constant ("keySelector");
      var elementSelector = Expression.Constant ("elementSelector");
      var resultOperator = new GroupResultOperator ("itemName", keySelector, elementSelector);

      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Single();
      var preparedSubStatementKeySelector = new SqlSubStatementExpression (sqlStatement);
      
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (keySelector, _context))
          .Return (preparedSubStatementKeySelector);
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (elementSelector, _context))
          .Return (elementSelector);

      _stageMock.Replay ();

      _handler.HandleResultOperator (resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

      _stageMock.VerifyAllExpectations ();

      Assert.That (_sqlStatementBuilder.SqlTables.Count, Is.EqualTo (2));
      Assert.That (_sqlStatementBuilder.SqlTables[1], Is.TypeOf (typeof(SqlTable)));
      Assert.That (((SqlTable) _sqlStatementBuilder.SqlTables[1]).TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));

      var groupKeyTableTableInfo = (ResolvedSubStatementTableInfo) ((SqlTable) _sqlStatementBuilder.SqlTables[1]).TableInfo;
      var expectedStatement = new SqlStatementBuilder (sqlStatement) 
        { DataInfo = new StreamedSequenceInfo (typeof (IEnumerable<int>), sqlStatement.SelectProjection) }
        .GetSqlStatement();
      Assert.That (groupKeyTableTableInfo.SqlStatement, Is.EqualTo (expectedStatement));

      var expectedGroupGyExpression = new SqlTableReferenceExpression (_sqlStatementBuilder.SqlTables[1]);
      SqlExpressionTreeComparer.CheckAreEqualTrees (_sqlStatementBuilder.GroupByExpression, expectedGroupGyExpression);
      SqlExpressionTreeComparer.CheckAreEqualTrees (
          _sqlStatementBuilder.SelectProjection, 
          SqlGroupingSelectExpression.CreateWithNames (expectedGroupGyExpression, elementSelector));
    }
		private static void RemoveCostantGroupByKeys(QueryModel queryModel, GroupResultOperator groupBy)
		{
			var keys = groupBy.ExtractKeyExpressions().Where(x => !(x is ConstantExpression)).ToList();

			if (!keys.Any())
			{
				// Remove the Group By clause completely if all the keys are constant (redundant)
				queryModel.ResultOperators.Remove(groupBy);
			}
			else
			{
				// Re-write the KeySelector as an object array of the non-constant keys
				// This should be safe because we've already re-written the select clause using the original keys
				groupBy.KeySelector = Expression.NewArrayInit(typeof (object), keys.Select(x => x.Type.IsValueType ? Expression.Convert(x, typeof(object)) : x));
			}
		}
Exemplo n.º 25
0
		public static Expression Visit(GroupResultOperator groupBy)
		{
			return VisitInternal(groupBy.KeySelector);
		}
		public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
		{
			var visitor = new GroupBySelectClauseRewriter(groupBy, model);
			return TransparentIdentifierRemovingExpressionTreeVisitor.ReplaceTransparentIdentifiers(visitor.VisitExpression(expression));
		}
Exemplo n.º 27
0
 private GroupBySelectClauseRewriter(GroupResultOperator groupBy, QueryModel model)
 {
     _groupBy = groupBy;
     _model   = model;
 }
    public void HandleResultOperator_GroupByAfterTopExpression ()
    {
      var topExpression = Expression.Constant ("top");
      _sqlStatementBuilder.TopExpression = topExpression;

      var keySelector = new SqlColumnDefinitionExpression(typeof(string), "c", "Name", false);
      var elementSelector = Expression.Constant ("elementSelector");
      var resultOperator = new GroupResultOperator ("itemName", keySelector, elementSelector);
      
      var originalStatement = _sqlStatementBuilder.GetSqlStatement ();
      var originalDataInfo = _sqlStatementBuilder.DataInfo;

      var fakeFromExpressionInfo = new FromExpressionInfo (
          new SqlTable (new ResolvedSubStatementTableInfo("sc", originalStatement), JoinSemantics.Inner), new Ordering[0], elementSelector, null);
      
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (keySelector, _context))
          .Return (keySelector);
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (elementSelector, _context))
          .Return (elementSelector);
      _stageMock
          .Expect (
              mock => mock.PrepareFromExpression (Arg<Expression>.Is.Anything, Arg.Is (_context), Arg<Func<ITableInfo, SqlTable>>.Is.Anything))
          .Return (fakeFromExpressionInfo)
          .WhenCalled (mi =>
          {
            var fromExpression = (Expression) mi.Arguments[0];
            CheckExpressionMovedIntoSubStatement (fromExpression, originalStatement);
          });
      
      _handler.HandleResultOperator (resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

      _stageMock.VerifyAllExpectations();
      Assert.That (_sqlStatementBuilder.GroupByExpression, Is.SameAs (keySelector));
      Assert.That (_sqlStatementBuilder.SqlTables.Count, Is.EqualTo (1));
      Assert.That (_sqlStatementBuilder.SqlTables[0], Is.SameAs (fakeFromExpressionInfo.SqlTable));

      Assert.That (_sqlStatementBuilder.DataInfo, Is.Not.SameAs (originalDataInfo));
      Assert.That (
          _sqlStatementBuilder.DataInfo.DataType,
          Is.EqualTo (typeof (IQueryable<>).MakeGenericType (typeof (IGrouping<,>).MakeGenericType (typeof (string), typeof (string)))));
    }
		private GroupBySelectClauseRewriter(GroupResultOperator groupBy, QueryModel model)
		{
			_groupBy = groupBy;
			_model = model;
			_nominatedKeySelector = GroupKeyNominator.Visit(groupBy);
		}
        protected virtual void VisitGroupResultOperator(GroupResultOperator groupResultOperator, QueryModel queryModel)
        {
            _groupingExpressionTransformerRegistry = new ExpressionTransformerRegistry();

            // Add GROUP BY clause for the grouping key
            // And add transformations for any references to the key

            if (groupResultOperator.KeySelector.NodeType == ExpressionType.New)
            {
                // Grouping by a multipart key, so add each key to the GROUP BY clause

                var newExpression = (NewExpression) groupResultOperator.KeySelector;

                foreach (var argument in newExpression.Arguments)                {
                    _queryPartsAggregator.AddGroupByPart(GetN1QlExpression(argument));
                }

                // Use MultiKeyExpressionTransformer to remap access to the Key property

                _groupingExpressionTransformerRegistry.Register(
                    new MultiKeyExpressionTransfomer(_queryGenerationContext.GroupingQuerySource, newExpression));
            }
            else
            {
                // Grouping by a single column

                _queryPartsAggregator.AddGroupByPart(GetN1QlExpression(groupResultOperator.KeySelector));

                // Use KeyExpressionTransformer to remap access to the Key property

                _groupingExpressionTransformerRegistry.Register(
                    new KeyExpressionTransfomer(_queryGenerationContext.GroupingQuerySource, groupResultOperator.KeySelector));
            }

            // Add transformations for any references to the element selector

            if (groupResultOperator.ElementSelector.NodeType == QuerySourceReferenceExpression.ExpressionType)
            {
                _queryGenerationContext.ExtentNameProvider.LinkExtents(
                    ((QuerySourceReferenceExpression) groupResultOperator.ElementSelector).ReferencedQuerySource,
                    _queryGenerationContext.GroupingQuerySource.ReferencedQuerySource);
            }
            else
            {
                throw new NotSupportedException("Unsupported GroupResultOperator ElementSelector Type");
            }
        }
Exemplo n.º 31
0
 public NonAggregatingGroupBy(GroupResultOperator groupBy)
 {
     GroupBy = groupBy;
 }
Exemplo n.º 32
0
 public static IEnumerable <Expression> ExtractKeyExpressions(this GroupResultOperator groupResult)
 {
     return(groupResult.KeySelector.ExtractKeyExpressions());
 }
		private GroupBySelectClauseRewriter(GroupResultOperator groupBy, QueryModel model)
		{
			_groupBy = groupBy;
			_model = model;
		}
Exemplo n.º 34
0
        public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
        {
            var visitor = new GroupBySelectClauseRewriter(groupBy, model);

            return(TransparentIdentifierRemovingExpressionTreeVisitor.ReplaceTransparentIdentifiers(visitor.VisitExpression(expression)));
        }
Exemplo n.º 35
0
    public void TransformExpressions ()
    {
      var oldExpression1 = ExpressionHelper.CreateExpression ();
      var oldExpression2 = ExpressionHelper.CreateExpression ();
      var newExpression1 = ExpressionHelper.CreateExpression ();
      var newExpression2 = ExpressionHelper.CreateExpression ();
      var resultOperator = new GroupResultOperator ("x", oldExpression1, oldExpression2);

      resultOperator.TransformExpressions (ex =>
      {
        if (ex == oldExpression1)
          return newExpression1;
        else
        {
          Assert.That (ex, Is.SameAs (oldExpression2));
          return newExpression2;
        }
      });

      Assert.That (resultOperator.KeySelector, Is.SameAs (newExpression1));
      Assert.That (resultOperator.ElementSelector, Is.SameAs (newExpression2));
    }
        public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
        {
            resultOptionType = resultOptionType ?? queryModel.SelectClause.Selector.Type;
            if (resultOperator is CastResultOperator)
            {
                CastResultOperator castResultOperator = (CastResultOperator)resultOperator;
                Type       castType = castResultOperator.CastItemType;
                MethodInfo cast     = GetMethod("Cast", expression.Type).MakeGenericMethod(castType);
                resultOptionType = castType;
                expression       = Expression.Call(cast, expression);
                return;
            }
            if (resultOperator is AllResultOperator)
            {
                AllResultOperator   allResultOperator   = (AllResultOperator)resultOperator;
                ParameterExpression parameterExpression = Expression.Parameter(selectorType, "p");
                Expression          predicateUpdate     = UpdateExpressionVisitor.Update(allResultOperator.Predicate, new[] { parameterExpression }, dbContext, queryContext);
                Expression          allLamda            = Expression.Lambda(predicateUpdate, parameterExpression);
                MethodInfo          all = GetMethod("All", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(all, new[] { expression, allLamda });
                return;
            }
            if (resultOperator is FirstResultOperator)
            {
                FirstResultOperator firstResultOperator = (FirstResultOperator)resultOperator;
                if (firstResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo firstOrDefault = GetMethod("FirstOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(firstOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo first = GetMethod("First", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(first, new[] { expression });
                }
                return;
            }
            if (resultOperator is SingleResultOperator)
            {
                SingleResultOperator singleResultOperator = (SingleResultOperator)resultOperator;
                if (singleResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo firstOrDefault = GetMethod("SingleOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(firstOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo first = GetMethod("Single", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(first, new[] { expression });
                }
                return;
            }
            if (resultOperator is AnyResultOperator)
            {
                MethodInfo any = GetMethod("Any", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(any, new[] { expression });
                return;
            }
            if (resultOperator is TrackingResultOperator)
            {
                MethodInfo asNoTracking = typeof(EntityFrameworkQueryableExtensions).GetMethod("AsNoTracking").MakeGenericMethod(selectorType);
                expression = Expression.Call(asNoTracking, new[] { expression });
                return;
            }
            if (resultOperator is CountResultOperator)
            {
                MethodInfo count = GetMethod("Count", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(count, new[] { expression });
                return;
            }
            if (resultOperator is AverageResultOperator)
            {
                MethodInfo average = GetAgregateMethod("Average", expression.Type, selectorType);
                expression = Expression.Call(average, new[] { expression });
                return;
            }
            if (resultOperator is ContainsResultOperator)
            {
                ContainsResultOperator containsResultOperator = (ContainsResultOperator)resultOperator;
                Expression             valExp;
                object value;
                ParameterExpression paramExp = containsResultOperator.Item as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    valExp = Expression.Constant(value);
                }
                else
                {
                    valExp = containsResultOperator.Item;
                }
                if (containsResultOperator.Item is SubQueryExpression)
                {
                    SubQueryExpression subQueryExpression = (SubQueryExpression)containsResultOperator.Item;
                    QueryModelVisitor  queryModelVisitor  = new QueryModelVisitor(dbContext, queryContext);
                    queryModelVisitor.VisitQueryModel(subQueryExpression.QueryModel);
                    valExp = queryModelVisitor.expression;
                }

                MethodInfo contains = GetMethod("Contains", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(contains, new[] { expression, valExp });
                return;
            }
            if (resultOperator is DefaultIfEmptyResultOperator)
            {
                DefaultIfEmptyResultOperator defaultIfEmptyResultOperator = (DefaultIfEmptyResultOperator)resultOperator;
                MethodInfo defaultIfEmpty;
                if (defaultIfEmptyResultOperator.OptionalDefaultValue != null)
                {
                    defaultIfEmpty = GetMethod("DefaultIfEmpty", expression.Type, 1).MakeGenericMethod(selectorType);
                    expression     = Expression.Call(defaultIfEmpty, new[] { expression, defaultIfEmptyResultOperator.OptionalDefaultValue });
                }
                defaultIfEmpty = GetMethod("DefaultIfEmpty", expression.Type).MakeGenericMethod(selectorType);
                expression     = Expression.Call(defaultIfEmpty, expression);
                return;
            }
            if (resultOperator is DistinctResultOperator)
            {
                MethodInfo distinct = GetMethod("Distinct", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(distinct, expression);
                return;
            }
            if (resultOperator is GroupResultOperator)
            {
                GroupResultOperator groupResultOperator = (GroupResultOperator)resultOperator;
                Type keySelectorType = GetTypeParameter(groupResultOperator.KeySelector);
                ParameterExpression keyExpressionParam  = Expression.Parameter(keySelectorType, "p");
                Expression          keyExpression       = UpdateExpressionVisitor.Update(groupResultOperator.KeySelector, new[] { keyExpressionParam }, dbContext, queryContext);
                LambdaExpression    keyLambdaExpression = Expression.Lambda(keyExpression, keyExpressionParam);
                Type elementSelectorType = GetTypeParameter(groupResultOperator.ElementSelector);
                ParameterExpression ElementExpressionParam  = Expression.Parameter(elementSelectorType, "p");
                Expression          ElementExpression       = UpdateExpressionVisitor.Update(groupResultOperator.ElementSelector, new[] { ElementExpressionParam }, dbContext, queryContext);
                LambdaExpression    ElementLambdaExpression = Expression.Lambda(ElementExpression, ElementExpressionParam);
                Type       tSource  = queryModel.MainFromClause.ItemType;
                Type       tKey     = keyExpression.Type;
                Type       tElement = ElementExpression.Type;
                Type       tResult  = queryModel.ResultTypeOverride;
                MethodInfo groupBy  = GetMethods("GroupBy", expression.Type, 2).Where(p => p.GetParameters()[2].Name == "elementSelector").Single().
                                      MakeGenericMethod(tSource, tKey, tElement);
                expression = Expression.Call(groupBy, new[] { expression, keyLambdaExpression, ElementLambdaExpression });
                return;
            }
            if (resultOperator is LastResultOperator)
            {
                LastResultOperator lastResultOperator = (LastResultOperator)resultOperator;
                if (lastResultOperator.ReturnDefaultWhenEmpty)
                {
                    MethodInfo lastOrDefault = GetMethod("LastOrDefault", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(lastOrDefault, new[] { expression });
                }
                else
                {
                    MethodInfo last = GetMethod("Last", expression.Type, 0).MakeGenericMethod(selectorType);
                    expression = Expression.Call(last, new[] { expression });
                }
                return;
            }
            if (resultOperator is LongCountResultOperator)
            {
                MethodInfo longCount = GetMethod("LongCount", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(longCount, new[] { expression });
                return;
            }
            if (resultOperator is MaxResultOperator)
            {
                MethodInfo max = GetMethod("Max", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(max, expression);
                return;
            }
            if (resultOperator is MinResultOperator)
            {
                MethodInfo min = GetMethod("Min", expression.Type).MakeGenericMethod(selectorType);
                expression = Expression.Call(min, expression);
                return;
            }
            if (resultOperator is SumResultOperator)
            {
                MethodInfo sum = GetAgregateMethod("Sum", expression.Type, selectorType);
                expression = Expression.Call(sum, expression);
                return;
            }
            if (resultOperator is SkipResultOperator)
            {
                SkipResultOperator  skipResultOperator = (SkipResultOperator)resultOperator;
                Expression          expVal;
                object              value;
                ParameterExpression paramExp = skipResultOperator.Count as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    expVal = Expression.Constant(value);
                }
                else
                {
                    expVal = skipResultOperator.Count;
                }
                MethodInfo skip = GetMethod("Skip", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(skip, new[] { expression, expVal });
                return;
            }
            if (resultOperator is TakeResultOperator)
            {
                TakeResultOperator  takeResultOperator = (TakeResultOperator)resultOperator;
                Expression          expVal;
                object              value;
                ParameterExpression paramExp = takeResultOperator.Count as ParameterExpression;
                if (paramExp != null &&
                    queryContext.ParameterValues.TryGetValue(paramExp.Name, out value))
                {
                    expVal = Expression.Constant(value);
                }
                else
                {
                    expVal = takeResultOperator.Count;
                }
                MethodInfo take = GetMethod("Take", expression.Type, 1).MakeGenericMethod(selectorType);
                expression = Expression.Call(take, new[] { expression, expVal });
                return;
            }
            if (resultOperator is IncludeResultOperator)
            {
                IncludeResultOperator includeResultOperator = (IncludeResultOperator)resultOperator;
                Expression            includeExpression     = includeResultOperator.NavigationPropertyPath;
                Type paramExpressionType = null;
                ParameterExpression parameterExpression = null;
                if (includeExpression is MemberExpression)
                {
                    MemberExpression memberExpression = (MemberExpression)includeExpression;
                    paramExpressionType = memberExpression.Expression.Type;
                    parameterExpression = Expression.Parameter(paramExpressionType, "p");
                    includeExpression   = Expression.Property(parameterExpression, memberExpression.Member.Name);
                }
                else
                {
                    paramExpressionType = GetTypeParameter(includeExpression);
                    parameterExpression = Expression.Parameter(paramExpressionType, "p");
                }
                Expression       updateOuterExpression   = UpdateExpressionVisitor.Update(includeExpression, new[] { parameterExpression }, dbContext, queryContext);
                LambdaExpression lambdaIncludeExpression = Expression.Lambda(updateOuterExpression, parameterExpression);
                MethodInfo       include = typeof(EntityFrameworkQueryableExtensions).GetMethods().First(m => m.Name == "Include").MakeGenericMethod(selectorType, updateOuterExpression.Type);
                expression = Expression.Call(include, new[] { expression, lambdaIncludeExpression });

                if (includeResultOperator.ChainedNavigationProperties != null)
                {
                    foreach (PropertyInfo propertyInfo in includeResultOperator.ChainedNavigationProperties)
                    {
                        Type       propertyType = propertyInfo.PropertyType;
                        Type       argument     = expression.Type.GetGenericArguments().Last();
                        MethodInfo thenInclude;
                        Type       realType;
                        if (typeof(IEnumerable).IsAssignableFrom(argument))
                        {
                            realType    = argument.GetGenericArguments().First();
                            thenInclude = ThenIncludeCollection.MakeGenericMethod(includeResultOperator.QuerySource.ItemType, realType, propertyType);
                        }
                        else
                        {
                            realType    = argument;
                            thenInclude = ThenIncludeProperty.MakeGenericMethod(includeResultOperator.QuerySource.ItemType, realType, propertyType);
                        }
                        ParameterExpression parameterThenIncludeExpression = Expression.Parameter(realType, "p");
                        MemberExpression    property = Expression.Property(parameterThenIncludeExpression, propertyInfo);
                        LambdaExpression    lambdaThenIncludeExpression = Expression.Lambda(property, parameterThenIncludeExpression);
                        expression = Expression.Call(thenInclude, new[] { expression, lambdaThenIncludeExpression });
                    }
                }
                return;
            }
            if (resultOperator is OfTypeResultOperator)
            {
                OfTypeResultOperator ofTypeResultOperator = (OfTypeResultOperator)resultOperator;
                selectorType = ofTypeResultOperator.SearchedItemType;
                var miOfType = GetMethod("OfType", expression.Type).MakeGenericMethod(ofTypeResultOperator.SearchedItemType);
                expression = Expression.Call(miOfType, new[] { expression });
                return;
            }
            throw new NotSupportedException();
        }
        private static Expression HandleGroup(
            EntityQueryModelVisitor entityQueryModelVisitor,
            GroupResultOperator groupResultOperator,
            QueryModel queryModel)
        {
            var keySelector
                = entityQueryModelVisitor
                    .ReplaceClauseReferences(
                        groupResultOperator.KeySelector,
                        queryModel.MainFromClause);

            var elementSelector
                = entityQueryModelVisitor
                    .ReplaceClauseReferences(
                        groupResultOperator.ElementSelector,
                        queryModel.MainFromClause);

            return Expression.Call(
                entityQueryModelVisitor.LinqOperatorProvider.GroupBy
                    .MakeGenericMethod(
                        typeof(QuerySourceScope),
                        groupResultOperator.KeySelector.Type,
                        groupResultOperator.ElementSelector.Type),
                entityQueryModelVisitor.CreateScope(
                    entityQueryModelVisitor.Expression,
                    entityQueryModelVisitor.StreamedSequenceInfo.ResultItemType,
                    queryModel.MainFromClause),
                Expression.Lambda(keySelector, EntityQueryModelVisitor.QuerySourceScopeParameter),
                Expression.Lambda(elementSelector, EntityQueryModelVisitor.QuerySourceScopeParameter));
        }
		public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
		{
			var visitor = new GroupBySelectClauseRewriter(groupBy, model);
			return visitor.VisitExpression(expression);
		}
Exemplo n.º 39
0
		private void ProcessGroupByOperator(GroupResultOperator resultOperator)
		{
			var visitor = new HqlGeneratorExpressionTreeVisitor(_parameterAggregator);
			visitor.Visit(resultOperator.KeySelector);
			_groupByClause = _hqlTreeBuilder.GroupBy();
			_groupByClause.AddChild(visitor.GetHqlTreeNodes().Single());
		}
Exemplo n.º 40
0
        internal static bool TryGetGroupResultOperator(this MemberExpression keyExpression, out GroupResultOperator groupBy)
        {
            if (keyExpression.IsGroupingKey() &&
                keyExpression.Expression is QuerySourceReferenceExpression querySource &&
                querySource.ReferencedQuerySource is MainFromClause fromClause &&
                fromClause.FromExpression is SubQueryExpression query)
            {
                groupBy = query.QueryModel.ResultOperators
                          .OfType <GroupResultOperator>()
                          .FirstOrDefault(o => o.KeySelector.Type == keyExpression.Type);
                return(groupBy != null);
            }

            groupBy = null;
            return(false);
        }
    public void HandleResultOperator_DetectConstantKeysAndReplaceWithSubStatement ()
    {
      var keySelector = Expression.Constant ("keySelector");
      var elementSelector = Expression.Constant ("elementSelector");
      var resultOperator = new GroupResultOperator ("itemName", keySelector, elementSelector);
      
      var preparedConstantKeySelector = Expression.Constant ("test");

      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (keySelector, _context))
          .Return (preparedConstantKeySelector);
      _stageMock
          .Expect (mock => mock.PrepareResultOperatorItemExpression (elementSelector, _context))
          .Return (elementSelector);
      _stageMock.Replay ();

      _handler.HandleResultOperator (resultOperator, _sqlStatementBuilder, _generator, _stageMock, _context);

      _stageMock.VerifyAllExpectations ();
      Assert.That (_sqlStatementBuilder.SqlTables.Count, Is.EqualTo (2));
      Assert.That (_sqlStatementBuilder.SqlTables[1], Is.TypeOf (typeof (SqlTable)));
      Assert.That (((SqlTable) _sqlStatementBuilder.SqlTables[1]).TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      
      var groupKeyTableTableInfo = (ResolvedSubStatementTableInfo) ((SqlTable) _sqlStatementBuilder.SqlTables[1]).TableInfo;
      var expectedSelectExpression = new NamedExpression (null, preparedConstantKeySelector);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedSelectExpression, groupKeyTableTableInfo.SqlStatement.SelectProjection);
      
      var expectedStatement = new SqlStatementBuilder 
        {
          DataInfo = new StreamedSequenceInfo (typeof (IEnumerable<string>), groupKeyTableTableInfo.SqlStatement.SelectProjection),
          SelectProjection = groupKeyTableTableInfo.SqlStatement.SelectProjection
        }
        .GetSqlStatement ();
      Assert.That (groupKeyTableTableInfo.SqlStatement, Is.EqualTo (expectedStatement));

      var expectedGroupGyExpression = new SqlTableReferenceExpression (_sqlStatementBuilder.SqlTables[1]);
      SqlExpressionTreeComparer.CheckAreEqualTrees (_sqlStatementBuilder.GroupByExpression, expectedGroupGyExpression);
      SqlExpressionTreeComparer.CheckAreEqualTrees (
          _sqlStatementBuilder.SelectProjection,
          SqlGroupingSelectExpression.CreateWithNames (expectedGroupGyExpression, elementSelector));
    }
		public NonAggregatingGroupBy(GroupResultOperator groupBy)
		{
			GroupBy = groupBy;
		}
Exemplo n.º 43
0
        public static bool IsGroupingElementOf(this QuerySourceReferenceExpression expression, GroupResultOperator groupBy)
        {
            var fromClause = expression.ReferencedQuerySource as MainFromClause;

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

            var innerQuerySource = fromClause.FromExpression as QuerySourceReferenceExpression;

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

            if (innerQuerySource.ReferencedQuerySource.ItemName != groupBy.ItemName ||
                innerQuerySource.ReferencedQuerySource.ItemType != groupBy.ItemType)
            {
                return(false);
            }

            var innerFromClause = innerQuerySource.ReferencedQuerySource as MainFromClause;

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

            var query = innerFromClause.FromExpression as SubQueryExpression;

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

            return(query.QueryModel.ResultOperators.Contains(groupBy));
        }
Exemplo n.º 44
0
        public static Expression ReWrite(Expression expression, GroupResultOperator groupBy, QueryModel model)
        {
            var visitor = new GroupBySelectClauseRewriter(groupBy, model);

            return(visitor.VisitExpression(expression));
        }
        private static Expression HandleGroup(
            EntityQueryModelVisitor entityQueryModelVisitor,
            GroupResultOperator groupResultOperator,
            QueryModel queryModel)
        {
            var keySelector
                = entityQueryModelVisitor
                    .ReplaceClauseReferences(
                        groupResultOperator.KeySelector,
                        queryModel.MainFromClause);

            var elementSelector
                = entityQueryModelVisitor
                    .ReplaceClauseReferences(
                        groupResultOperator.ElementSelector,
                        queryModel.MainFromClause);

            var expression
                = Expression.Call(
                    entityQueryModelVisitor.LinqOperatorProvider.GroupBy
                        .MakeGenericMethod(
                            entityQueryModelVisitor.Expression.Type.GetSequenceType(),
                            keySelector.Type,
                            elementSelector.Type),
                    entityQueryModelVisitor.Expression,
                    Expression.Lambda(keySelector, entityQueryModelVisitor.CurrentParameter),
                    Expression.Lambda(elementSelector, entityQueryModelVisitor.CurrentParameter));

            entityQueryModelVisitor.CurrentParameter
                = Expression.Parameter(expression.Type.GetSequenceType(), groupResultOperator.ItemName);

            entityQueryModelVisitor
                .AddOrUpdateMapping(groupResultOperator, entityQueryModelVisitor.CurrentParameter);

            return expression;
        }
Exemplo n.º 46
0
 public KeySelectorVisitor(GroupResultOperator groupBy)
 {
     _groupBy = groupBy;
 }
Exemplo n.º 47
0
    protected override ResultOperatorBase CreateResultOperator (ClauseGenerationContext clauseGenerationContext)
    {
      var resolvedKeySelector = GetResolvedKeySelector (clauseGenerationContext);

      var resolvedElementSelector = GetResolvedOptionalElementSelector (clauseGenerationContext);
      if (resolvedElementSelector == null)
      {
        // supply a default element selector if none is given
        // just resolve KeySelector.Parameters[0], that's the input data flowing in from the source node
        resolvedElementSelector = Source.Resolve (_keySelector.Parameters[0], _keySelector.Parameters[0], clauseGenerationContext);
      }
      
      var resultOperator = new GroupResultOperator (AssociatedIdentifier, resolvedKeySelector, resolvedElementSelector);
      clauseGenerationContext.AddContextInfo (this, resultOperator);
      return resultOperator;
    }
Exemplo n.º 48
0
 public static Expression Visit(GroupResultOperator groupBy)
 {
     return(VisitInternal(groupBy.KeySelector));
 }
Exemplo n.º 49
0
 private GroupBySelectClauseRewriter(GroupResultOperator groupBy, QueryModel model)
 {
     _groupBy = groupBy;
     _model   = model;
     _nominatedKeySelector = GroupKeyNominator.Visit(groupBy);
 }
Exemplo n.º 50
0
        private static void FlattenSubQuery(QueryModel queryModel, QueryModel subQueryModel, GroupResultOperator groupBy)
        {
            foreach (var resultOperator in queryModel.ResultOperators.Where(resultOperator => !AcceptableOuterResultOperators.Contains(resultOperator.GetType())))
            {
                throw new NotImplementedException("Cannot use group by with the " + resultOperator.GetType().Name + " result operator.");
            }

            // Move the result operator up.
            SubQueryFromClauseFlattener.InsertResultOperators(subQueryModel.ResultOperators, queryModel);

            for (var i = 0; i < queryModel.BodyClauses.Count; i++)
            {
                var clause = queryModel.BodyClauses[i];
                clause.TransformExpressions(s => GroupBySelectClauseRewriter.ReWrite(s, groupBy, subQueryModel));

                //all outer where clauses actually are having clauses
                var whereClause = clause as WhereClause;
                if (whereClause != null)
                {
                    queryModel.BodyClauses[i] = new NhHavingClause(whereClause.Predicate);
                }
            }

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

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

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

            queryModel.TransformExpressions(visitor.Swap);

            // Replace the outer query source
            queryModel.MainFromClause = subQueryModel.MainFromClause;
        }
Exemplo n.º 51
0
		public KeySelectorVisitor(GroupResultOperator groupBy)
		{
			_groupBy = groupBy;
		}