```
CREATE TABLE t (x UInt8, PROJECTION p (SELECT x GROUP BY x)) ENGINE = MergeTree ORDER BY ();
INSERT INTO t VALUES (0);

SET group_by_overflow_mode = 'any', max_rows_to_group_by = 1000, totals_mode = 'after_having_auto';
SELECT x FROM t GROUP BY x WITH TOTALS;
```
{
    auto res = getDataPartsVectorForInternalUsage({DataPartState::Active, DataPartState::Outdated});
    filterVisibleDataParts(res, snapshot_version, current_tid);
    return res;
}
void MergeTreeData::filterVisibleDataParts(DataPartsVector & maybe_visible_parts, CSN snapshot_version, TransactionID current_tid) const
{
    [[maybe_unused]] size_t total_size = maybe_visible_parts.size();
    auto need_remove_pred = [snapshot_version, &current_tid] (const DataPartPtr & part) -> bool
    {
        return !part->version.isVisible(snapshot_version, current_tid);
    };
    std::erase_if(maybe_visible_parts, need_remove_pred);
    [[maybe_unused]] size_t visible_size = maybe_visible_parts.size();
    LOG_TEST(log, "Got {} parts (of {}) visible in snapshot {} (TID {}): {}",
             visible_size, total_size, snapshot_version, current_tid, fmt::join(getPartsNames(maybe_visible_parts), ", "));
}
std::unordered_set<String> MergeTreeData::getPartitionIDsFromQuery(const ASTs & asts, ContextPtr local_context) const