Repository: ClickHouse/ClickHouse
File: src/Functions/FunctionsStringDistance.cpp (C++)

Code before:
            while (haystack < haystack_end)
            {
                scratch.haystack_set[static_cast<unsigned char>(*haystack)] = 1;
                ++haystack;
            }
            while (needle < needle_end)
            {
                scratch.needle_set[static_cast<unsigned char>(*needle)] = 1;
                ++needle;
            }
        }

        using CalcType = typename ScratchType::CalcType;

        CalcType intersection = 0;
        CalcType union_size = 0;

        if constexpr (is_utf8)
        {
            const auto & small = (scratch.haystack_utf8_set.size() < scratch.needle_utf8_set.size()) ? scratch.haystack_utf8_set : scratch.needle_utf8_set;
            const auto & large = (scratch.haystack_utf8_set.size() < scratch.needle_utf8_set.size()) ? scratch.needle_utf8_set : scratch.haystack_utf8_set;

            for (auto it = small.begin(); it != small.end(); ++it)
            {
                const auto & key = it->getKey();
                if (large.has(key))
                    ++intersection;
            }
            union_size = static_cast<UInt32>(scratch.haystack_utf8_set.size() + scratch.needle_utf8_set.size() - intersection);
        }
        else
        {
            for (size_t i = 0; i < ScratchType::max_size; ++i)
            {
                intersection += (scratch.haystack_set[i] & scratch.needle_set[i]);
                union_size += (scratch.haystack_set[i] | scratch.needle_set[i]);
            }
        }

        return static_cast<ResultType>(intersection) / static_cast<ResultType>(union_size);
    }
};

static constexpr size_t max_string_size = 1u << 16;

template<bool is_utf8>
struct ByteEditDistanceImpl
{
    using ResultType = UInt64;

    static ResultType process(

Review comment (bug):
Potential integer overflow: if both sets are large, the sum could exceed `UInt32::max()` before subtracting intersection. Consider using a wider integer type (e.g., `size_t` or `UInt64`) for intermediate calculations to prevent overflow, especially since the result is cast to `ResultType` (Float64) anyway.
```suggestion
            const size_t haystack_set_size = static_cast<size_t>(scratch.haystack_utf8_set.size());
            const size_t needle_set_size = static_cast<size_t>(scratch.needle_utf8_set.size());
            const size_t union_size_wide = haystack_set_size + needle_set_size - static_cast<size_t>(intersection);
            union_size = static_cast<CalcType>(union_size_wide);
```

Code after:
                ++haystack;
            }
            while (needle < needle_end)
            {
                scratch.needle_set[static_cast<unsigned char>(*needle)] = 1;
                ++needle;
            }
        }

        using CalcType = typename ScratchType::CalcType;

        CalcType intersection = 0;
        CalcType union_size = 0;

        if constexpr (is_utf8)
        {
            const auto & small = (scratch.haystack_utf8_set.size() < scratch.needle_utf8_set.size()) ? scratch.haystack_utf8_set : scratch.needle_utf8_set;
            const auto & large = (scratch.haystack_utf8_set.size() < scratch.needle_utf8_set.size()) ? scratch.needle_utf8_set : scratch.haystack_utf8_set;

            for (auto it = small.begin(); it != small.end(); ++it)
            {
                const auto & key = it->getKey();
                if (large.has(key))
                    ++intersection;
            }
            union_size = static_cast<UInt32>(scratch.haystack_utf8_set.size() + scratch.needle_utf8_set.size() - intersection);
        }
        else
        {
            for (size_t i = 0; i < ScratchType::max_size; ++i)
            {
                intersection += (scratch.haystack_set[i] & scratch.needle_set[i]);
                union_size += (scratch.haystack_set[i] | scratch.needle_set[i]);
            }
        }

        return static_cast<ResultType>(intersection) / static_cast<ResultType>(union_size);
    }
};

static constexpr size_t max_string_size = 1u << 16;

template<bool is_utf8>
struct ByteEditDistanceImpl
{
    using ResultType = UInt64;

    static ResultType process(
        const char * __restrict haystack, size_t haystack_size, const char * __restrict needle, size_t needle_size)
    {
        if (haystack_size == 0 || needle_size == 0)