SqlSubStatementExpression represents a SQL database subquery. The QueryModel of the subquery is translated to this model, and the SqlSubStatementExpression is transformed several times until it can easily be translated to SQL text.
Inheritance: Remotion.Linq.Clauses.Expressions.ExtensionExpression
    public void To_String ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook));
      var expression = new SqlSubStatementExpression (sqlStatement);

      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("(SELECT [t0] FROM [Table] [t])"));
    }
    public void PrepareSelectExpression ()
    {
      var singleDataInfo = new StreamedSingleValueInfo (typeof (int), false);
      var selectProjection = Expression.Constant (0);
      var subStatement = new SqlStatement (singleDataInfo, selectProjection, new SqlTable[0], null, null, new Ordering[0], null, false, null, null);
      var expressionWithSubStatement = new SqlSubStatementExpression (subStatement);

      var result = _stage.PrepareSelectExpression (expressionWithSubStatement, _context);

      Assert.That (result, Is.SameAs(expressionWithSubStatement));
    }
    public void VisitSqlSubStatementExpression_LeavesSqlSubStatementExpression_ForStreamedScalarInfo ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Scalar();
      var expression = new SqlSubStatementExpression (sqlStatement);

      _stageMock
          .Expect (mock => mock.ResolveSqlStatement (sqlStatement, _mappingResolutionContext))
          .Return (sqlStatement);
      _groupAggregateSimplifier
          .Expect (mock => mock.SimplifyIfPossible (expression, sqlStatement.SelectProjection))
          .Return (expression);

      var visitor = CreateVisitor (new SqlStatementBuilder (sqlStatement));
      var result = visitor.VisitExpression (expression);

      _stageMock.VerifyAllExpectations();
      _groupAggregateSimplifier.VerifyAllExpectations ();
      Assert.That (result, Is.TypeOf (typeof (SqlSubStatementExpression)));
      Assert.That (((SqlSubStatementExpression) result).SqlStatement, Is.SameAs (sqlStatement));
    }
    public Expression SimplifyIfPossible (
        SqlSubStatementExpression subStatementExpression,
        Expression unresolvedSelectProjection)
    {
      ArgumentUtility.CheckNotNull ("subStatementExpression", subStatementExpression);
      ArgumentUtility.CheckNotNull ("unresolvedSelectProjection", unresolvedSelectProjection);

      var resolvedSqlStatement = subStatementExpression.SqlStatement;
      if (IsSimplifiableGroupAggregate (resolvedSqlStatement))
      {
        var joinedGroupingTableInfo = (ResolvedJoinedGroupingTableInfo) resolvedSqlStatement.SqlTables[0].GetResolvedTableInfo ();

        // Strip surrounding names so that there won't be a named expression inside the new aggregation
        var elementExpression = _context.RemoveNamesAndUpdateMapping (joinedGroupingTableInfo.AssociatedGroupingSelectExpression.ElementExpression);
        var visitor = new SimplifyingVisitor (resolvedSqlStatement.SqlTables[0], elementExpression);

        var aggregationExpression = FindAggregationExpression (unresolvedSelectProjection);
        if (aggregationExpression == null)
        {
          throw new ArgumentException (
              "The unresolved projection doesn't match the resolved statement: it has no aggregation.",
              "unresolvedSelectProjection");
        }
        var newAggregation = visitor.VisitExpression (aggregationExpression);

        if (visitor.CanBeTransferredToGroupingSource)
        {
          var resolvedNewAggregation = _stage.ResolveAggregationExpression (newAggregation, _context);

          var aggregationName = joinedGroupingTableInfo.AssociatedGroupingSelectExpression.AddAggregationExpressionWithName (resolvedNewAggregation);

          return new SqlColumnDefinitionExpression (
              resolvedSqlStatement.SelectProjection.Type,
              joinedGroupingTableInfo.GroupSourceTableAlias,
              aggregationName,
              false);
        }
      }

      return subStatementExpression;
    }
    public void ConvertToSqlTable_StreamedSingleValueInfo_NoSqlTables ()
    {
      var selectProjection = Expression.Constant (new Cook ());
      var topExpression = new SqlLiteralExpression (2);
      var sqlStatement =
          new SqlStatementBuilder
          {
            DataInfo = new StreamedSingleValueInfo (typeof (Cook), false),
            SelectProjection = selectProjection,
            TopExpression = topExpression
          }.GetSqlStatement ();
      var expression = new SqlSubStatementExpression (sqlStatement);

      var result = expression.ConvertToSqlTable ("q0");

      Assert.That (result.JoinSemantics, Is.EqualTo (JoinSemantics.Inner));
      Assert.That (result.TableInfo.GetResolvedTableInfo ().TableAlias, Is.EqualTo ("q0"));
      Assert.That (result.TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));

      var newSubStatement = ((ResolvedSubStatementTableInfo) result.TableInfo).SqlStatement;
      Assert.That (newSubStatement.TopExpression, Is.SameAs (topExpression));
    }
    public void VisitQuerySourceReferenceExpression_WithExtractedOrderings ()
    {
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook));
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (sqlTable);
      var selectProjection = new NamedExpression("test", Expression.MakeMemberAccess (sqlTableReferenceExpression, typeof (Cook).GetProperty ("Name")));
      var orderingExpression = Expression.MakeMemberAccess (sqlTableReferenceExpression, typeof (Cook).GetProperty ("ID"));
      var sqlStatement = new SqlStatementBuilder
                         {
                             DataInfo = new StreamedSequenceInfo(typeof (DateTime[]), Expression.Constant (new DateTime (2000, 1, 1))),
                             SelectProjection = selectProjection,
                             SqlTables = { sqlTable },
                             Orderings =
                                 { new Ordering (orderingExpression, OrderingDirection.Asc) }
                         }.GetSqlStatement();
      var fakeSelectExpression = Expression.Constant (new KeyValuePair<string, int>("test", 5));
      var fakeWhereExpression = Expression.Constant (true);

      var innerSequenceExpression = new SqlSubStatementExpression (sqlStatement);
          
      var joinClause = new JoinClause (
          "x",
          typeof (Cook[]),
          innerSequenceExpression,
          Expression.Constant (new Cook ()),
          Expression.Constant (new Cook ()));
      var groupJoinClause = new GroupJoinClause ("g", typeof (Cook[]), joinClause);
      var querySourceReferenceExpression = new QuerySourceReferenceExpression (groupJoinClause);

      _stageMock
          .Expect (mock => mock.PrepareSelectExpression(Arg<Expression>.Is.Anything, Arg<ISqlPreparationContext>.Is.Anything))
          .Return (fakeSelectExpression);
      _stageMock
          .Expect (mock => mock.PrepareWhereExpression (Arg<Expression>.Matches (e => e is BinaryExpression), Arg.Is (_context)))
          .WhenCalled (
              mi =>
              SqlExpressionTreeComparer.CheckAreEqualTrees (
                  Expression.Equal (groupJoinClause.JoinClause.OuterKeySelector, groupJoinClause.JoinClause.InnerKeySelector),
                  (Expression) mi.Arguments[0]))
          .Return (fakeWhereExpression);
      _stageMock.Replay ();

      _visitor.VisitQuerySourceReferenceExpression (querySourceReferenceExpression);

      _stageMock.VerifyAllExpectations ();

      Assert.That (_visitor.FromExpressionInfo != null); // inline condition because of ReSharper
      var fromExpressionInfo = (FromExpressionInfo) _visitor.FromExpressionInfo;

      Assert.That (fromExpressionInfo.ExtractedOrderings.Count, Is.EqualTo(1));
      Assert.That (fromExpressionInfo.ExtractedOrderings[0].Expression, Is.AssignableTo(typeof(MemberExpression)));
      Assert.That (((MemberExpression) fromExpressionInfo.ExtractedOrderings[0].Expression).Expression, Is.TypeOf(typeof(SqlTableReferenceExpression)));
      Assert.That (
          ((SqlTableReferenceExpression) ((MemberExpression) fromExpressionInfo.ExtractedOrderings[0].Expression).Expression).SqlTable, Is.TypeOf (typeof (SqlTable)));
      Assert.That (
          ((SqlTable) ((SqlTableReferenceExpression) ((MemberExpression) fromExpressionInfo.ExtractedOrderings[0].Expression).Expression).SqlTable).TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      var resolvedSubStatementtableInfo =
         (ResolvedSubStatementTableInfo) ((SqlTable) ((SqlTableReferenceExpression) ((MemberExpression) fromExpressionInfo.ExtractedOrderings[0].Expression).Expression).SqlTable).TableInfo;
      Assert.That (resolvedSubStatementtableInfo.SqlStatement.SelectProjection, Is.SameAs(fakeSelectExpression));
      Assert.That (resolvedSubStatementtableInfo.SqlStatement.Orderings.Count, Is.EqualTo (0));
      Assert.That (((MemberExpression) fromExpressionInfo.ExtractedOrderings[0].Expression).Member, Is.EqualTo(typeof(KeyValuePair<,>).MakeGenericType(typeof(string), typeof(int)).GetProperty("Value")));
      Assert.That (fromExpressionInfo.ItemSelector, Is.AssignableTo (typeof (MemberExpression)));
      Assert.That (((MemberExpression) fromExpressionInfo.ItemSelector).Expression, Is.TypeOf(typeof(SqlTableReferenceExpression)));
      Assert.That (((SqlTableReferenceExpression) ((MemberExpression) fromExpressionInfo.ItemSelector).Expression).SqlTable, Is.TypeOf (typeof (SqlTable)));
      Assert.That (
          ((SqlTable) ((SqlTableReferenceExpression) ((MemberExpression) fromExpressionInfo.ItemSelector).Expression).SqlTable).TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      Assert.That (((MemberExpression) fromExpressionInfo.ItemSelector).Member, Is.EqualTo (typeof (KeyValuePair<,>).MakeGenericType (typeof (string), typeof (int)).GetProperty ("Key")));
    }
    public void ConvertToSqlTable_StreamedSequenceInfo ()
    {
      var selectProjection = Expression.Constant (new Cook ());
      var sqlStatement =
          new SqlStatementBuilder { DataInfo = new StreamedSequenceInfo(typeof (Cook[]), Expression.Constant(new Cook())), SelectProjection = selectProjection }.
              GetSqlStatement ();
      var expression = new SqlSubStatementExpression (sqlStatement);

      var result = expression.ConvertToSqlTable ("q0");

      Assert.That (result.JoinSemantics, Is.EqualTo (JoinSemantics.Inner));
      Assert.That (result.TableInfo.GetResolvedTableInfo ().TableAlias, Is.EqualTo ("q0"));
      Assert.That (result.TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      Assert.That (((ResolvedSubStatementTableInfo) result.TableInfo).SqlStatement, Is.EqualTo(sqlStatement));
    }
    public virtual Expression VisitSqlSubStatementExpression (SqlSubStatementExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var resolvedSqlStatement = _stage.ResolveSqlStatement (expression.SqlStatement, _context);
      var resolvedExpression = Equals (resolvedSqlStatement, expression.SqlStatement)
                                   ? expression
                                   : new SqlSubStatementExpression (resolvedSqlStatement);

      return _groupAggregateSimplifier.SimplifyIfPossible (resolvedExpression, expression.SqlStatement.SelectProjection);
    }
    public void SimplifyIfPossible_NonSimplifiableStatement ()
    {
      var resolvedSqlStatement = new SqlStatementBuilder (_simplifiableResolvedSqlStatement)
      {
        IsDistinctQuery = true
      }.GetSqlStatement ();
      var expression = new SqlSubStatementExpression (resolvedSqlStatement);
      
      _stageMock.Replay();

      var result = _groupAggregateSimplifier.SimplifyIfPossible (expression, _simplifiableUnresolvedProjection);

      _stageMock.VerifyAllExpectations();

      Assert.That (result, Is.SameAs (expression));
    }
    public void VisitSqlSubStatementExpression ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook));
      var subStatementExpression = new SqlSubStatementExpression (sqlStatement);

      _stageMock
          .Expect (
              mock =>
              mock.GenerateTextForSqlStatement (_commandBuilder, sqlStatement))
          .WhenCalled (mi => ((SqlCommandBuilder) mi.Arguments[0]).Append ("SELECT [t].[Name] FROM [Table] AS [t]"));
      _stageMock.Replay();

      SqlGeneratingExpressionVisitor.GenerateSql (subStatementExpression, _commandBuilder, _stageMock);

      Assert.That (_commandBuilder.GetCommandText(), Is.EqualTo ("(SELECT [t].[Name] FROM [Table] AS [t])"));
      _stageMock.VerifyAllExpectations();
    }
    public virtual Expression VisitSqlSubStatementExpression (SqlSubStatementExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      if (expression.SqlStatement.Orderings.Count > 0 && expression.SqlStatement.TopExpression == null)
      {
        var builder = new SqlStatementBuilder (expression.SqlStatement);
        builder.Orderings.Clear();
        return new SqlSubStatementExpression (builder.GetSqlStatement());
      }
      return expression;
    }
    public void ResolvePotentialEntity_Substatement_StripsConversions ()
    {
      var subStatement = SqlStatementModelObjectMother.CreateSqlStatement (Expression.Convert (_entityExpression, typeof (object)), SqlStatementModelObjectMother.CreateSqlTable ());
      var subStatementExpression = new SqlSubStatementExpression (subStatement);

      var result = _entityIdentityResolver.ResolvePotentialEntity (Expression.Convert (subStatementExpression, typeof (object)));

      Assert.That (result, Is.TypeOf<SqlSubStatementExpression> ());
      var expectedSelectProjection = _entityExpression.GetIdentityExpression ();
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedSelectProjection, ((SqlSubStatementExpression) result).SqlStatement.SelectProjection);
      Assert.That (((SqlSubStatementExpression) result).SqlStatement.DataInfo.DataType, Is.SameAs (typeof (IQueryable<int>)));
    }
    public void VisitSqlSubStatementExpression_NoChanges ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement();
      var expression = new SqlSubStatementExpression (sqlStatement);

      _stageMock
          .Expect (mock => mock.ResolveSqlStatement (sqlStatement, _mappingResolutionContext))
          .Return (sqlStatement);
      _groupAggregateSimplifierMock
          .Expect (mock => mock.SimplifyIfPossible (expression, expression.SqlStatement.SelectProjection))
          .Return (expression);

      var result = _visitor.VisitExpression (expression);

      _stageMock.VerifyAllExpectations ();
      _groupAggregateSimplifierMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (expression));
    }
    public void ResolvePotentialEntity_Substatement_WithEntity_TrivialProjection_ResolvesToIdentityDirectly ()
    {
      // No SQL tables => the substatement can be completely eliminated.
      var subStatement = SqlStatementModelObjectMother.CreateSqlStatement (_entityExpression);
      var subStatementExpression = new SqlSubStatementExpression (subStatement);

      var result = _entityIdentityResolver.ResolvePotentialEntity (subStatementExpression);

      var expectedSelectProjection = _entityExpression.GetIdentityExpression ();
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedSelectProjection, result);
    }
    public void ResolvePotentialEntity_Substatement_WithoutEntity_ReturnsSameExpression ()
    {
      var subStatement = SqlStatementModelObjectMother.CreateSqlStatement (Expression.Constant (0));
      var subStatementExpression = new SqlSubStatementExpression (subStatement);

      var result = _entityIdentityResolver.ResolvePotentialEntity (subStatementExpression);

      Assert.That (result, Is.SameAs (subStatementExpression));
    }
    public void SimplifyIfPossible_WithUnresolvedProjection_NotMatchingResolvedOned_NoAggregation ()
    {
      var expression = new SqlSubStatementExpression (_simplifiableResolvedSqlStatement);

      var nonSimplifiableProjection = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable ());
      _groupAggregateSimplifier.SimplifyIfPossible (expression, nonSimplifiableProjection);
    }
    public void SimplifyIfPossible_WithNonSimplifiableProjection_ReturnsOriginalStatement ()
    {
      Assert.That (_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo (0));
      var expression = new SqlSubStatementExpression (_simplifiableResolvedSqlStatement);

      _stageMock.Replay ();

      var nonSimplifiableProjection = new AggregationExpression (
          typeof (int), 
          new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable ()), AggregationModifier.Count);
      var result = _groupAggregateSimplifier.SimplifyIfPossible (expression, nonSimplifiableProjection);

      _stageMock.VerifyAllExpectations ();

      var expected = new SqlSubStatementExpression (_simplifiableResolvedSqlStatement);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expected, result);

      Assert.That (_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo (0));
    }
    public void SimplifyIfPossible_SimplifiableStatement_AddsAggregationAndReturnsReference ()
    {
      Assert.That (_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo (0));

      var expression = new SqlSubStatementExpression (_simplifiableResolvedSqlStatement);

      var preparedResolvedAggregate = new AggregationExpression (
          typeof (int), 
          new NamedExpression ("element", Expression.Constant ("e")), 
          AggregationModifier.Count);
      _stageMock
          .Expect (mock => mock.ResolveAggregationExpression(Arg<Expression>.Is.Anything, Arg.Is (_context)))
          .Return (preparedResolvedAggregate)
          .WhenCalled (mi => {
            var expectedReplacedAggregate = new AggregationExpression (
                typeof (int),
                ((NamedExpression) _associatedGroupingSelectExpression.ElementExpression).Expression, 
                AggregationModifier.Count);
            SqlExpressionTreeComparer.CheckAreEqualTrees (expectedReplacedAggregate, (Expression) mi.Arguments[0]);
          });
      _stageMock.Replay();

      var result = _groupAggregateSimplifier.SimplifyIfPossible (expression, _simplifiableUnresolvedProjection);

      _stageMock.VerifyAllExpectations();

      Assert.That (_associatedGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo (1));
      Assert.That (
          ((NamedExpression) _associatedGroupingSelectExpression.AggregationExpressions[0]).Expression, 
          Is.SameAs (preparedResolvedAggregate));

      var expected = new SqlColumnDefinitionExpression (typeof (int), "q0", "a0", false);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expected, result);
    }
    public void ConvertToSqlTable_StreamedSingleValueInfoWithReturnsTrueIfEmpty_JoinSemanticIsChanged ()
    {
      var selectProjection = Expression.Constant (new Cook ());
      var sqlStatement =
          new SqlStatementBuilder
          {
            DataInfo = new StreamedSingleValueInfo (typeof (Cook), true),
            SelectProjection = selectProjection,
            TopExpression = new SqlLiteralExpression (2),
            SqlTables = { new SqlTable (new ResolvedSimpleTableInfo (typeof (Cook), "CookTable", "c"), JoinSemantics.Inner) }
          }.GetSqlStatement ();
      var expression = new SqlSubStatementExpression (sqlStatement);

      var result = expression.ConvertToSqlTable ("q0");

      Assert.That (result.JoinSemantics, Is.EqualTo (JoinSemantics.Left));
      Assert.That (result.TableInfo.GetResolvedTableInfo ().TableAlias, Is.EqualTo ("q0"));
      Assert.That (result.TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));

      var newSubStatement = ((ResolvedSubStatementTableInfo) result.TableInfo).SqlStatement;
      var expectedSubStatement = new SqlStatementBuilder (sqlStatement)
      {
        DataInfo = new StreamedSequenceInfo (typeof (IEnumerable<Cook>), sqlStatement.SelectProjection),
        TopExpression = newSubStatement.TopExpression
      }.GetSqlStatement ();

      SqlExpressionTreeComparer.CheckAreEqualTrees (new SqlLiteralExpression (1), newSubStatement.TopExpression);
      Assert.That (newSubStatement, Is.EqualTo (expectedSubStatement));
    }
    public void VisitSqlSubStatementExpression_WithChanges ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement (Expression.Constant (0));
      var expression = new SqlSubStatementExpression (sqlStatement);

      var fakeResolvedStatement = SqlStatementModelObjectMother.CreateSqlStatement (Expression.Constant (1));
      _stageMock
          .Expect (mock => mock.ResolveSqlStatement (sqlStatement, _mappingResolutionContext))
          .Return (fakeResolvedStatement);
      var fakeSimplifiedExpression = Expression.Constant (0);
      _groupAggregateSimplifierMock
          .Expect (
              mock => mock.SimplifyIfPossible (
                  Arg<SqlSubStatementExpression>.Matches (e => ReferenceEquals (e.SqlStatement, fakeResolvedStatement)),
                  Arg.Is (expression.SqlStatement.SelectProjection)))
          .Return (fakeSimplifiedExpression);

      var result = _visitor.VisitExpression (expression);

      _stageMock.VerifyAllExpectations ();
      _groupAggregateSimplifierMock.VerifyAllExpectations ();
      Assert.That (result, Is.SameAs (fakeSimplifiedExpression));
    }
 public void SetUp ()
 {
   _sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement();
   _expression = new SqlSubStatementExpression (_sqlStatement);
 }
    public override Expression VisitSqlSubStatementExpression (SqlSubStatementExpression expression)
    {
      var newExpression = base.VisitSqlSubStatementExpression (expression);
      var newExpressionAsSqlSubStatementExpression = newExpression as SqlSubStatementExpression;

      // Substatements returning a single value need to be moved to the FROM part of the SQL statement because they might return more than one column.
      // Since a SqlSubStatementExpression must return a single row anyway, we can do this.
      // (However, errors that would have arisen because the statement does not return exactly one row will not be found.)
      if (newExpressionAsSqlSubStatementExpression != null
          && newExpressionAsSqlSubStatementExpression.SqlStatement.DataInfo is StreamedSingleValueInfo)
      {
        var sqlTable = newExpressionAsSqlSubStatementExpression.ConvertToSqlTable (Generator.GetUniqueIdentifier ("q"));
        var sqlTableReferenceExpression = new SqlTableReferenceExpression (sqlTable);

        Context.AddSqlTable (sqlTable, _sqlStatementBuilder);
        return VisitExpression (sqlTableReferenceExpression);
      }
      return newExpression;
    }
    public void ConvertToSqlTable ()
    {
      var selectProjection = Expression.Constant (new Cook());
      var sqlStatement =
          new SqlStatementBuilder { DataInfo = new StreamedSingleValueInfo (typeof (Cook), false), SelectProjection = selectProjection }.
              GetSqlStatement();
      var expression = new SqlSubStatementExpression (sqlStatement);

      var result = expression.ConvertToSqlTable ("q0");

      Assert.That (result.JoinSemantics, Is.EqualTo (JoinSemantics.Inner));
      Assert.That (result.TableInfo.GetResolvedTableInfo().TableAlias, Is.EqualTo ("q0"));
      Assert.That (result.TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      
      var newSubStatement = ((ResolvedSubStatementTableInfo) result.TableInfo).SqlStatement;
      var expectedSubStatement = new SqlStatementBuilder (sqlStatement)
      {
        DataInfo = new StreamedSequenceInfo (typeof (IEnumerable<Cook>), sqlStatement.SelectProjection)
      }.GetSqlStatement();

      Assert.That (newSubStatement, Is.EqualTo (expectedSubStatement));
    }
    public void VisitSqlInExpression ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatementWithCook();
      var sqlSubStatementExpression = new SqlSubStatementExpression (sqlStatement);
      var sqlInExpression = new SqlInExpression (Expression.Constant (1), sqlSubStatementExpression);

      _stageMock
          .Expect (
              mock =>
              mock.GenerateTextForSqlStatement (
                  Arg.Is (_commandBuilder), Arg<SqlStatement>.Is.Anything))
          .WhenCalled (mi => ((SqlCommandBuilder) mi.Arguments[0]).Append ("test"));
      _stageMock.Replay();

      SqlGeneratingExpressionVisitor.GenerateSql (
          sqlInExpression, _commandBuilder, _stageMock);

      Assert.That (_commandBuilder.GetCommandText(), Is.EqualTo ("@1 IN (test)"));
      _stageMock.VerifyAllExpectations();
    }
    public override Expression VisitSqlSubStatementExpression (SqlSubStatementExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var sqlStatement = expression.SqlStatement;

      var factory = new SqlPreparationSubStatementTableFactory (Stage, Context, _generator);
      FromExpressionInfo = factory.CreateSqlTableForStatement (sqlStatement, _tableGenerator);
      Assertion.DebugAssert (FromExpressionInfo.Value.WhereCondition == null);

      return new SqlTableReferenceExpression (FromExpressionInfo.Value.SqlTable);
    }
    public void VisitSqlSubStatementExpression_WithOrderingsAndNoTopExpression ()
    {
      var builder = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatementWithCook())
                    {
                        SelectProjection = new NamedExpression ("test", Expression.Constant ("test")),
                        Orderings = { new Ordering (Expression.Constant ("order1"), OrderingDirection.Asc) }
                    };
      var statement = builder.GetSqlStatement();
      var sqlSubStatementExpression = new SqlSubStatementExpression (statement);

      var stage = new DefaultSqlPreparationStage (_methodCallTransformerProvider, new ResultOperatorHandlerRegistry(), _generator);

      var result = SqlPreparationFromExpressionVisitor.AnalyzeFromExpression (
          sqlSubStatementExpression,
          stage,
          _generator,
          _methodCallTransformerProvider,
          _context,
          info => new SqlTable (info, JoinSemantics.Inner));

      var sqlTable = (SqlTable) result.SqlTable;
      Assert.That (sqlTable.TableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));
      Assert.That (((ResolvedSubStatementTableInfo) sqlTable.TableInfo).SqlStatement.Orderings.Count, Is.EqualTo (0));
    }
    public Expression VisitSqlSubStatementExpression (SqlSubStatementExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var newSqlStatement = _stage.ApplySelectionContext (expression.SqlStatement, _currentContext, _context);
      if (!ReferenceEquals (expression.SqlStatement, newSqlStatement))
        return new SqlSubStatementExpression (newSqlStatement);
      return expression;
    }
    public void ResolveSelectExpression_SqlSubStatementExpressionWithStreamedSingleValueInfo ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Single();
      var expression = new SqlSubStatementExpression (sqlStatement);
      var sqlStatementBuilder = new SqlStatementBuilder ();

      _resolverMock
          .Expect (mock => mock.ResolveConstantExpression (((ConstantExpression) sqlStatement.SelectProjection)))
          .Return (sqlStatement.SelectProjection);
      _resolverMock.Replay ();

      var result = _stage.ResolveSelectExpression (expression, sqlStatementBuilder, _mappingResolutionContext);

      _resolverMock.VerifyAllExpectations ();
      var expectedDataInfo = new StreamedSequenceInfo (typeof (IEnumerable<>).MakeGenericType (sqlStatement.DataInfo.DataType), sqlStatement.SelectProjection);
      var expectedSqlStatement = new SqlStatementBuilder (sqlStatement) { DataInfo = expectedDataInfo }.GetSqlStatement ();

      Assert.That (sqlStatementBuilder.SqlTables.Count, Is.EqualTo (1));
      Assert.That (((ResolvedSubStatementTableInfo) ((SqlTable) sqlStatementBuilder.SqlTables[0]).TableInfo).SqlStatement, Is.EqualTo (expectedSqlStatement));
      Assert.That (result, Is.SameAs (sqlStatement.SelectProjection));
    }
    private Expression CheckAndSimplifyEntityWithinSubStatement (SqlSubStatementExpression sqlSubStatementExpression)
    {
      var newSelectProjection = ResolvePotentialEntity (sqlSubStatementExpression.SqlStatement.SelectProjection);
      if (newSelectProjection != sqlSubStatementExpression.SqlStatement.SelectProjection)
      {
        var newSubStatement = new SqlStatementBuilder (sqlSubStatementExpression.SqlStatement) { SelectProjection = newSelectProjection };
        newSubStatement.RecalculateDataInfo (sqlSubStatementExpression.SqlStatement.SelectProjection);

        return newSubStatement.GetSqlStatement ().CreateExpression ();
      }

      return sqlSubStatementExpression;
    }
    public void VisitSqlSubStatementExpression_WithNonBooleanSqlGroupingSelectExpression ()
    {
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatementWithCook())
                         {
                             SelectProjection =
                                 new NamedExpression (
                                     "test", new SqlGroupingSelectExpression (Expression.Constant ("key"), Expression.Constant ("element")))
                         }.GetSqlStatement();

      var sqlSubStatementExpression = new SqlSubStatementExpression (sqlStatement);
      var stage = new DefaultSqlPreparationStage (_methodCallTransformerProvider, new ResultOperatorHandlerRegistry(), _generator);

      var result = SqlPreparationFromExpressionVisitor.AnalyzeFromExpression (
          sqlSubStatementExpression,
          stage,
          _generator,
          _methodCallTransformerProvider,
          _context,
          info => new SqlTable (info, JoinSemantics.Inner));

      Assert.That (((SqlTable) result.SqlTable).TableInfo, Is.InstanceOf (typeof (ResolvedSubStatementTableInfo)));
    }