Support for arrays in `startsWith` (and, maybe, `endsWith`)

**Use case**

Would be quite useful for handling tree-like structured data where the node paths are specified as arrays of names or IDs.

**Describe the solution you'd like**

The desired behavior would be like this:
```
startsWith([1, 2, 3, 4], [1, 2])  -- true (1)
startsWith(['qwe', 'rty', 'ui', 'op'], ['qwe', 'rty'])  -- true (1)
startsWith([1, 2, 3, 4], [2, 4])  -- false (0)
startsWith([1, 1, 2, 2], [1, 2])  -- false (0)
```

And similarly, for `endsWith`

**Describe alternatives you've considered**

Something like `arraySlice(first, 1, length(second)) = second`

But `startsWith` would be much more readable, harder to make a mistake in and, probably, can be better optimized (i.e. might not have to create new objects like `arraySlice` does)
{
    const bool has_first_null_map = first_null_map != nullptr;
    const bool has_second_null_map = second_null_map != nullptr;
    for (size_t i = 0; i < second.size; ++i)
    {
        bool has = false;
        for (size_t j = 0; j < first.size && !has; ++j)
        {
            const bool is_first_null = has_first_null_map && first_null_map[j];
            const bool is_second_null = has_second_null_map && second_null_map[i];
            if (is_first_null && is_second_null)
                has = true;
            if (!is_first_null && !is_second_null && isEqual(first, second, j, i))
                has = true;
        }
        if (has && search_type == ArraySearchType::Any)
            return true;
        if (!has && search_type == ArraySearchType::All)
            return false;
    }
    return search_type == ArraySearchType::All;
}
template <typename SliceType, typename EqualityFunc>
std::vector<size_t> buildKMPPrefixFunction(const SliceType & pattern, const EqualityFunc & isEqualFunc)