21.5.1.6605

```sql
create table bftest (k Int64, x Array(Int64), index ix1(x) TYPE bloom_filter GRANULARITY 3) 
Engine=MergeTree order by k;

insert into bftest select number, 
    arrayMap(i->rand64()%565656, range(10)) from numbers(10000000);
insert into bftest select number, 
    arrayMap(i->rand64()%565656, range(10)) from numbers(100000000);

###  hasAny(x, [42,-42])
select count() from bftest where hasAny(x, [42,-42]);
Elapsed: 0.909 sec. Processed 110.00 million rows

### has (x, 42) or has(x, -42)
select count() from bftest where has (x, 42) or has(x, -42);
Elapsed: 0.143 sec. Processed 6.55 million rows

```
{
            if (array_type)
                throw Exception("An array type of bloom_filter supports only has() and indexOf() function.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
            out.function = function_name == "equals" ? RPNElement::FUNCTION_EQUALS : RPNElement::FUNCTION_NOT_EQUALS;
            const DataTypePtr actual_type = BloomFilter::getPrimitiveType(index_type);
            Field converted_field = convertFieldToType(value_field, *actual_type, value_type.get());
            out.predicate.emplace_back(std::make_pair(position, BloomFilterHash::hashWithField(actual_type.get(), converted_field)));
        }
        return true;
    }
    if (const auto * function = key_ast->as<ASTFunction>())
    {
        WhichDataType which(value_type);
        if (which.isTuple() && function->name == "tuple")
        {
            const Tuple & tuple = get<const Tuple &>(value_field);
            const auto * value_tuple_data_type = typeid_cast<const DataTypeTuple *>(value_type.get());
            const ASTs & arguments = typeid_cast<const ASTExpressionList &>(*function->arguments).children;
            if (tuple.size() != arguments.size())
                throw Exception("Illegal types of arguments of function " + function_name, ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
            bool match_with_subtype = false;
            const DataTypes & subtypes = value_tuple_data_type->getElements();
            for (size_t index = 0; index < tuple.size(); ++index)
                match_with_subtype |= traverseASTEquals(function_name, arguments[index], subtypes[index], tuple[index], out, key_ast);
            return match_with_subtype;
        }
    }
    return false;
}
SetPtr MergeTreeIndexConditionBloomFilter::getPreparedSet(const ASTPtr & node)