public void HandleResultOperator_OrderingsWithTopInMainSqlStatement_ShouldBeMovedToSubStatement_WithoutAffectingProjectionOrOuterOrderings()
        {
            var originalOrdering = SqlStatementModelObjectMother.CreateOrdering();

            _sqlStatementBuilder.Orderings.Add(originalOrdering);
            _sqlStatementBuilder.TopExpression = ExpressionHelper.CreateExpression();
            var originalSelectProjection = _sqlStatementBuilder.SelectProjection;

            var resultOperator = CreateValidResultOperator();

            var stage = CreateDefaultSqlPreparationStage();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, UniqueIdentifierGenerator, stage, _context);

            AssertStatementWasMovedToSubStatement(_sqlStatementBuilder);

            // Statement was moved to substatement as is, without affecting select projection (apart from NamedExpression)
            // and leaving the orderings in place.
            var subStatement = ((ResolvedSubStatementTableInfo)_sqlStatementBuilder.SqlTables[0].TableInfo).SqlStatement;

            Assert.That(((NamedExpression)subStatement.SelectProjection).Expression, Is.SameAs(originalSelectProjection));
            Assert.That(subStatement.Orderings, Is.EqualTo(new[] { originalOrdering }));

            // Outer statement has no orderings.
            Assert.That(_sqlStatementBuilder.Orderings, Is.Empty);
        }
        public void HandleResultOperator_OrderingsWithTopInSource2_CausesMainStatementToBeMovedToSubStatement()
        {
            var sqlStatement = SqlStatementModelObjectMother.CreateMinimalSqlStatement(new SqlStatementBuilder
            {
                Orderings     = { SqlStatementModelObjectMother.CreateOrdering() },
                TopExpression = Expression.Constant(10)
            });
            var resultOperator = new UnionResultOperator("x", typeof(int), new SqlSubStatementExpression(sqlStatement));

            var stage = CreateDefaultSqlPreparationStage();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, UniqueIdentifierGenerator, stage, _context);

            AssertStatementWasMovedToSubStatement(_sqlStatementBuilder);
        }
        public void HandleResultOperator_OrderingsWithoutTopInMainSqlStatement_ShouldBeRemoved()
        {
            _sqlStatementBuilder.Orderings.Add(SqlStatementModelObjectMother.CreateOrdering());
            var originalSqlTable = SqlStatementModelObjectMother.CreateSqlTable();

            _sqlStatementBuilder.SqlTables.Add(originalSqlTable);

            var stage = CreateDefaultSqlPreparationStage();

            var resultOperator = CreateValidResultOperator();

            _handler.HandleResultOperator(resultOperator, _sqlStatementBuilder, UniqueIdentifierGenerator, stage, _context);

            Assert.That(_sqlStatementBuilder.Orderings, Is.Empty);
            Assert.That(_sqlStatementBuilder.SqlTables, Is.EqualTo(new[] { originalSqlTable }), "Query was not moved to a substatement.");
        }
        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);
        }