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

else if (name == "_sample_factor")
        {
            sample_factor_column_queried = true;
            virt_column_names.push_back(name);
        }
        else
        {
            real_column_names.push_back(name);
        }
    }
    
    std::unordered_set<String> part_values;
    if (!use_cache)
    {
        ASTPtr expression_ast;
        auto virtual_columns_block = data.getBlockWithVirtualPartColumns(parts, true );
        
        VirtualColumnUtils::prepareFilterBlockWithQuery(query_info.query, context, virtual_columns_block, expression_ast);
        
        if (expression_ast)
        {
            virtual_columns_block = data.getBlockWithVirtualPartColumns(parts, false );
            VirtualColumnUtils::filterBlockWithQuery(query_info.query, virtual_columns_block, context, expression_ast);
            part_values = VirtualColumnUtils::extractSingleValueFromBlock<String>(virtual_columns_block, "_part");
            if (part_values.empty())
                return std::make_unique<QueryPlan>();
        }
    }
    
    const Settings & settings = context->getSettingsRef();