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)
{
        if (!isStringOrFixedString(arguments[0]))
            throw Exception("Illegal type " + arguments[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
        if (!isStringOrFixedString(arguments[1]))
            throw Exception("Illegal type " + arguments[1]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
        return std::make_shared<DataTypeUInt8>();
    }
    ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
    {
        const IColumn * haystack_column = arguments[0].column.get();
        const IColumn * needle_column = arguments[1].column.get();
        auto col_res = ColumnVector<UInt8>::create();
        typename ColumnVector<UInt8>::Container & vec_res = col_res->getData();
        vec_res.resize(input_rows_count);
        if (const ColumnString * haystack = checkAndGetColumn<ColumnString>(haystack_column))
            dispatch<StringSource>(StringSource(*haystack), needle_column, vec_res);
        else if (const ColumnFixedString * haystack_fixed = checkAndGetColumn<ColumnFixedString>(haystack_column))
            dispatch<FixedStringSource>(FixedStringSource(*haystack_fixed), needle_column, vec_res);
        else if (const ColumnConst * haystack_const = checkAndGetColumnConst<ColumnString>(haystack_column))
            dispatch<ConstSource<StringSource>>(ConstSource<StringSource>(*haystack_const), needle_column, vec_res);
        else if (const ColumnConst * haystack_const_fixed = checkAndGetColumnConst<ColumnFixedString>(haystack_column))
            dispatch<ConstSource<FixedStringSource>>(ConstSource<FixedStringSource>(*haystack_const_fixed), needle_column, vec_res);
        else
            throw Exception("Illegal combination of columns as arguments of function " + getName(), ErrorCodes::ILLEGAL_COLUMN);
        return col_res;
    }
private: