Now it support only `String` and `FixedString`

https://github.com/ClickHouse/ClickHouse/blob/33aefa832b3c544934a757cc9d0e284252a1dd3e/src/Storages/MergeTree/MergeTreeIndexFullText.cpp#L809

Seems that `LowCardinality(String)` can be supported too, because we only use `column->getDataAt` to retrieve data and it will work on `LowCardinality(String)` in same way as for `String`
https://github.com/ClickHouse/ClickHouse/blob/33aefa832b3c544934a757cc9d0e284252a1dd3e/src/Storages/MergeTree/MergeTreeIndexFullText.cpp#L543
https://github.com/ClickHouse/ClickHouse/blob/33aefa832b3c544934a757cc9d0e284252a1dd3e/src/Storages/MergeTree/MergeTreeIndexFullText.cpp#L145
{
    std::shared_ptr<MergeTreeIndexGranuleFullText> granule
            = std::dynamic_pointer_cast<MergeTreeIndexGranuleFullText>(idx_granule);
    if (!granule)
        throw Exception(
                "BloomFilter index condition got a granule with the wrong type.", ErrorCodes::LOGICAL_ERROR);
    
    std::vector<BoolMask> rpn_stack;
    for (const auto & element : rpn)
    {
        if (element.function == RPNElement::FUNCTION_UNKNOWN)
        {
            rpn_stack.emplace_back(true, true);
        }
        else if (element.function == RPNElement::FUNCTION_EQUALS
             || element.function == RPNElement::FUNCTION_NOT_EQUALS
             || element.function == RPNElement::FUNCTION_HAS)
        {
            rpn_stack.emplace_back(granule->bloom_filters[element.key_column].contains(*element.bloom_filter), true);
            if (element.function == RPNElement::FUNCTION_NOT_EQUALS)
                rpn_stack.back() = !rpn_stack.back();
        }
        else if (element.function == RPNElement::FUNCTION_IN
             || element.function == RPNElement::FUNCTION_NOT_IN)
        {
            std::vector<bool> result(element.set_bloom_filters.back().size(), true);
            for (size_t column = 0; column < element.set_key_position.size(); ++column)
            {
                const size_t key_idx = element.set_key_position[column];