**Use case**
Manually modify the contents of ZooKeeper.
Not for normal usage scenarios... mostly for operations engineers.

**Describe the solution you'd like**

Allow INSERT. It should contain only subset of the columns, because some of the columns in `system.zookeeper` table (like numChildren, ctime, etc...) cannot be specified explicitly.

INSERT will perform multiple create operations.

Add a setting to perform set operations (update existing nodes) instead of creating new nodes.

**Additional context**

Also it will be nice to allow "full scan" queries to `system.zookeeper` table to quickly creating dumps.
It can be filtered by condition on prefix of path.

{
    const auto & select = query->as<ASTSelectQuery &>();
    if (!select.where())
        return allow_unrestricted ? Paths{{"/", ZkPathType::Recurse}} : Paths();
    Paths res;
    return extractPathImpl(*select.where(), res, context, allow_unrestricted) ? res : Paths();
}
void StorageSystemZooKeeper::fillData(MutableColumns & res_columns, ContextPtr context, const SelectQueryInfo & query_info) const
{
    Paths paths = extractPath(query_info.query, context, context->getSettingsRef().allow_unrestricted_reads_from_keeper);
    zkutil::ZooKeeperPtr zookeeper = context->getZooKeeper();
    if (paths.empty())
        throw Exception("SELECT from system.zookeeper table must contain condition like path = 'path' or path IN ('path1','path2'...) or path IN (subquery) in WHERE clause unless `set allow_unrestricted_reads_from_keeper = 'true'`.", ErrorCodes::BAD_ARGUMENTS);
    std::unordered_set<String> added;
    while (!paths.empty())
    {
        auto [path, path_type] = std::move(paths.front());
        paths.pop_front();
        String prefix;
        if (path_type == ZkPathType::Prefix)