public void ResolvePotentialEntity_Substatement_WithEntity_ResolvesToSubstatement_WithIdentity()
        {
            var subStatement           = SqlStatementModelObjectMother.CreateSqlStatement(_entityExpression, SqlStatementModelObjectMother.CreateSqlTable());
            var subStatementExpression = new SqlSubStatementExpression(subStatement);

            var result = _entityIdentityResolver.ResolvePotentialEntity(subStatementExpression);

            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>)));
        }
Example #2
0
        public void VisitSqlSubStatmentExpression_NoTopExpression_ReturnsSame()
        {
            var builder = new SqlStatementBuilder(SqlStatementModelObjectMother.CreateSqlStatementWithCook());

            builder.Orderings.Clear();
            var sqlStatement = builder.GetSqlStatement();

            var subStatementExpression = new SqlSubStatementExpression(sqlStatement);

            var result = SqlPreparationExpressionVisitor.TranslateExpression(subStatementExpression, _context, _stageMock, _methodCallTransformerProvider);

            Assert.That(result, Is.SameAs(subStatementExpression));
        }
        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));
        }
Example #4
0
        public void VisitSqlSubStatementExpression_ConvertsToSqlTable_ForStreamedSingleValueInfo()
        {
            var sqlStatement             = SqlStatementModelObjectMother.CreateSqlStatement_Single();
            var fakeResolvedSqlStatement = SqlStatementModelObjectMother.CreateSqlStatement_Single();
            var expression = new SqlSubStatementExpression(sqlStatement);

            var      resolvedReference = Expression.Constant("fake");
            SqlTable sqlTable          = null;

            _stageMock
            .Expect(mock => mock.ResolveSqlStatement(sqlStatement, _mappingResolutionContext))
            .Return(fakeResolvedSqlStatement);
            _groupAggregateSimplifier
            .Expect(
                mock => mock.SimplifyIfPossible(
                    Arg <SqlSubStatementExpression> .Matches(e => e.SqlStatement == fakeResolvedSqlStatement), Arg.Is(sqlStatement.SelectProjection)))
            .Return(null)
            .WhenCalled(mi => mi.ReturnValue = mi.Arguments[0]);
            _stageMock
            .Expect(mock => mock.ResolveTableReferenceExpression(Arg <SqlTableReferenceExpression> .Is.Anything, Arg.Is(_mappingResolutionContext)))
            .WhenCalled(
                mi =>
            {
                var expectedStatement =
                    new SqlStatementBuilder(fakeResolvedSqlStatement)
                {
                    DataInfo = new StreamedSequenceInfo(typeof(IEnumerable <int>), fakeResolvedSqlStatement.SelectProjection)
                }.GetSqlStatement();
                sqlTable = (SqlTable)((SqlTableReferenceExpression)mi.Arguments[0]).SqlTable;
                Assert.That(((ResolvedSubStatementTableInfo)sqlTable.TableInfo).SqlStatement, Is.EqualTo(expectedStatement));
            })
            .Return(resolvedReference);

            _resolverMock.Expect(mock => mock.ResolveConstantExpression(resolvedReference)).Return(resolvedReference);

            var sqlStatementBuilder = new SqlStatementBuilder(sqlStatement);
            var visitor             = CreateVisitor(sqlStatementBuilder);

            Assert.That(sqlStatementBuilder.SqlTables.Count, Is.EqualTo(0));

            var result = visitor.VisitExpression(expression);

            _stageMock.VerifyAllExpectations();
            _groupAggregateSimplifier.VerifyAllExpectations();
            _resolverMock.VerifyAllExpectations();

            Assert.That(result, Is.SameAs(resolvedReference));
            Assert.That(sqlStatementBuilder.SqlTables.Count, Is.EqualTo(1));
            Assert.That(sqlStatementBuilder.SqlTables[0], Is.EqualTo(sqlTable));
        }
        public void VisitQuerySourceReferenceExpression_WithOrderings_AndDoNotExtractOrdingsPolicy()
        {
            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 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.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();

            var visitor = CreateTestableVisitor(OrderingExtractionPolicy.DoNotExtractOrderings);

            visitor.VisitQuerySourceReference(querySourceReferenceExpression);

            _stageMock.VerifyAllExpectations();

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

            Assert.That(fromExpressionInfo.ExtractedOrderings, Is.Empty);
        }
        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 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));
        }
Example #8
0
        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();
        }
Example #9
0
        public override void HandleResultOperator(AnyResultOperator resultOperator, SqlStatementBuilder sqlStatementBuilder, UniqueIdentifierGenerator generator, ISqlPreparationStage stage, ISqlPreparationContext context)
        {
            ArgumentUtility.CheckNotNull("resultOperator", resultOperator);
            ArgumentUtility.CheckNotNull("sqlStatementBuilder", sqlStatementBuilder);
            ArgumentUtility.CheckNotNull("generator", generator);
            ArgumentUtility.CheckNotNull("stage", stage);
            ArgumentUtility.CheckNotNull("context", context);

            // No name required for the select projection inside of an EXISTS expression
            var sqlSubStatement        = sqlStatementBuilder.GetStatementAndResetBuilder();
            var subStatementExpression = new SqlSubStatementExpression(sqlSubStatement);

            var sqlExistsExpression = new SqlExistsExpression(subStatementExpression);

            sqlStatementBuilder.SelectProjection = stage.PrepareSelectExpression(sqlExistsExpression, context);
            UpdateDataInfo(resultOperator, sqlStatementBuilder, sqlSubStatement.DataInfo);
        }
