When I'm executing a UDF function, a `null value` input to the script is received as `0`(for numbers) and `empty string` (for strings). 

The UDF definition like this
```
<function>
    <type>executable</type>
    <name>some_function_name</name>
    <return_name>result</return_name>
    <return_type>String</return_type>
    <argument>
        <type>Nullable(Int32)</type>
        <name>argument_1</name>
    </argument>
    <format>JSONEachRow</format>
    <command>some_function.py</command>
</function>
```
And the script file link this (Here whatever input I got I'm logging it to a file.)
```
#!/usr/bin/python3

import sys
import json

def write_to_file(line):
	with open("/tmp/input.log",'a') as fw:
		fw.write(str(line))

if __name__ == '__main__':
    for line in sys.stdin:
        # Writing log
        write_to_file(line)

        result = {"result":str(line)}
        print(json.dumps(result))
        sys.stdout.flush()
```

I got the below results 
```
clickhouse-client --query="select value, some_function_name(value) from (SELECT 1 as value UNION ALL SELECT NULL UNION ALL SELECT 0) FORMAT Vertical"  --input_format_tsv_empty_as_default=1

Row 1:
──────
value:                     1
some_function_name(value): {"argument_1":1}


Row 2:
──────
value:                     ᴺᵁᴸᴸ
some_function_name(value): ᴺᵁᴸᴸ

Row 3:
──────
value:                     0
some_function_name(value): {"argument_1":0}

```
Here, the result for `Row 2` should be `{"argument_1":NULL}` but it's `NULL`.

And the log I got  for inputs as below
```
{"argument_1":1}
{"argument_1":0}
{"argument_1":0}
```

So, is there any option to get the `NULL` value as `NULL` to the input script?

{
    const auto & loader = context->getExternalUserDefinedExecutableFunctionsLoader();
    auto load_result = loader.getLoadResult(function_name);
    if (load_result.object)
    {
        auto executable_function = std::static_pointer_cast<const UserDefinedExecutableFunction>(load_result.object);
        auto function = std::make_shared<UserDefinedFunction>(std::move(executable_function), std::move(context));
        return std::make_unique<FunctionToOverloadResolverAdaptor>(std::move(function));
    }
    return nullptr;
}
bool UserDefinedExecutableFunctionFactory::has(const String & function_name, ContextPtr context)
{
    const auto & loader = context->getExternalUserDefinedExecutableFunctionsLoader();
    auto load_result = loader.getLoadResult(function_name);
    bool result = load_result.object != nullptr;
    return result;
}
std::vector<String> UserDefinedExecutableFunctionFactory::getRegisteredNames(ContextPtr context)
{
    const auto & loader = context->getExternalUserDefinedExecutableFunctionsLoader();
    auto loaded_objects = loader.getLoadedObjects();
    std::vector<std::string> registered_names;
    registered_names.reserve(loaded_objects.size());
    for (auto & loaded_object : loaded_objects)
        registered_names.emplace_back(loaded_object->getLoadableName());
    return registered_names;
}
}