**Describe the situation**
hasAll() filter condition not relying on bloom filter, but re-writing as series of has() AND has()... (or series of indexOf conditions) does use bloom filter 

**How to reproduce**
* ClickHouse server version: 21.2.7.2

Test Table: 
- 33M records, 10 columns
- MergeTree() engine, has a sort order specified
- Has a field STRING_ARRAY that is a Array(String) column. It has a bloom filter data-skipping index (`TYPE bloom_filter(0.01) GRANULARITY 1`)

The following query takes 1.5 seconds: 
```
SELECT * FROM db_name.table_name
WHERE hasAll(STRING_ARRAY, ['value_1', 'value_2', 'value_3']
```
Running `EXPLAIN indexes = 1`, only the primary key is picked up. The bloom filter isn't used. 

The following query takes 0.45 seconds: 
```
SELECT * FROM db_name.table_name
WHERE has(STRING_ARRAY, 'value_1') AND has(STRING_ARRAY, 'value_2') AND has(STRING_ARRAY, 'value_3')
```
Running `EXPLAIN indexes = 1`, the bloom filter is used. 

**Expected performance**
Expecting the hasAll() filter condition to also get performance improvement from the bloom filter on STRING_ARRAY. 

Function function = FUNCTION_UNKNOWN;
        std::vector<std::pair<size_t, ColumnPtr>> predicate;
    };
    MergeTreeIndexConditionBloomFilter(const SelectQueryInfo & info_, ContextPtr context_, const Block & header_, size_t hash_functions_);
    bool alwaysUnknownOrTrue() const override;
    bool mayBeTrueOnGranule(MergeTreeIndexGranulePtr granule) const override
    {
        if (const auto & bf_granule = typeid_cast<const MergeTreeIndexGranuleBloomFilter *>(granule.get()))
            return mayBeTrueOnGranule(bf_granule);
        throw Exception("LOGICAL ERROR: require bloom filter index granule.", ErrorCodes::LOGICAL_ERROR);
    }
private:
    const Block & header;
    const SelectQueryInfo & query_info;
    const size_t hash_functions;
    std::vector<RPNElement> rpn;
    SetPtr getPreparedSet(const ASTPtr & node);
    bool mayBeTrueOnGranule(const MergeTreeIndexGranuleBloomFilter * granule) const;
    bool traverseAtomAST(const ASTPtr & node, Block & block_with_constants, RPNElement & out);
    bool traverseFunction(const ASTPtr & node, Block & block_with_constants, RPNElement & out, const ASTPtr & parent);
    bool traverseASTIn(const String & function_name, const ASTPtr & key_ast, const SetPtr & prepared_set, RPNElement & out);
    bool traverseASTIn(
        const String & function_name, const ASTPtr & key_ast, const DataTypePtr & type, const ColumnPtr & column, RPNElement & out);
    bool traverseASTEquals(
        const String & function_name, const ASTPtr & key_ast, const DataTypePtr & value_type, const Field & value_field, RPNElement & out, const ASTPtr & parent);
};
}