protected override Expression VisitSelect(SqlSelectExpression select)
            {
                var savedIsTopLevel = this.isTopLevel;

                this.isTopLevel = false;

                select = (SqlSelectExpression)base.VisitSelect(select);

                // Attempt to merge subqueries that would have been removed by the above
                // logic except for the existence of a where clause

                while (CanMergeWithFrom(select))
                {
                    var fromSelect = select.From.GetLeftMostSelect();

                    CanMergeWithFrom(select);

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

                    // merge where expressions
                    var where = select.Where;

                    if (fromSelect.Where != null)
                    {
                        if (where != null)
                        {
                            where = Expression.And(fromSelect.Where, where);
                        }
                        else
                        {
                            where = fromSelect.Where;
                        }
                    }

                    var orderBy    = select.OrderBy != null && select.OrderBy.Count > 0 ? select.OrderBy : fromSelect.OrderBy;
                    var groupBy    = select.GroupBy != null && select.GroupBy.Count > 0 ? select.GroupBy : fromSelect.GroupBy;
                    var skip       = select.Skip ?? fromSelect.Skip;
                    var take       = select.Take ?? fromSelect.Take;
                    var isDistinct = select.Distinct || fromSelect.Distinct;

                    if (where != select.Where || orderBy != select.OrderBy || groupBy != select.GroupBy || isDistinct != select.Distinct || skip != select.Skip || take != select.Take)
                    {
                        select = new SqlSelectExpression(select.Type, select.Alias, select.Columns, select.From, where, orderBy, groupBy, isDistinct, skip, take, select.ForUpdate);
                    }
                }

                this.isTopLevel = savedIsTopLevel;

                return(select);
            }
        protected override Expression VisitSelect(SqlSelectExpression select)
        {
            select = (SqlSelectExpression)base.VisitSelect(select);

            // Expand all purely redundant subqueries

            var redundantQueries = SqlRedundantSubqueryFinder.Find(select.From);

            if (redundantQueries != null)
            {
                select = SqlSubqueryRemover.Remove(select, redundantQueries);
            }

            return(select);
        }
        protected override Expression VisitProjection(SqlProjectionExpression projection)
        {
            projection = (SqlProjectionExpression)base.VisitProjection(projection);

            if (projection.Select.From is SqlSelectExpression)
            {
                var redundantQueries = SqlRedundantSubqueryFinder.Find(projection.Select);

                if (redundantQueries != null)
                {
                    projection = SqlSubqueryRemover.Remove(projection, redundantQueries);
                }
            }

            return(projection);
        }