```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".

const auto & index_name = index_and_condition.index->index.name;
            LOG_DEBUG(
                log,
                "Index {} has dropped {}/{} granules.",
                backQuote(index_name),
                index_and_condition.granules_dropped,
                index_and_condition.total_granules);
            std::string description
                = index_and_condition.index->index.type + " GRANULARITY " + std::to_string(index_and_condition.index->index.granularity);
            index_stats->emplace_back(ReadFromMergeTree::IndexStat{
                .type = ReadFromMergeTree::IndexType::Skip,
                .name = index_name,
                .description = std::move(description),
                .num_parts_after = index_and_condition.total_parts - index_and_condition.parts_dropped,
                .num_granules_after = index_and_condition.total_granules - index_and_condition.granules_dropped});
        }
        LOG_DEBUG(
            log,
            "Selected {}/{} parts by partition key, {} parts by primary key, {}/{} marks by primary key, {} marks to read from {} ranges",
            parts.size(),
            total_parts,
            parts_with_ranges.size(),
            sum_marks_pk.load(std::memory_order_relaxed),
            total_marks_pk.load(std::memory_order_relaxed),
            sum_marks,
            sum_ranges);
    }
    if (cache)
    {
        if (cache->use_cache)