SqlTableReferenceExpression represents a data row in a SqlTable.
Inheritance: Remotion.Linq.Clauses.Expressions.ExtensionExpression
    public void PrepareTopExpression ()
    {
      var result = _stage.PrepareTopExpression (_querySourceReferenceExpression, _context);

      var expectedExpression = new SqlTableReferenceExpression (_sqlTable);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedExpression, result);
    }
    public void ToString_SqlTableWithUnresolvedTableInfo ()
    {
      var sqlTable = new SqlTable (new UnresolvedTableInfo (typeof (Cook)), JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF(UnresolvedTableInfo(Cook))"));
    }
    public void TryGetExpressiontMappingFromHierarchy ()
    {
      var querySourceReferenceExpression = new QuerySourceReferenceExpression (_source);
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (_sqlTable);
      _context.AddExpressionMapping (querySourceReferenceExpression, sqlTableReferenceExpression);

      Expression result = _context.GetExpressionMapping (querySourceReferenceExpression);

      Assert.That (result, Is.SameAs (sqlTableReferenceExpression));
    }
    public void CreateSqlTableForSubStatement_WithoutOrderings ()
    {
      var statementWithoutOrderings = SqlStatementModelObjectMother.CreateSqlStatementWithCook();

      var result = _factory.CreateSqlTableForStatement (statementWithoutOrderings, info => new SqlTable (info, JoinSemantics.Inner));

      _stageMock.VerifyAllExpectations ();

      var tableInfo = ((SqlTable) result.SqlTable).TableInfo;
      Assert.That (tableInfo, Is.TypeOf (typeof (ResolvedSubStatementTableInfo)));

      var subStatement = ((ResolvedSubStatementTableInfo) tableInfo).SqlStatement;
      Assert.That (subStatement, Is.SameAs (statementWithoutOrderings));

      Assert.That (result.WhereCondition, Is.Null);
      Assert.That (result.ExtractedOrderings, Is.Empty);

      var expectedItemSelector = new SqlTableReferenceExpression (result.SqlTable);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedItemSelector, result.ItemSelector);
    }
    public void SetUp ()
    {
      _stageMock = MockRepository.GenerateMock<ISqlPreparationStage> ();
      _generator = new UniqueIdentifierGenerator ();
      _context = SqlStatementModelObjectMother.CreateSqlPreparationContext ();

      _handler = new SkipResultOperatorHandler ();
      
      _sqlTable = new SqlTable (new UnresolvedTableInfo (typeof (Cook)), JoinSemantics.Inner);
      _selectProjection = new SqlTableReferenceExpression (_sqlTable);

      _ordering = new Ordering (Expression.Constant (7), OrderingDirection.Asc);
      _sqlStatementBuilder = new SqlStatementBuilder
      {
        SelectProjection = _selectProjection,
        DataInfo = new StreamedSequenceInfo (typeof (Cook[]), Expression.Constant (new Cook ())),
        SqlTables = { _sqlTable },
      };

      _tupleCtor = _tupleCtor = typeof (KeyValuePair<Cook, int>).GetConstructor (new[] { typeof (Cook), typeof (int) });
    }
    protected override Expression VisitMemberExpression (MemberExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var preparedMemberExpression = (MemberExpression) TranslateExpression (expression, Context, Stage, MethodCallTransformerProvider);

      var joinInfo = new UnresolvedCollectionJoinInfo (preparedMemberExpression.Expression, preparedMemberExpression.Member);
      var joinedTable = new SqlJoinedTable (joinInfo, JoinSemantics.Inner);
      var oldStyleJoinedTable = _tableGenerator (joinedTable);
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (oldStyleJoinedTable);
      FromExpressionInfo = new FromExpressionInfo (
          oldStyleJoinedTable, new Ordering[0], sqlTableReferenceExpression, new JoinConditionExpression (joinedTable));

      return sqlTableReferenceExpression;
    }
 public void GetExpressionMapping_GetFromParentContext ()
 {
   var querySourceReferenceExpression = new QuerySourceReferenceExpression (_parentSource);
   var sqlTableReferenceExpression = new SqlTableReferenceExpression (_parentSqlTable);
   _parentContext.AddExpressionMapping (querySourceReferenceExpression, sqlTableReferenceExpression);
   Assert.That (_contextWithParent.GetExpressionMapping (querySourceReferenceExpression), Is.SameAs (sqlTableReferenceExpression));
 }
    public void AddJoinClause ()
    {
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable();
      var preparedExpression = new SqlTableReferenceExpression (sqlTable);
      var joinClause = ExpressionHelper.CreateJoinClause<Cook>();
      var preparedFromExpressionInfo = new FromExpressionInfo (
          sqlTable, new Ordering[] { }, new SqlTableReferenceExpression (sqlTable), null);

      _stageMock
          .Expect (
              mock =>
              mock.PrepareFromExpression (
                  Arg<Expression>.Matches (e => e == joinClause.InnerSequence),
                  Arg<ISqlPreparationContext>.Matches (c => c != _context),
                  Arg < Func<ITableInfo, SqlTable>>.Is.Anything))
          .Return (preparedFromExpressionInfo);
      _stageMock
          .Expect (
              mock =>
              mock.PrepareWhereExpression (
                  Arg<Expression>.Matches (
                      e => ((BinaryExpression) e).Left == joinClause.OuterKeySelector && ((BinaryExpression) e).Right == joinClause.InnerKeySelector),
                  Arg<ISqlPreparationContext>.Matches (c => c != _context)))
          .Return (preparedExpression);
      _stageMock.Replay();

      var result = _visitor.AddJoinClause (joinClause);

      _stageMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (sqlTable));
      Assert.That (_visitor.SqlStatementBuilder.WhereCondition, Is.SameAs (preparedExpression));
    }
    public virtual SqlEntityExpression ResolveEntityRefMemberExpression (SqlEntityRefMemberExpression expression, IJoinInfo joinInfo, IMappingResolutionContext context)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);
      ArgumentUtility.CheckNotNull ("joinInfo", joinInfo);
      ArgumentUtility.CheckNotNull ("context", context);

      var originatingSqlTable = context.GetSqlTableForEntityExpression (expression.OriginatingEntity);
      var join = originatingSqlTable.GetOrAddLeftJoin (joinInfo, expression.MemberInfo);
      join.JoinInfo = ResolveJoinInfo (join.JoinInfo, context);
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (join);
      
      return (SqlEntityExpression) ResolveExpression (sqlTableReferenceExpression, context);
    }
 public void SetUp ()
 {
   _tableReferenceExpression = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable(typeof(Cook)));
 }
    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 Expression VisitSqlTableReferenceExpression (SqlTableReferenceExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var resolvedExpression = _stage.ResolveTableReferenceExpression (expression, _context);
      return VisitExpression (resolvedExpression);
    }
    public void VisitSqlTableReferenceExpression_RevisitsResult ()
    {
      var tableReferenceExpression = new SqlTableReferenceExpression (_sqlTable);
      var fakeResult = Expression.Constant (0);

      _stageMock
          .Expect (mock => mock.ResolveTableReferenceExpression (tableReferenceExpression, _mappingResolutionContext))
          .Return (fakeResult);
      _stageMock.Replay();
      _resolverMock
          .Expect (mock => mock.ResolveConstantExpression (fakeResult))
          .Return (fakeResult);
      _resolverMock.Replay();

      var result = _visitor.VisitExpression (tableReferenceExpression);

      _stageMock.VerifyAllExpectations();
      _resolverMock.VerifyAllExpectations();
      Assert.That (result, Is.SameAs (fakeResult));
    }
    public void VisitExpression_ReferenceToOtherTable ()
    {
      var visitor = new GroupAggregateSimplifier.SimplifyingVisitor (_resolvedJoinedGroupingTable, _associatedGroupingSelectExpression.ElementExpression);

      var input = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable());
      visitor.VisitExpression (input);

      Assert.That (visitor.CanBeTransferredToGroupingSource, Is.False);
    }
    public void VisitExpression_ReferenceToRightTable ()
    {
      var visitor = new GroupAggregateSimplifier.SimplifyingVisitor (_resolvedJoinedGroupingTable, _associatedGroupingSelectExpression.ElementExpression);

      var input = new SqlTableReferenceExpression (_resolvedJoinedGroupingTable);
      var result = visitor.VisitExpression (input);

      Assert.That (visitor.CanBeTransferredToGroupingSource, Is.True);
      Assert.That (result, Is.SameAs (_associatedGroupingSelectExpression.ElementExpression));
    }
    public void SimplifyIfPossible_WithUnresolvedProjection_NotMatchingResolvedOned_NoAggregation ()
    {
      var expression = new SqlSubStatementExpression (_simplifiableResolvedSqlStatement);

      var nonSimplifiableProjection = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable ());
      _groupAggregateSimplifier.SimplifyIfPossible (expression, nonSimplifiableProjection);
    }
    public void ResolveTableReferenceExpression ()
    {
      var expression = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable_WithResolvedTableInfo (typeof (Cook)));
      var fakeResult = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook));

      _resolverMock
          .Expect (mock => mock.ResolveSimpleTableInfo (expression.SqlTable.GetResolvedTableInfo(), _uniqueIdentifierGenerator))
          .Return (fakeResult);

      var result = _stage.ResolveTableReferenceExpression (expression, _mappingResolutionContext);

      Assert.That (result, Is.SameAs (fakeResult));
    }
    public void ResolveSqlStatement ()
    {
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable_WithUnresolvedTableInfo (typeof (Cook));
      var tableReferenceExpression = new SqlTableReferenceExpression (new SqlTable (_fakeResolvedSimpleTableInfo, JoinSemantics.Inner));
      var sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement(tableReferenceExpression, new[] { sqlTable});
      var fakeEntityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook));

      _resolverMock
          .Expect (mock => mock.ResolveTableInfo ((UnresolvedTableInfo) ((SqlTable) sqlStatement.SqlTables[0]).TableInfo, _uniqueIdentifierGenerator))
          .Return (_fakeResolvedSimpleTableInfo);
      _resolverMock
          .Expect (mock => mock.ResolveSimpleTableInfo (tableReferenceExpression.SqlTable.GetResolvedTableInfo(), _uniqueIdentifierGenerator))
          .Return (fakeEntityExpression);
      _resolverMock.Replay();

      var newSqlStatment = _stage.ResolveSqlStatement (sqlStatement, _mappingResolutionContext);

      _resolverMock.VerifyAllExpectations();
      Assert.That (((SqlTable) newSqlStatment.SqlTables[0]).TableInfo, Is.SameAs (_fakeResolvedSimpleTableInfo));
      Assert.That (newSqlStatment.SelectProjection, Is.SameAs (fakeEntityExpression));
    }
    public Expression ResolveTableReferenceExpression (SqlTableReferenceExpression expression, IMappingResolutionContext context)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);
      ArgumentUtility.CheckNotNull ("context", context);

      return expression.SqlTable.GetResolvedTableInfo ().ResolveReference (expression.SqlTable, _resolver, context, _uniqueIdentifierGenerator);
    }
    public Expression VisitSqlTableReferenceExpression (SqlTableReferenceExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var tableInfo = new UnresolvedGroupReferenceTableInfo (expression.SqlTable);
      var sqlTable = new SqlTable (tableInfo, JoinSemantics.Inner);
      FromExpressionInfo = new FromExpressionInfo (sqlTable, new Ordering[0], new SqlTableReferenceExpression (sqlTable), null);

      return expression;
    }
    protected override Expression VisitConstantExpression (ConstantExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var itemType = ReflectionUtility.GetItemTypeOfClosedGenericIEnumerable (expression.Type, "from expression");
      var sqlTable = _tableGenerator (new UnresolvedTableInfo (itemType));
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (sqlTable);
      FromExpressionInfo = new FromExpressionInfo (sqlTable, new Ordering[0], sqlTableReferenceExpression, null);

      return sqlTableReferenceExpression;
    }
    public void VisitSqlTableReferenceExpression_Grouping ()
    {
      var sqlTable = new SqlTable (new ResolvedSimpleTableInfo (typeof (IGrouping<string, int>), "test", "t0"), JoinSemantics.Inner);
      var expression = new SqlTableReferenceExpression (sqlTable);

      var result = SqlPreparationFromExpressionVisitor.AnalyzeFromExpression (
          expression, _stageMock, _generator, _methodCallTransformerProvider, _context, null);

      Assert.That (result.SqlTable, Is.Not.SameAs (sqlTable));
      Assert.That (result.WhereCondition, Is.Null);
      Assert.That (result.ExtractedOrderings, Is.Empty);

      var expectedItemSelector = new SqlTableReferenceExpression (result.SqlTable);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedItemSelector, result.ItemSelector);

      var tableInfo = ((SqlTable) result.SqlTable).TableInfo;
      Assert.That (tableInfo, Is.TypeOf (typeof (UnresolvedGroupReferenceTableInfo)));
      var castTableInfo = (UnresolvedGroupReferenceTableInfo) tableInfo;
      Assert.That (castTableInfo.ItemType, Is.SameAs (typeof (int)));
      Assert.That (castTableInfo.ReferencedGroupSource, Is.SameAs (sqlTable));
      Assert.That (result.SqlTable.JoinSemantics, Is.EqualTo (JoinSemantics.Inner));
    }
    public void VisitSelectClause_CreatesSelectProjection ()
    {
      var preparedExpression = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook)));

      _stageMock
          .Expect (
              mock =>
              mock.PrepareSelectExpression (
                  Arg<Expression>.Matches (e => e == _selectClause.Selector),
                  Arg<ISqlPreparationContext>.Matches (c => c != _context)))
          .Return (preparedExpression);
      _stageMock.Replay();

      _visitor.VisitSelectClause (_selectClause, _queryModel);

      _stageMock.VerifyAllExpectations();
      Assert.That (_visitor.SqlStatementBuilder.SelectProjection, Is.SameAs (preparedExpression));
      Assert.That (_visitor.SqlStatementBuilder.DataInfo, Is.TypeOf (typeof (StreamedSequenceInfo)));
      Assert.That (((StreamedSequenceInfo) _visitor.SqlStatementBuilder.DataInfo).DataType, Is.EqualTo (_selectClause.GetOutputDataInfo().DataType));
    }
    public void ToString_SqlJoinedTableWithResolvedJoinInfo ()
    {
      var sqlTable =
          new SqlJoinedTable (
              new ResolvedJoinInfo (
                  new ResolvedSimpleTableInfo (typeof (Cook), "CookTable", "c"), Expression.Constant (true)),
              JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF(c)"));
    }
    public void ToString_OtherSqlTable ()
    {
      var sqlTable = new OtherSqlTable (typeof (Cook), JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF (OtherSqlTable (Cook))"));
    }
    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 void VisitQuerySourceReferenceExpression_WithNonNullWhereCondition ()
    {
      var memberInfo = typeof (Cook).GetProperty ("Assistants");
      var sqlTableReferenceExpression = new SqlTableReferenceExpression (SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook)));
      var innerSequenceExpression =
          Expression.MakeMemberAccess (
              sqlTableReferenceExpression, memberInfo);
      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);
      var fakeWhereExpression = Expression.Constant (true);

      _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.WhereCondition, Is.AssignableTo (typeof (BinaryExpression)));
      Assert.That (fromExpressionInfo.WhereCondition.NodeType, Is.EqualTo(ExpressionType.AndAlso));
      Assert.That (((BinaryExpression) fromExpressionInfo.WhereCondition).Left, Is.TypeOf(typeof(JoinConditionExpression)));
      Assert.That (((JoinConditionExpression) ((BinaryExpression) fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo, Is.TypeOf (typeof (UnresolvedCollectionJoinInfo)));
      Assert.That (
          ((UnresolvedCollectionJoinInfo) ((JoinConditionExpression) ((BinaryExpression) fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo).SourceExpression, Is.SameAs(sqlTableReferenceExpression));
      Assert.That (
          ((UnresolvedCollectionJoinInfo) ((JoinConditionExpression) ((BinaryExpression) fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinInfo).MemberInfo, Is.SameAs (memberInfo));
      Assert.That (((JoinConditionExpression) ((BinaryExpression) fromExpressionInfo.WhereCondition).Left).JoinedTable.JoinSemantics, Is.EqualTo(JoinSemantics.Inner));
      Assert.That (((BinaryExpression) fromExpressionInfo.WhereCondition).Right, Is.SameAs (fakeWhereExpression));
    }
    public void ResolveGroupByExpression_ResolvesExpression ()
    {
      var expression = new SqlTableReferenceExpression (_sqlTable);
      var fakeResult = Expression.Constant (0);

      _stageMock
          .Expect (mock => mock.ResolveGroupByExpression (expression, _mappingResolutionContext))
          .Return (fakeResult);
      _stageMock.Replay ();

      var result = _visitor.ResolveGroupByExpression (expression);

      _stageMock.VerifyAllExpectations ();

      Assert.That (result, Is.SameAs (fakeResult));
    }
    public void ToString_SqlJoinedTableWithUnresolvedJoinInfo ()
    {
      var sqlTable = new SqlJoinedTable (SqlStatementModelObjectMother.CreateUnresolvedJoinInfo_KitchenCook(), JoinSemantics.Left);
      var expression = new SqlTableReferenceExpression (sqlTable);
      var result = expression.ToString();

      Assert.That (result, Is.EqualTo ("TABLE-REF(UnresolvedJoinInfo(Cook))"));
    }
    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")));
    }