```sql
DROP TABLE IF EXISTS tp;

create table tp (d1 Int32, d2 Int32, eventcnt Int64,
projection p (select sum(eventcnt), d1 group by d1)) 
engine = SummingMergeTree order by (d1, d2);

set allow_experimental_projection_optimization = 1, force_optimize_projection = 1;

select sum(eventcnt) eventcnt, d1
from tp
group by d1;

DB::Exception: No projection is used when allow_experimental_projection_optimization = 1.

```

The exception message is also incorrect, should be "when force_optimize_projection = 1".

if (limits.max_rows || leaf_limits.max_rows)
                    {
                        
                        auto current_rows_estimate = ranges.getRowsCount();
                        size_t prev_total_rows_estimate = total_rows.fetch_add(current_rows_estimate);
                        size_t total_rows_estimate = current_rows_estimate + prev_total_rows_estimate;
                        limits.check(total_rows_estimate, 0, "rows (controlled by 'max_rows_to_read' setting)", ErrorCodes::TOO_MANY_ROWS);
                        leaf_limits.check(
                            total_rows_estimate, 0, "rows (controlled by 'max_rows_to_read_leaf' setting)", ErrorCodes::TOO_MANY_ROWS);
                    }
                    parts_with_ranges[part_index] = std::move(ranges);
                }
            };
            size_t num_threads = std::min(size_t(num_streams), parts.size());
            if (num_threads <= 1)
            {
                for (size_t part_index = 0; part_index < parts.size(); ++part_index)
                    process_part(part_index);
            }
            else
            {
                
                ThreadPool pool(num_threads);
                for (size_t part_index = 0; part_index < parts.size(); ++part_index)
                    pool.scheduleOrThrowOnError([&, part_index, thread_group = CurrentThread::getGroup()]
                    {
                        SCOPE_EXIT_SAFE(if (thread_group) CurrentThread::detachQueryIfNotDetached(););
                        if (thread_group)
                            CurrentThread::attachTo(thread_group);
                        process_part(part_index);