As discussed with @kitaisreal 
const Names & column_names, const NamesAndTypesList & virtuals, const StorageID & storage_id) const
{
    Block res;
    DenseHashMap<StringRef, const DataTypePtr *, StringRefHash> virtuals_map;
    virtuals_map.set_empty_key(StringRef());
    
    
    for (const auto & column : virtuals)
        virtuals_map[column.name] = &column.type;
    for (const auto & name : column_names)
    {
        auto column = getColumns().tryGetColumnOrSubcolumn(ColumnsDescription::All, name);
        if (column)
        {
            res.insert({column->type->createColumn(), column->type, column->name});
        }
        else if (auto it = virtuals_map.find(name); it != virtuals_map.end())
        {
            const auto & type = *it->second;
            res.insert({type->createColumn(), type, name});
        }
        else
            throw Exception(
                "Column " + backQuote(name) + " not found in table " + (storage_id.empty() ? "" : storage_id.getNameForLogs()),
                ErrorCodes::NOT_FOUND_COLUMN_IN_BLOCK);
    }
    return res;
}
const KeyDescription & StorageInMemoryMetadata::getPartitionKey() const