For example Null can be represented as empty string

```sql
select arrayStringConcat(['x',Null], ';');

┌─arrayStringConcat(['x', Null], ';')─┐
│ x;                                  │
└─────────────────────────────────────┘
```

But mostly it for avoiding a cast in case of Nullable Strings
```
SELECT arrayStringConcat(col0, ';')
FROM
(
    SELECT [toNullable('x')] AS col0
) AS t
```

Also I think arrayStringConcat can support any types not only Strings, it allows to avoid explicit casts.

```
SELECT arrayStringConcat(col0, ';')
FROM
(
    SELECT [1, 2, 3] AS col0
) AS t
```
memcpySmallAllowReadWriteOverflow15(&res_strings_chars[current_dst_strings_offset], token_begin, token_size);
                    res_strings_chars[current_dst_strings_offset + token_size] = 0;
                    current_dst_strings_offset += token_size + 1;
                    res_strings_offsets.push_back(current_dst_strings_offset);
                    ++j;
                }
                current_dst_offset += j;
                res_offsets.push_back(current_dst_offset);
            }
            return col_res;
        }
        else if (col_const_str)
        {
            String src = col_const_str->getValue<String>();
            Array dst;
            generator.set(src.data(), src.data() + src.size());
            Pos token_begin = nullptr;
            Pos token_end = nullptr;
            while (generator.get(token_begin, token_end))
                dst.push_back(String(token_begin, token_end - token_begin));
            return result_type->createColumnConst(col_const_str->size(), dst);
        }
        else
            throw Exception("Illegal columns " + array_argument.column->getName()
                    + ", " + array_argument.column->getName()
                    + " of arguments of function " + getName(),
                ErrorCodes::ILLEGAL_COLUMN);
    }
};
class FunctionArrayStringConcat : public IFunction