Example #10
0
        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_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.Visit(expression);

            _stageMock.VerifyAllExpectations();
            _groupAggregateSimplifierMock.VerifyAllExpectations();
            Assert.That(result, Is.SameAs(expression));
        }
Example #12
0
        public void VisitSqlSubStatmentExpression_HasTopExpression_ReturnsNew()
        {
            var builder = new SqlStatementBuilder(SqlStatementModelObjectMother.CreateSqlStatementWithCook());

            builder.Orderings.Add(new Ordering(Expression.Constant("order"), OrderingDirection.Asc));
            var sqlStatement = builder.GetSqlStatement();

            builder.Orderings.Clear();
            var expectedStatement = builder.GetSqlStatement();

            var subStatementExpression = new SqlSubStatementExpression(sqlStatement);

            var result = SqlPreparationExpressionVisitor.TranslateExpression(subStatementExpression, _context, _stageMock, _methodCallTransformerProvider);

            Assert.That(result, Is.Not.SameAs(subStatementExpression));
            Assert.That(result, Is.TypeOf(typeof(SqlSubStatementExpression)));
            Assert.That(((SqlSubStatementExpression)result).SqlStatement, Is.EqualTo(expectedStatement));
        }
Example #13
0
        public override Expression VisitSqlSubStatement(SqlSubStatementExpression expression)
        {
            var newExpression = base.VisitSqlSubStatement(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(Visit(sqlTableReferenceExpression));
            }
            return(newExpression);
        }
Example #14
0
        public void HandleResultOperator_TransformSubqueriesUsedAsGroupByKeys()
        {
            var keySelector     = Expression.Constant("keySelector");
            var elementSelector = Expression.Constant("elementSelector");
            var resultOperator  = new GroupResultOperator("itemName", keySelector, elementSelector);

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

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

            _stageMock.Replay();

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

            _stageMock.VerifyAllExpectations();

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

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

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

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

            SqlExpressionTreeComparer.CheckAreEqualTrees(_sqlStatementBuilder.GroupByExpression, expectedGroupGyExpression);
            SqlExpressionTreeComparer.CheckAreEqualTrees(
                _sqlStatementBuilder.SelectProjection,
                SqlGroupingSelectExpression.CreateWithNames(expectedGroupGyExpression, elementSelector));
        }
        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.Visit(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 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 VisitSqlSubStatementExpression()
        {
            var sqlStatement = new SqlStatementBuilder(SqlStatementModelObjectMother.CreateSqlStatementWithCook())
            {
                SelectProjection = new NamedExpression("test", Expression.Constant("test"))
            }.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)));
        }
Example #18
0
        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();
        }
Example #19
0
        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 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,
                _tableGenerator,
                _someOrderingExtractionPolicy);

            Assert.That(result.SqlTable.TableInfo, Is.InstanceOf(typeof(ResolvedSubStatementTableInfo)));
        }
        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 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));
        }
        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 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 VisitSqlSubStatementExpression_WithDoNotExtractOrderingsPolicy()
        {
            var sqlStatement = new SqlStatementBuilder(SqlStatementModelObjectMother.CreateSqlStatementWithCook())
            {
                SelectProjection = new NamedExpression("test", Expression.Constant("test")),
                Orderings        = { SqlStatementModelObjectMother.CreateOrdering() }
            }.GetSqlStatement();

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

            var result = SqlPreparationFromExpressionVisitor.AnalyzeFromExpression(
                sqlSubStatementExpression,
                stage,
                _generator,
                _methodCallTransformerProvider,
                _context,
                _tableGenerator,
                OrderingExtractionPolicy.DoNotExtractOrderings);

            Assert.That(result.SqlTable.TableInfo, Is.InstanceOf(typeof(ResolvedSubStatementTableInfo)));
            Assert.That(((ResolvedSubStatementTableInfo)result.SqlTable.TableInfo).SqlStatement.Orderings.Count, Is.EqualTo(0));
            Assert.That(result.ExtractedOrderings, Is.Empty);
        }
 public void SetUp()
 {
     _sqlStatement = SqlStatementModelObjectMother.CreateSqlStatement();
     _expression   = new SqlSubStatementExpression(_sqlStatement);
 }
        public void VisitQuerySourceReferenceExpression_WithOrderings_AndExtractOrdingsPolicy()
        {
            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();

            var visitor = CreateTestableVisitor(OrderingExtractionPolicy.ExtractOrderingsIntoProjection);

            visitor.VisitQuerySourceReference(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")));
        }