```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 (no_data)
        {
            LOG_DEBUG(log, "Sampling yields no data.");
            return std::make_unique<QueryPlan>();
        }
    }
    MergeTreeReaderSettings reader_settings =
    {
        .min_bytes_to_use_direct_io = settings.min_bytes_to_use_direct_io,
        .min_bytes_to_use_mmap_io = settings.min_bytes_to_use_mmap_io,
        .mmap_cache = context->getMMappedFileCache(),
        .max_read_buffer_size = settings.max_read_buffer_size,
        .save_marks_in_cache = true,
        .checksum_on_read = settings.checksum_on_read,
    };
    RangesInDataParts parts_with_ranges(parts.size());
    size_t sum_marks = 0;
    size_t sum_ranges = 0;
    
    if (!use_cache)
    {
        struct DataSkippingIndexAndCondition
        {
            MergeTreeIndexPtr index;
            MergeTreeIndexConditionPtr condition;
            std::atomic<size_t> total_granules{0};
            std::atomic<size_t> granules_dropped{0};
            std::atomic<size_t> total_parts{0};
            std::atomic<size_t> parts_dropped{0};
            DataSkippingIndexAndCondition(MergeTreeIndexPtr index_, MergeTreeIndexConditionPtr condition_)