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

RangesInDataParts && parts,
    ReadFromMergeTree::IndexStatPtr index_stats,
    size_t num_streams,
    const Names & column_names,
    const StorageMetadataPtr & metadata_snapshot,
    UInt64 max_block_size,
    bool use_uncompressed_cache,
    const SelectQueryInfo & query_info,
    const ActionsDAGPtr & sorting_key_prefix_expr,
    const Names & virt_columns,
    const Settings & settings,
    const MergeTreeReaderSettings & reader_settings,
    ActionsDAGPtr & out_projection,
    const String & query_id,
    const InputOrderInfoPtr & input_order_info) const
{
    size_t sum_marks = 0;
    size_t adaptive_parts = 0;
    std::vector<size_t> sum_marks_in_parts(parts.size());
    const auto data_settings = data.getSettings();
    for (size_t i = 0; i < parts.size(); ++i)
    {
        sum_marks_in_parts[i] = parts[i].getMarksCount();
        sum_marks += sum_marks_in_parts[i];
        if (parts[i].data_part->index_granularity_info.is_adaptive)
            ++adaptive_parts;
    }
    size_t index_granularity_bytes = 0;
    if (adaptive_parts > parts.size() / 2)
        index_granularity_bytes = data_settings->index_granularity_bytes;