Hi, 
I'm trying to figure out how read / write some data formats that are not TabSeparated (e.g. [Native](https://clickhouse.com/docs/en/interfaces/formats/#native) or [JSONEachRow](https://clickhouse.com/docs/en/interfaces/formats/#jsoneachrow)) in my EUDF -  C++ script. 

Context:
I already succeed to implement some EUDF but always with TabSeparated or CSV. However, in one of my script I'm looking for performance on a quite big array. The query is executed in ~10sec while my script takes ~2sec to execute (bench with RDTSC). Since the query is just calling my script (called in the same way that the example), I guess that the data format conversion may be too heavy. 
In order to benchmark several types and find the best compromise between fastest input/output transfert and serialisation/deserialisation  speed, I made a very simple c++ code. This code writes in standard output, what is read from standard input (see below). However, as you already guessed, I'm struggling with some data formats.

I have a table (`table1`) with one column of `Array(UInt64)` that I send as one block of `Array(Array(UInt64))` to my script using `groupArray`. 
In the below example I'm just writing what I read from the client.

info:
Clickhouse version 22.2.1

This is what I use for my tests.

my_function.xml
```
<clickhouse>
<functions>
        <type>executable</type>
        <name>data_debug</name>
        <return_type>Array(Array(UInt64))</return_type>
        <argument>
            <type>Array(Array(UInt64))</type>
        </argument>
        <format>Native</format>
        <command>data_debug</command>
</functions>
</clickhouse>
```
My c++ script data_debug.cpp:
```
#include <iostream>

int main(int argc, char **argv)
{
  std::string line;

  std::cin.tie(nullptr);
  std::cin.sync_with_stdio(false);

  std::cout.tie(nullptr);
  std::cout.sync_with_stdio(false);

  while(std::cin >> line) {
    std::cout << line << "\n";
    std::cout.flush();
  }
  return 0;
}
```
Compile with:
`g++ -std=c++11 -O3  data_debug.cpp -o data_debug`
Executed in CH client as follow:
`SELECT data_debug(groupArray(table1.journey)) FROM table1`

Leads to this error:
```
Received exception from server (version 22.2.1):
Code: 10. DB::Exception: Received from localhost:9000. DB::Exception: Not found column groupArray(journey) in block. There are only columns: result: While executing Native: While executing ShellCommandSource. (NOT_FOUND_COLUMN_IN_BLOCK)
```
When I use the JSONEachRows format I get: 
```
Received exception from server (version 22.2.1):
Code: 117. DB::Exception: Received from localhost:9000. DB::Exception: Unknown field found while parsing JSONEachRow format: groupArray(journey): (at row 1)
: While executing ParallelParsingBlockInputFormat: While executing ShellCommandSource: while executing 'FUNCTION data_debug(groupArray(journey) :: 0) -> data_debug(groupArray(journey)) Array(Array(UInt64)) : 1'. (INCORRECT_DATA)
```

Can you tell me what I'm doing wrong with these two types ? Cause if even if CH doesn't accept what he sent itself, I don't know what to do differently.
{
    return std::static_pointer_cast<const UserDefinedExecutableFunction>(tryLoad(user_defined_function_name));
}
void ExternalUserDefinedExecutableFunctionsLoader::reloadFunction(const std::string & user_defined_function_name) const
{
    loadOrReload(user_defined_function_name);
}
ExternalLoader::LoadablePtr ExternalUserDefinedExecutableFunctionsLoader::create(const std::string & name,
    const Poco::Util::AbstractConfiguration & config,
    const std::string & key_in_config,
    const std::string &) const
{
    if (FunctionFactory::instance().hasNameOrAlias(name))
        throw Exception(ErrorCodes::FUNCTION_ALREADY_EXISTS, "The function '{}' already exists", name);
    if (AggregateFunctionFactory::instance().hasNameOrAlias(name))
        throw Exception(ErrorCodes::FUNCTION_ALREADY_EXISTS, "The aggregate function '{}' already exists", name);
    String type = config.getString(key_in_config + ".type");
    bool is_executable_pool = false;
    if (type == "executable")
        is_executable_pool = false;
    else if (type == "executable_pool")
        is_executable_pool = true;
    else
        throw Exception(ErrorCodes::BAD_ARGUMENTS,
            "Wrong user defined function type expected 'executable' or 'executable_pool' actual {}",
            type);
    bool execute_direct = config.getBool(key_in_config + ".execute_direct", true);
    String command_value = config.getString(key_in_config + ".command");
    std::vector<String> command_arguments;
    if (execute_direct)