NamedExpression holds an expression and a name for it. If the name is null, a default name is used (or omitted if possible). When a NamedExpression holds an expression resolved to a SqlEntityExpression, the entity's name is set to the NamedExpression's name. Otherwise, the NamedExpression is retained and used to emit "AS ..." clauses in SQL generation. Therefore, NamedExpression must only be used in parts of a SqlStatement where "AS ..." clauses are allowed.
Inheritance: Remotion.Linq.Clauses.Expressions.ExtensionExpression
    public void ProcessNames_NoSqlEntityExpression_SameExpression ()
    {
      var expression = new NamedExpression ("test", Expression.Constant ("test"));

      var result = _namedExpressionCombiner.ProcessNames (expression);

      Assert.That (result, Is.SameAs (expression));
    }
    public void ProcessNames_ReturnsNamedExpression_OuterNameIsNull ()
    {
      var expression = new NamedExpression (null, new NamedExpression ("inner", Expression.Constant ("test")));

      var result = _namedExpressionCombiner.ProcessNames (expression);

      Assert.That (result, Is.TypeOf (typeof (NamedExpression)));
      Assert.That (((NamedExpression) result).Name, Is.EqualTo ("inner"));
    }
    public void VisitNamedExpression_NameIsNotNull ()
    {
      var columnExpression = new SqlColumnDefinitionExpression (typeof (string), "c", "Name", false);
      var expression = new NamedExpression ("test", columnExpression);

      SqlGeneratingSelectExpressionVisitor.GenerateSql (expression, _commandBuilder, _stageMock);

      Assert.That (_commandBuilder.GetCommandText (), Is.EqualTo ("[c].[Name] AS [test]"));
    }
    public override Expression VisitNamedExpression (NamedExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var result = base.VisitNamedExpression (expression);
      SetInMemoryProjectionForNamedExpression (expression.Type, Expression.Constant (GetNextColumnID (expression.Name ?? NamedExpression.DefaultName)));

      return result;
    }
    public override Expression VisitNamedExpression (NamedExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      VisitExpression (expression.Expression);
      CommandBuilder.Append (" AS ");
      CommandBuilder.AppendIdentifier (expression.Name ?? NamedExpression.DefaultName);
      
      return expression;
    }
    public Expression VisitNamedExpression (NamedExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      return new SqlColumnDefinitionExpression (
          expression.Type,
          _tableInfo.TableAlias,
          expression.Name ?? NamedExpression.DefaultName,
          false);
    }
    public void CreateWithNames ()
    {
      var result = SqlGroupingSelectExpression.CreateWithNames (_keyExpression, _elementExpression);

      var expectedKeyExpression = new NamedExpression ("key", _keyExpression);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedKeyExpression, result.KeyExpression);

      var expectedElementExpression = new NamedExpression ("element", _elementExpression);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedElementExpression, result.ElementExpression);
    }
    public void AddAggregationExpressionWithName ()
    {
      var name = _sqlGroupingSelectExpression.AddAggregationExpressionWithName (_aggregateExpression2);

      Assert.That (_sqlGroupingSelectExpression.AggregationExpressions.Count, Is.EqualTo (2));

      Assert.That (name, Is.EqualTo ("a1"));
      var expectedNamedExpression = new NamedExpression ("a1", _aggregateExpression2);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedNamedExpression, _sqlGroupingSelectExpression.AggregationExpressions[1]);
    }
    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 SetUp ()
    {
      _stageMock = MockRepository.GenerateStrictMock<ISqlGenerationStage> ();
      _commandBuilder = new SqlCommandBuilder ();
      _visitor = new TestableSqlGeneratingOuterSelectExpressionVisitor (_commandBuilder, _stageMock);

      _namedIntExpression = new NamedExpression ("test", Expression.Constant (0));
      _nameColumnExpression = new SqlColumnDefinitionExpression (typeof (string), "c", "Name", false);
      _entityExpression = new SqlEntityDefinitionExpression (
          typeof (Cook),
          "c",
          "test",
          e => e,
          new SqlColumnDefinitionExpression (typeof (int), "c", "ID", true),
          _nameColumnExpression,
          new SqlColumnDefinitionExpression (typeof (string), "c", "FirstName", false)
          );
    }
    public void SetUp ()
    {
      _dataInfo = new StreamedScalarValueInfo (typeof (int));

      _resolvedElementExpressionReference = new SqlColumnDefinitionExpression (typeof (string), "q0", "element", false);
      _resolvedSelectProjection = new NamedExpression (
          null, 
          new AggregationExpression (typeof (int), _resolvedElementExpressionReference, AggregationModifier.Min));

      _associatedGroupingSelectExpression = new SqlGroupingSelectExpression (
          new NamedExpression ("key", Expression.Constant ("k")),
          new NamedExpression ("element", Expression.Constant ("e")));

      _resolvedJoinedGroupingSubStatement = SqlStatementModelObjectMother.CreateSqlStatement (_associatedGroupingSelectExpression);
      _resolvedJoinedGroupingTable = new SqlTable (
          new ResolvedJoinedGroupingTableInfo (
              "q1",
              _resolvedJoinedGroupingSubStatement,
              _associatedGroupingSelectExpression,
              "q0"), JoinSemantics.Inner);

      _simplifiableResolvedSqlStatement = new SqlStatement (
          _dataInfo,
          _resolvedSelectProjection,
          new[] { _resolvedJoinedGroupingTable },
          null,
          null,
          new Ordering[0],
          null,
          false,
          Expression.Constant (0),
          Expression.Constant (0));
      _simplifiableUnresolvedProjection = new AggregationExpression (
          typeof (int),
          new SqlTableReferenceExpression (_resolvedJoinedGroupingTable),
          AggregationModifier.Count);

      _stageMock = MockRepository.GenerateStrictMock<IMappingResolutionStage> ();
      _context = new MappingResolutionContext();

      _groupAggregateSimplifier = new GroupAggregateSimplifier (_stageMock, _context);
    }
    public virtual Expression VisitSqlConvertedBooleanExpression (SqlConvertedBooleanExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var namedExpression = expression.Expression as NamedExpression;
      if (namedExpression != null)
      {
        // Since ADO.NET returns bit columns as actual boolean values (not as integer values), we need to convert the NamedExpression back to be
        // of type bool/bool? instead of int/int?.
        var conversionToBool = GetBitConversionExpression (
            sourceType: namedExpression.Type, targetType: expression.Type, convertedExpression: namedExpression.Expression);

        var newNamedExpression = new NamedExpression (namedExpression.Name, conversionToBool);
        return VisitExpression (newNamedExpression);
      }
      else
      {
        VisitExpression (expression.Expression);
        return expression;
      }
    }
    public void VisitNamedExpression_RevisitingTerminatesAfterInnerChanges_WithoutOuterChanges ()
    {
      var innerExpression = Expression.Constant (0);
      var namedExpression = new NamedExpression ("Name", innerExpression);

      var fakeResolvedInnerExpression = new SqlLiteralExpression (1);
      _resolverMock.Expect (mock => mock.ResolveConstantExpression (innerExpression)).Return (fakeResolvedInnerExpression);

      _namedExpressionCombinerMock
          .Expect (mock => mock.ProcessNames (Arg<NamedExpression>.Is.Anything))
          .Return (null)
          .WhenCalled (mi => mi.ReturnValue = mi.Arguments[0]);

      // No revisiting

      var result = _visitor.VisitExpression (namedExpression);

      _resolverMock.VerifyAllExpectations ();
      _namedExpressionCombinerMock.VerifyAllExpectations ();

      Assert.That (result, Is.TypeOf<NamedExpression> ());
      Assert.That (((NamedExpression) result).Name, Is.EqualTo ("Name"));
      Assert.That (((NamedExpression) result).Expression, Is.SameAs (fakeResolvedInnerExpression));
    }
    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 ProcessNames_SqlGroupingSelectExpression ()
    {
      var keyExpression = new NamedExpression ("key", Expression.Constant ("key"));
      var elementExpression = new NamedExpression ("element", Expression.Constant ("element"));
      var aggregationExpression = new NamedExpression ("a0", Expression.Constant ("aggregation"));
      var groupingSelectExpression = new SqlGroupingSelectExpression (keyExpression, elementExpression, new[]{aggregationExpression});
      var expression = new NamedExpression ("outer", groupingSelectExpression);
      var sqlTable = SqlStatementModelObjectMother.CreateSqlTable (typeof (Cook));
      _context.AddGroupReferenceMapping (groupingSelectExpression, sqlTable);

      var expectedResult = new SqlGroupingSelectExpression (
          new NamedExpression ("outer_key", Expression.Constant ("key")), 
          new NamedExpression ("outer_element", Expression.Constant ("element")),
          new[]{new NamedExpression("outer_a0", Expression.Constant("aggregation"))});

      var result = _namedExpressionCombiner.ProcessNames (expression);

      SqlExpressionTreeComparer.CheckAreEqualTrees (result, expectedResult);
      Assert.That (_context.GetReferencedGroupSource (((SqlGroupingSelectExpression) result)), Is.SameAs (sqlTable));
    }
    public void ProcessNames_MethodCallExpression_NoObject ()
    {
      var argument = ExpressionHelper.CreateExpression (typeof (string));
      var expression = Expression.Call (
          ReflectionUtility.GetMethod (() => int.Parse ("arg")),
          argument);
      var namedExpression = new NamedExpression ("test", expression);

      var result = _namedExpressionCombiner.ProcessNames (namedExpression);

      Assert.That (result, Is.AssignableTo (typeof (MethodCallExpression)));
      Assert.That (((MethodCallExpression) result).Arguments.Count, Is.EqualTo (1));
      Assert.That (((MethodCallExpression) result).Object, Is.Null);
    }
    public Expression VisitNamedExpression (NamedExpression expression)
    {
      var newInnerExpression = VisitExpression (expression.Expression);
      if (newInnerExpression is SqlConvertedBooleanExpression)
      {
        var convertedBooleanExpression = (SqlConvertedBooleanExpression) newInnerExpression;
        var innerNamedExpression = new NamedExpression (expression.Name, convertedBooleanExpression.Expression);
        return VisitExpression (new SqlConvertedBooleanExpression (innerNamedExpression));
      }

      if (newInnerExpression != expression.Expression)
        return new NamedExpression (expression.Name, newInnerExpression);

      return expression;
    }
    public Expression VisitNamedExpression (NamedExpression expression)
    {
      ArgumentUtility.CheckNotNull ("expression", expression);

      var baseVisitedExpression =  (NamedExpression) VisitExtensionExpression (expression);

      var result = _namedExpressionCombiner.ProcessNames (baseVisitedExpression);

      if (result != baseVisitedExpression)
        return VisitExpression (result);
      
      return baseVisitedExpression;
    }
    public void ProcessNames_ConvertChecked ()
    {
      var namedExpression = new NamedExpression (
          "outer", 
          Expression.ConvertChecked (new NamedExpression ("inner", Expression.Constant (1)), 
          typeof (double)));

      var result = _namedExpressionCombiner.ProcessNames (namedExpression);

      var expectedResult = Expression.ConvertChecked (new NamedExpression ("outer_inner", Expression.Constant (1)), typeof (double));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }
    public void CreateNewExpressionWithNamedArguments_ArgumentsAlreadyNamedCorrectly_WithGetters ()
    {
      var innerExpression = new NamedExpression ("A", Expression.Constant (0));
      var memberInfo = (MemberInfo) typeof (TypeForNewExpression).GetProperty ("A").GetGetMethod();
      var expression = Expression.New (TypeForNewExpression.GetConstructor (typeof (int)), new[] { innerExpression }, memberInfo);

      var result = NamedExpression.CreateNewExpressionWithNamedArguments (expression);

      Assert.That (result, Is.SameAs (expression));
    }
    public void CreateNewExpressionWithNamedArguments_ArgumentsAlreadyNamedCorrectly ()
    {
      var innerExpression = new NamedExpression("m0", Expression.Constant (0));
      var expression = Expression.New (TypeForNewExpression.GetConstructor (typeof (int)), new[] { innerExpression });

      var result = NamedExpression.CreateNewExpressionWithNamedArguments (expression);

      Assert.That (result, Is.SameAs (expression));
    }
    public void ResolvePotentialEntity_NamedExpression_WithNoEntity_IsLeftUnchanged ()
    {
      var namedExpression = new NamedExpression ("X", Expression.Constant (0));

      var result = _entityIdentityResolver.ResolvePotentialEntity (namedExpression);

      Assert.That (result, Is.SameAs (namedExpression));
    }
    public Expression ProcessNames (NamedExpression outerExpression)
    {
      ArgumentUtility.CheckNotNull ("outerExpression", outerExpression);

      // We cannot implement this as an expression visitor because expression visitors have no fallback case, i.e., there is no good possibility
      // to catch all cases not explicitly handled by a visitor. We need that catch-all case, however, and don't want to automatically visit the
      // expressions' children.

      if (outerExpression.Expression is NewExpression)
      {
        var newExpression = (NewExpression) outerExpression.Expression;
        var preparedArguments = newExpression.Arguments.Select (expr => ProcessNames (new NamedExpression (outerExpression.Name, expr)));

        if (newExpression.Members != null && newExpression.Members.Count>0)
          return Expression.New (newExpression.Constructor, preparedArguments, newExpression.Members);
        else
          return Expression.New (newExpression.Constructor, preparedArguments);
      }
      else if (outerExpression.Expression is MethodCallExpression)
      {
        var methodCallExpression = (MethodCallExpression) outerExpression.Expression;
        var namedInstance = methodCallExpression.Object != null ? new NamedExpression (outerExpression.Name, methodCallExpression.Object) : null;
        var namedArguments = methodCallExpression.Arguments.Select ((a, i) => new NamedExpression (outerExpression.Name, a));
        return Expression.Call (
            namedInstance != null ? ProcessNames (namedInstance) : null,
            methodCallExpression.Method,
            namedArguments.Select (ProcessNames));
      }
      else if (outerExpression.Expression is SqlEntityExpression)
      {
        var entityExpression = (SqlEntityExpression) outerExpression.Expression;
        string newName = CombineNames (outerExpression.Name, entityExpression.Name);

        return _mappingResolutionContext.UpdateEntityAndAddMapping (entityExpression, entityExpression.Type, entityExpression.TableAlias, newName);
      }
      else if (outerExpression.Expression is NamedExpression)
      {
        var namedExpression = (NamedExpression) outerExpression.Expression;
        var newName = CombineNames (outerExpression.Name, namedExpression.Name);
        return ProcessNames (new NamedExpression (newName, namedExpression.Expression));
      }
      else if (outerExpression.Expression is SqlGroupingSelectExpression)
      {
        var groupingSelectExpression = (SqlGroupingSelectExpression) outerExpression.Expression;
        var newKeyExpression = ProcessNames (new NamedExpression (outerExpression.Name, groupingSelectExpression.KeyExpression));
        var newElementExpression = ProcessNames (new NamedExpression (outerExpression.Name, groupingSelectExpression.ElementExpression));
        var newAggregationExpressions =
            groupingSelectExpression.AggregationExpressions.Select (e => ProcessNames (new NamedExpression (outerExpression.Name, e)));
        return _mappingResolutionContext.UpdateGroupingSelectAndAddMapping (
            groupingSelectExpression, newKeyExpression, newElementExpression, newAggregationExpressions);
      }
      else if (outerExpression.Expression.NodeType == ExpressionType.Convert || outerExpression.Expression.NodeType == ExpressionType.ConvertChecked)
      {
        var unaryExpression = (UnaryExpression) outerExpression.Expression;
        var innerNamedExpression = new NamedExpression (outerExpression.Name, unaryExpression.Operand);
        return Expression.MakeUnary (
            unaryExpression.NodeType, 
            ProcessNames (innerNamedExpression), 
            unaryExpression.Type, 
            unaryExpression.Method);
      }
      else
        return outerExpression;
    }
    public void ProcessNames_SqlEntityExpression ()
    {
      var entityExpression = SqlStatementModelObjectMother.CreateSqlEntityDefinitionExpression (typeof (Cook), "test2");
      var namedExpression = new NamedExpression ("test", entityExpression);

      var tableRegisteredForEntity = SqlStatementModelObjectMother.CreateSqlTable ();
      _context.AddSqlEntityMapping (entityExpression, tableRegisteredForEntity);

      var result = _namedExpressionCombiner.ProcessNames (namedExpression);

      Assert.That (result, Is.Not.SameAs (namedExpression));
      Assert.That (result, Is.TypeOf (typeof (SqlEntityDefinitionExpression)));
      Assert.That (((SqlEntityDefinitionExpression) result).Name, Is.EqualTo ("test_test2"));
      Assert.That (_context.GetSqlTableForEntityExpression ((SqlEntityExpression) result), Is.SameAs (tableRegisteredForEntity));
    }
    public void CreateNewExpressionWithNamedArguments_ArgumentsAlreadyNamedWithDifferentName ()
    {
      var innerExpression = new NamedExpression ("test", Expression.Constant (0));
      var expression = Expression.New (TypeForNewExpression.GetConstructor (typeof (int)), new[] { innerExpression });

      var result = NamedExpression.CreateNewExpressionWithNamedArguments (expression);

      var expectedResult = Expression.New (
           TypeForNewExpression.GetConstructor (typeof (int)), new[] { new NamedExpression ("m0", innerExpression) });

      Assert.That (result, Is.Not.SameAs (expression));
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }
    public void ProcessNames_MethodCallExpression_NamedExpressionsInsideArgumentsCombined ()
    {
      var instance = ExpressionHelper.CreateExpression (typeof (int));
      var argument = ExpressionHelper.CreateExpression (typeof (string));
      var expression = Expression.Call (
          new NamedExpression ("inner", instance),
          ReflectionUtility.GetMethod (() => 5.ToString ("arg")),
          new NamedExpression ("inner", argument));
      var namedExpression = new NamedExpression ("outer", expression);

      var result = _namedExpressionCombiner.ProcessNames (namedExpression);

      Assert.That (result, Is.AssignableTo (typeof (MethodCallExpression)));
      Assert.That (((MethodCallExpression) result).Arguments.Count, Is.EqualTo (1));
      
      Assert.That (((MethodCallExpression) result).Arguments[0], Is.TypeOf (typeof (NamedExpression)));
      Assert.That (((NamedExpression) ((MethodCallExpression) result).Arguments[0]).Name, Is.EqualTo ("outer_inner"));
      Assert.That (((NamedExpression) ((MethodCallExpression) result).Arguments[0]).Expression, Is.SameAs (argument));
 
      Assert.That (((MethodCallExpression) result).Object, Is.TypeOf (typeof (NamedExpression)));
      Assert.That (((NamedExpression) ((MethodCallExpression) result).Object).Name, Is.EqualTo ("outer_inner"));
      Assert.That (((NamedExpression) ((MethodCallExpression) result).Object).Expression, Is.SameAs (instance));
    }
 public void SetUp ()
 {
   _wrappedExpression = Expression.Constant (1);
   _namedExpression = new NamedExpression ("test", _wrappedExpression);
 }
    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 VisitNamedExpression ()
    {
      var innerExpression = Expression.Constant (0);
      var namedExpression = new NamedExpression ("Name", innerExpression);

      var fakeResolvedInnerExpression = new SqlLiteralExpression (1);
      _resolverMock.Expect (mock => mock.ResolveConstantExpression (innerExpression)).Return (fakeResolvedInnerExpression);

      var fakeCombinedExpression = new NamedExpression ("Name2", Expression.Constant (2));
      _namedExpressionCombinerMock
          .Expect (mock => mock.ProcessNames (Arg<NamedExpression>.Matches (e => e.Name == "Name" && e.Expression == fakeResolvedInnerExpression)))
          .Return (fakeCombinedExpression);

      // Result is revisited.
      var fakeResolvedInnerExpression2 = new SqlLiteralExpression (3);
      _resolverMock
          .Expect (mock => mock.ResolveConstantExpression ((ConstantExpression) fakeCombinedExpression.Expression))
          .Return (fakeResolvedInnerExpression2);
      _namedExpressionCombinerMock
          .Expect (mock => mock.ProcessNames (Arg<NamedExpression>.Matches (e => e.Name == "Name2" && e.Expression == fakeResolvedInnerExpression2)))
          .Return (null)
          .WhenCalled (mi => mi.ReturnValue = mi.Arguments[0]);

      var result = _visitor.VisitExpression (namedExpression);

      _resolverMock.VerifyAllExpectations ();
      _namedExpressionCombinerMock.VerifyAllExpectations ();

      Assert.That (result, Is.TypeOf<NamedExpression> ());
      Assert.That (((NamedExpression) result).Name, Is.EqualTo ("Name2"));
      Assert.That (((NamedExpression) result).Expression, Is.SameAs (fakeResolvedInnerExpression2));
    }
    public void ProcessNames_Convert_WithMethod ()
    {
      var convertMethod = typeof (Convert).GetMethod ("ToDouble", new[] { typeof (int) });
      var namedExpression = new NamedExpression (
          "outer", 
          Expression.Convert (
              new NamedExpression (
                  "inner", 
                  Expression.Constant (1)), 
              typeof (double), 
              convertMethod));

      var result = _namedExpressionCombiner.ProcessNames (namedExpression);

      var expectedResult = Expression.Convert (new NamedExpression ("outer_inner", Expression.Constant (1)), typeof (double), convertMethod);
      SqlExpressionTreeComparer.CheckAreEqualTrees (expectedResult, result);
    }