protected override Expression VisitProjection(ProjectionExpression proj)
 {
     proj = (ProjectionExpression)base.VisitProjection(proj);
     if (proj.Source.From is SelectExpression)
     {
         List <SelectExpression> redundant = RedundantSubqueryGatherer.Gather(proj.Source, Logger);
         if (redundant != null)
         {
             proj = SubqueryRemover.Remove(proj, redundant, Logger);
         }
     }
     return(proj);
 }
        protected override Expression VisitSelect(SelectExpression select)
        {
            select = (SelectExpression)base.VisitSelect(select);

            // first remove all purely redundant subqueries
            List <SelectExpression> redundant = RedundantSubqueryGatherer.Gather(select.From, Logger);

            if (redundant != null)
            {
                select = SubqueryRemover.Remove(select, redundant, Logger);
            }

            // next attempt to merge subqueries that would have been removed by the above
            // logic except for the existence of a where clause
            while (CanMergeWithFrom(select))
            {
                SelectExpression fromSelect = (SelectExpression)select.From;

                // remove the redundant subquery
                select = SubqueryRemover.Remove(select, Logger, fromSelect);

                // merge where expressions
                Expression where = select.Where;
                if (fromSelect.Where != null)
                {
                    if (where != null)
                    {
                        where = Expression.And(fromSelect.Where, where);
                    }
                    else
                    {
                        where = fromSelect.Where;
                    }
                }
                if (where != select.Where)
                {
                    select = new SelectExpression(select.Type, select.Alias, select.Columns, select.From, where, select.OrderBy, select.GroupBy);
                }
            }

            return(select);
        }