ResolvedSubStatementTableInfo represents the data source defined by a table of a subquery in a relational database.
Inheritance: IResolvedTableInfo
    public ITableInfo VisitSubStatementTableInfo (ResolvedSubStatementTableInfo tableInfo)
    {
      ArgumentUtility.CheckNotNull ("tableInfo", tableInfo);

      var newStatement = _stage.ApplySelectionContext (tableInfo.SqlStatement, _expressionContext, _mappingResolutionContext);
      if (newStatement != tableInfo.SqlStatement)
        return new ResolvedSubStatementTableInfo (tableInfo.TableAlias, newStatement);
      return tableInfo;
    }
 public void SetUp ()
 {
   _sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)))
                      {
                          SelectProjection = new NamedExpression ("test", Expression.Constant (5)),
                          DataInfo = new StreamedSequenceInfo (typeof (int[]), Expression.Constant (0))
                      }.GetSqlStatement();
   _tableInfo = new ResolvedSubStatementTableInfo ("c", _sqlStatement);
 }
    protected SubStatementReferenceResolver (ResolvedSubStatementTableInfo tableInfo, SqlTableBase sqlTable, IMappingResolutionContext context)
    {
      ArgumentUtility.CheckNotNull ("tableInfo", tableInfo);
      ArgumentUtility.CheckNotNull ("sqlTable", sqlTable);
      ArgumentUtility.CheckNotNull ("context", context);

      _tableInfo = tableInfo;
      _sqlTable = sqlTable;
      _context = context;
    }
    public void Initialization_ItemTypeWithCovariantSubstatement ()
    {
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)))
      {
        SelectProjection = new NamedExpression ("test", Expression.Constant (5)),
        DataInfo = new StreamedSequenceInfo (typeof (object[]), Expression.Constant (0))
      }.GetSqlStatement ();
      var tableInfo = new ResolvedSubStatementTableInfo ("c", sqlStatement);

      Assert.That (tableInfo.ItemType, Is.EqualTo (typeof (object)));
    }
    public FromExpressionInfo CreateSqlTableForStatement (SqlStatement sqlStatement, Func<ITableInfo, SqlTable> tableCreator)
    {
      if (sqlStatement.Orderings.Count == 0)
      {
        var tableInfo = new ResolvedSubStatementTableInfo (_uniqueIdentifierGenerator.GetUniqueIdentifier ("q"), sqlStatement);
        var sqlTable = tableCreator (tableInfo);
        return new FromExpressionInfo (sqlTable, new Ordering[0], new SqlTableReferenceExpression (sqlTable), null);
      }

      var selectExpressionWithOrderings = GetNewSelectExpressionWithOrderings (sqlStatement);
      var tableWithSubStatement = CreateSqlCompatibleSubStatementTable (sqlStatement, selectExpressionWithOrderings, tableCreator);
      return GetFromExpressionInfoForSubStatement (sqlStatement, tableWithSubStatement);
    }
    public void ResolveSubStatementReferenceExpression_CreatesColumnExpression_ForNamedExpression ()
    {
      var referencedExpression = new NamedExpression ("test", Expression.Constant (0));
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement (referencedExpression);

      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (
          referencedExpression, tableInfo, sqlTable, _context);

      var expectedResult = new SqlColumnDefinitionExpression (typeof (int), "q0", "test", false);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }
    public void ApplyContext_ResolvedSubStatementTableInfo_SameTableInfo ()
    {
      var subStatement = SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook));
      var subStatementTableInfo = new ResolvedSubStatementTableInfo ("c", subStatement);
     
      _stageMock
          .Expect (mock => mock.ApplySelectionContext (subStatement, SqlExpressionContext.ValueRequired, _mappingresolutionContext))
          .Return (subStatement);
      _stageMock.Replay ();

      var result = SqlContextTableInfoVisitor.ApplyContext (subStatementTableInfo, SqlExpressionContext.ValueRequired, _stageMock, _mappingresolutionContext);

      Assert.That (result, Is.SameAs (subStatementTableInfo));
      _stageMock.VerifyAllExpectations ();
    }
    public static Expression ResolveSubStatementReferenceExpression (
        Expression referencedExpression,
        ResolvedSubStatementTableInfo containingSubStatementTableInfo,
        SqlTableBase containingSqlTable,
        IMappingResolutionContext context)
    {
      ArgumentUtility.CheckNotNull ("referencedExpression", referencedExpression);
      ArgumentUtility.CheckNotNull ("containingSubStatementTableInfo", containingSubStatementTableInfo);
      ArgumentUtility.CheckNotNull ("containingSqlTable", containingSqlTable);
      
      var visitor = new SubStatementReferenceResolver (containingSubStatementTableInfo, containingSqlTable, context);
      var result = visitor.VisitExpression (referencedExpression);

      return result;
    }
    public SqlTable ConvertToSqlTable (string uniqueIdentifier)
    {
      ArgumentUtility.CheckNotNullOrEmpty ("uniqueIdentifier", uniqueIdentifier);
      ArgumentUtility.CheckNotNullOrEmpty ("uniqueIdentifier", uniqueIdentifier);
      
      var joinSemantic = CalculateJoinSemantic();

      SqlStatement sequenceStatement;
      if (SqlStatement.DataInfo is StreamedSequenceInfo)
        sequenceStatement = SqlStatement;
      else
        sequenceStatement = ConvertValueStatementToSequenceStatement ();

      var resolvedSubStatementTableInfo = new ResolvedSubStatementTableInfo (uniqueIdentifier, sequenceStatement);
      return new SqlTable (resolvedSubStatementTableInfo, joinSemantic);
    }
    public void ResolveSubStatementReferenceExpression_CreatesNewExpressionWithReferences_ForNewExpressions ()
    {
      var newExpression = Expression.New (
          TypeForNewExpression.GetConstructor (typeof(int)),
          new[] { new NamedExpression ("const", Expression.Constant (0)) },
          (MemberInfo) typeof (TypeForNewExpression).GetProperty ("A"));

      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement (newExpression);

      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (newExpression, tableInfo, sqlTable, _context);

      var expectedResult = Expression.New (
          TypeForNewExpression.GetConstructor (typeof (int)),
          new Expression[] { new NamedExpression ("A", new SqlColumnDefinitionExpression (typeof (int), "q0", "const", false) ) },
          newExpression.Members);

      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }
    private SqlTable CreateSqlCompatibleSubStatementTable (
        SqlStatement originalStatement, 
        Expression newSelectProjection, 
        Func<ITableInfo, SqlTable> tableCreator)
    {
      // create a new statement equal to the original one, but with the tuple as its select projection
      var builder = new SqlStatementBuilder (originalStatement) { SelectProjection = newSelectProjection };
      builder.RecalculateDataInfo (originalStatement.SelectProjection);

      // clear orderings unless required for TopExpression
      if (originalStatement.TopExpression == null)
        builder.Orderings.Clear();
        
      var newSqlStatement = builder.GetSqlStatement();

      // put new statement into a sub-statement table
      var subStatementTableInfo = new ResolvedSubStatementTableInfo (_uniqueIdentifierGenerator.GetUniqueIdentifier ("q"), newSqlStatement);
      return tableCreator (subStatementTableInfo);
    }
    public new void ToString ()
    {
      var sqlStatement = new SqlStatementBuilder ()
      {
        SelectProjection = Expression.Constant (new Cook ()),
        DataInfo = new StreamedSequenceInfo (typeof (IQueryable<int>), Expression.Constant (0))
      }.GetSqlStatement ();
      var subStatementInfo = new ResolvedSubStatementTableInfo ("c", sqlStatement);

      var result = subStatementInfo.ToString ();
      Assert.That (result, Is.EqualTo ("(" + sqlStatement + ") [c]"));
    }
    public ITableInfo VisitSubStatementTableInfo (ResolvedSubStatementTableInfo tableInfo)
    {
      ArgumentUtility.CheckNotNull ("tableInfo", tableInfo);

      _commandBuilder.Append ("(");
      _stage.GenerateTextForSqlStatement (_commandBuilder, tableInfo.SqlStatement);
      _commandBuilder.Append (")");
      _commandBuilder.Append (" AS ");
      _commandBuilder.AppendIdentifier (tableInfo.TableAlias);

      return tableInfo;
    }
    public ITableInfo VisitSubStatementTableInfo (ResolvedSubStatementTableInfo tableInfo)
    {
      ArgumentUtility.CheckNotNull ("tableInfo", tableInfo);

      var newSqlStatement = _stage.ResolveSqlStatement (tableInfo.SqlStatement, _context);
      if (newSqlStatement.Equals (tableInfo.SqlStatement))
        return tableInfo;
      else
        return new ResolvedSubStatementTableInfo (tableInfo.TableAlias, newSqlStatement);
    }
    public void ResolveTableInfo_SubStatementTableInfo_SubStatementUnmodified ()
    {
      var sqlSubStatementTableInfo = new ResolvedSubStatementTableInfo ("c", _sqlStatement);

      _stageMock
          .Expect (mock => mock.ResolveSqlStatement (_sqlStatement, _mappingResolutionContext))
          .Return (_sqlStatement);
      _resolverMock.Replay ();

      var result = (ResolvedSubStatementTableInfo) ResolvingTableInfoVisitor.ResolveTableInfo (sqlSubStatementTableInfo, _resolverMock, _generator, _stageMock, _mappingResolutionContext);

      _stageMock.VerifyAllExpectations ();
      Assert.That (result, Is.SameAs (sqlSubStatementTableInfo));
    }
    public void ResolveSubStatementReferenceExpression_RegistersEntityTable_WithinUnknownExpression ()
    {
      var referencedExpression = Expression.Convert (SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook)), typeof (Chef));
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement (referencedExpression);

      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (
          referencedExpression, tableInfo, sqlTable, _context);

      Assert.That (result.NodeType, Is.EqualTo (ExpressionType.Convert));
      var entityReference = (SqlEntityExpression) ((UnaryExpression) result).Operand;
      Assert.That (_context.GetSqlTableForEntityExpression (entityReference), Is.SameAs (sqlTable));
      
    }
    public void ResolveSubStatementReferenceExpression_CopiesExpression_ForUnknownExpression ()
    {
      var referencedExpression = Expression.Constant (0);
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement (referencedExpression);

      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (
          referencedExpression, tableInfo, sqlTable, _context);

      Assert.That (result, Is.SameAs (referencedExpression));
    }
    public void ResolveSubStatementReferenceExpression_CreatesSqlGroupingSelectExpressionWithNamedExpressions ()
    {
      var expression = new SqlGroupingSelectExpression (
          Expression.Constant ("key"), Expression.Constant ("element"), new[] { Expression.Constant ("aggregation") });
      var tableInfo = new ResolvedSubStatementTableInfo ("q0", SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)));
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable(typeof(Cook));

      var exprectedResult = new SqlGroupingSelectExpression (
          new NamedExpression ("key", Expression.Constant ("key")),
          new NamedExpression ("element", Expression.Constant ("element")),
          new[] { new NamedExpression ("a0", Expression.Constant ("aggregation")) });

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (expression, tableInfo, sqlTable, _context);

      SqlExpressionTreeComparer.CheckAreEqualTrees (result, exprectedResult);
      Assert.That (_context.GetReferencedGroupSource (((SqlGroupingSelectExpression) result)), Is.SameAs (sqlTable));
    }
    public void ApplyContext_JoinInfo ()
    {
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)))
                         {
                             SelectProjection = Expression.Constant (true),
                             DataInfo = new StreamedSequenceInfo (typeof (Cook[]), Expression.Constant (new Cook()))
                         }.GetSqlStatement();
      var tableInfo = new ResolvedSubStatementTableInfo ("c", sqlStatement);
      var joinInfo = new ResolvedJoinInfo (tableInfo, Expression.Equal (new SqlLiteralExpression (1), new SqlLiteralExpression (1)));

      var result = _stage.ApplyContext (joinInfo, SqlExpressionContext.ValueRequired, _mappingResolutionContext);

      Assert.That (result, Is.Not.SameAs (joinInfo));
      Assert.That (
          ((ResolvedSubStatementTableInfo) ((ResolvedJoinInfo) result).ForeignTableInfo).SqlStatement.SelectProjection,
          Is.TypeOf (typeof (SqlConvertedBooleanExpression)));
      Assert.That (
          ((ConstantExpression)
           ((SqlConvertedBooleanExpression) ((ResolvedSubStatementTableInfo) ((ResolvedJoinInfo) result).ForeignTableInfo).SqlStatement.SelectProjection)
               .Expression).Value,
          Is.EqualTo (1));
    }
    public void ResolveSubStatementReferenceExpression_CreatesEntityReference_ForEntities ()
    {
      var entityDefinitionExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook));
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)))
                         {
                             SelectProjection = entityDefinitionExpression,
                             DataInfo = new StreamedSequenceInfo (typeof (Cook[]), Expression.Constant (new Cook()))
                         }.GetSqlStatement();
      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (entityDefinitionExpression, tableInfo, sqlTable, _context);

      Assert.That (result, Is.TypeOf (typeof (SqlEntityReferenceExpression)));
      Assert.That (_context.GetSqlTableForEntityExpression ((SqlEntityReferenceExpression) result), Is.SameAs (sqlTable));

      var expectedResult = entityDefinitionExpression.CreateReference ("q0", tableInfo.SqlStatement.SelectProjection.Type);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }
    public void VisitSubStatementTableInfo ()
    {
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook[])))
      {
        DataInfo = new StreamedSequenceInfo (typeof (IQueryable<Cook>), Expression.Constant (new Cook ()))
      }.GetSqlStatement ();
      var resolvedSubTableInfo = new ResolvedSubStatementTableInfo ("cook", sqlStatement);

      _stageMock
          .Expect (mock => mock.GenerateTextForSqlStatement (_commandBuilder, sqlStatement))
          .WhenCalled (mi => ((SqlCommandBuilder) mi.Arguments[0]).Append ("XXX"));
      _stageMock.Replay();

      _generator.VisitSubStatementTableInfo (resolvedSubTableInfo);

      _stageMock.VerifyAllExpectations();
      Assert.That (_commandBuilder.GetCommandText (), Is.EqualTo ("(XXX) AS [cook]"));
    }
    public void GenerateSql_InnerJoinSemantics_NonFirstTable_SubstatementTableInfo ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook));
      var tableInfo = new ResolvedSubStatementTableInfo("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

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

      SqlTableAndJoinTextGenerator.GenerateSql (sqlTable, _commandBuilder, _stageMock, isFirstTable: false);

      _stageMock.VerifyAllExpectations();
      Assert.That (_commandBuilder.GetCommandText (), Is.EqualTo (" CROSS APPLY ([Table] AS [t]) AS [q0]"));
    }
    public void ResolveTableInfo ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook));
      var fakeResolvedSubStatementTableInfo = new ResolvedSubStatementTableInfo ("c", sqlStatement);

      _resolverMock
          .Expect (mock => mock.ResolveTableInfo (_unresolvedTableInfo, _uniqueIdentifierGenerator))
          .Return (fakeResolvedSubStatementTableInfo);
      _resolverMock.Replay();

      var result = _stage.ResolveTableInfo (_sqlTable.TableInfo, _mappingResolutionContext);

      _resolverMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (fakeResolvedSubStatementTableInfo));
    }
    public void ResolveSubStatementReferenceExpression_CreatesSqlGroupingReferenceExpression_ForSqlGroupingSelectExpression ()
    {
      var groupingSelectExpression = new SqlGroupingSelectExpression (
          SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook), "key"),  
          new NamedExpression ("element", Expression.Constant (0)), 
          new[] { new NamedExpression ("a0", Expression.Constant (1)) });
      var sqlStatement = new SqlStatementBuilder (SqlStatementModelObjectMother.CreateSqlStatement_Resolved (typeof (Cook)))
      {
        SelectProjection = groupingSelectExpression,
        DataInfo = new StreamedSequenceInfo (typeof (IGrouping<int, int>[]), Expression.Constant (null, typeof (IGrouping<int, int>)))
      }.GetSqlStatement ();
      var tableInfo = new ResolvedSubStatementTableInfo ("q0", sqlStatement);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);

      var result = SubStatementReferenceResolver.ResolveSubStatementReferenceExpression (groupingSelectExpression, tableInfo, sqlTable, _context);

      Assert.That (result, Is.TypeOf (typeof (SqlGroupingSelectExpression)));

      var referencedKeyExpression = ((SqlGroupingSelectExpression) result).KeyExpression;
      var expectedReferencedKeyExpression = new NamedExpression("key", new SqlEntityReferenceExpression (
          typeof (Cook), 
          "q0", 
          null, 
          (SqlEntityExpression) groupingSelectExpression.KeyExpression));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedReferencedKeyExpression, referencedKeyExpression);

      var referencedElementExpression = ((SqlGroupingSelectExpression) result).ElementExpression;
      var expectedReferencedElementExpression = new NamedExpression("element", new SqlColumnDefinitionExpression (typeof (int), "q0", "element", false));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedReferencedElementExpression, referencedElementExpression);

      Assert.That (((SqlGroupingSelectExpression) result).AggregationExpressions.Count, Is.EqualTo (1));
      var referencedAggregationExpression = ((SqlGroupingSelectExpression) result).AggregationExpressions[0];
      var expectedReferencedAggregationExpression = new NamedExpression("a0", new SqlColumnDefinitionExpression (typeof (int), "q0", "a0", false));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedReferencedAggregationExpression, referencedAggregationExpression);

      Assert.That (_context.GetReferencedGroupSource (((SqlGroupingSelectExpression) result)), Is.SameAs (sqlTable));
    }
    public void ResolveTableInfo_SubStatementTableInfo_SubStatementModified ()
    {
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatementWithCook ();

      var sqlSubStatementTableInfo = new ResolvedSubStatementTableInfo ("c", sqlStatement);

      _stageMock
          .Expect (mock => mock.ResolveSqlStatement (sqlStatement, _mappingResolutionContext))
          .Return (_sqlStatement);
      _resolverMock.Replay ();

      var result = (ResolvedSubStatementTableInfo) ResolvingTableInfoVisitor.ResolveTableInfo (sqlSubStatementTableInfo, _resolverMock, _generator, _stageMock, _mappingResolutionContext);

      _stageMock.VerifyAllExpectations ();
      Assert.That (result, Is.Not.SameAs (sqlSubStatementTableInfo));
      Assert.That (result.SqlStatement, Is.SameAs (_sqlStatement));
      Assert.That (result.TableAlias, Is.EqualTo (sqlSubStatementTableInfo.TableAlias));
    }