> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentation for User Defined Functions (UDFs)

# User Defined Functions (UDFs)

export const ExperimentalBadge = () => {
  return <div className="experimentalBadge">
            <div className="experimentalIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.25" d="M5.5 2H10.5" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M9.50015 2V6.19625L13.4283 12.7425C13.4738 12.8183 13.4985 12.9049 13.4996 12.9934C13.5008 13.0818 13.4785 13.169 13.435 13.246C13.3914 13.323 13.3283 13.3871 13.2519 13.4317C13.1755 13.4764 13.0886 13.4999 13.0002 13.5H3.00015C2.91164 13.5 2.8247 13.4766 2.74822 13.432C2.67174 13.3874 2.60847 13.3233 2.56487 13.2463C2.52126 13.1693 2.49889 13.082 2.50004 12.9935C2.50119 12.905 2.52582 12.8184 2.5714 12.7425L6.50015 6.19625V2" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.25" d="M4.47656 9.56754C5.30344 9.41254 6.47656 9.47942 7.99969 10.25C10.0153 11.2707 11.4216 11.0569 12.2184 10.7282" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            Experimental feature. <u><a href="/docs/beta-and-experimental-features#experimental-features">Learn more.</a></u>
        </div>;
};

export const CloudNotSupportedBadge = () => {
  return <div className="cloudNotSupportedBadge">
            <div className="cloudNotSupportedIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path strokeWidth="1.5" d="M6.33366 12.6666L12.3739 12.6667C13.6593 12.6667 14.7073 11.6187 14.7073 10.3334C14.7073 9.04804 13.6593 8.00003 12.3739 8.00003C12.3739 8.00003 12.3337 7.66659 12.0003 7.33325M10.667 5.33322C8.00033 2.33325 4.45395 4.78537 4.14195 6.68203C2.55728 6.7627 1.29395 8.06203 1.29395 9.6667C1.29395 11.3234 2.66699 12.6666 4.00033 12.6666" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path strokeWidth="1.5" d="M2.66699 14L12.0003 4.66663" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>

        </div>
            Not supported in ClickHouse Cloud
        </div>;
};

export const PrivatePreviewBadge = () => {
  return <div className="privatePreviewBadge">
            <div className="privatePreviewIcon">
            <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M5.33301 6.66667V4.66667V4.66667C5.33301 3.194 6.52701 2 7.99967 2V2C9.47234 2 10.6663 3.194 10.6663 4.66667V4.66667V6.66667" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path d="M8.00033 9.33337V11.3334" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
                <path fillRule="evenodd" clipRule="evenodd" d="M11.333 14H4.66634C3.92967 14 3.33301 13.4033 3.33301 12.6666V7.99996C3.33301 7.26329 3.92967 6.66663 4.66634 6.66663H11.333C12.0697 6.66663 12.6663 7.26329 12.6663 7.99996V12.6666C12.6663 13.4033 12.0697 14 11.333 14Z" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" />
            </svg>
        </div>
            {'Private preview in ClickHouse Cloud'}
        </div>;
};

# UDFs User Defined Functions

ClickHouse supports several types of user defined functions (UDFs):

* [Executable UDFs](#executable-user-defined-functions) start an external program or script (Python, Bash, etc.) and stream blocks of data to it over STDIN / STDOUT. Use them to integrate existing code or tooling without recompiling ClickHouse. They have higher per‑call overhead compared to in‑process options and are best for heavier logic or where a different runtime is required.
* [SQL UDFs](#sql-user-defined-functions) are defined with `CREATE FUNCTION` purely in SQL. They are inlined/expanded into the query plan (no process boundary), making them lightweight and ideal for reusing expression logic or simplifying complex calculated columns.
* [Experimental WebAssembly UDFs](#webassembly-user-defined-functions) run code compiled to WebAssembly inside a sandbox within the server process. They offer lower per‑call overhead than external executables with better isolation than native extensions, making them suitable for custom algorithms written in languages that can target WASM (e.g. C/C++/Rust).

<h2 id="executable-user-defined-functions">
  Executable User Defined Functions
</h2>

<Note>
  This feature is supported in private preview in ClickHouse Cloud.
  Please contact ClickHouse Support at [https://clickhouse.cloud/support](https://clickhouse.cloud/support) to access.
</Note>

ClickHouse can call any external executable program or script to process data.

The configuration of executable user defined functions can be located in one or more xml-files.
The path to the configuration is specified in the [`user_defined_executable_functions_config`](/reference/settings/server-settings/settings#user_defined_executable_functions_config) parameter.

A function configuration contains the following settings:

| Parameter                     | Description                                                                                                                                                                                                                                                                                                                                                                      | Required | Default Value          |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------- |
| `name`                        | A function name                                                                                                                                                                                                                                                                                                                                                                  | Yes      | -                      |
| `command`                     | Script name to execute or command if `execute_direct` is false                                                                                                                                                                                                                                                                                                                   | Yes      | -                      |
| `argument`                    | Argument description with the `type`, and optional `name` of an argument. Each argument is described in a separate setting. Specifying name is necessary if argument names are part of serialization for user defined function format like [Native](/reference/formats/Native) or [JSONEachRow](/reference/formats/JSON/JSONEachRow)                                             | Yes      | `c` + argument\_number |
| `format`                      | A [format](/reference/formats/index) in which arguments are passed to the command. The command output is expected to use the same format too                                                                                                                                                                                                                                     | Yes      | -                      |
| `return_type`                 | The type of a returned value                                                                                                                                                                                                                                                                                                                                                     | Yes      | -                      |
| `return_name`                 | Name of returned value. Specifying return name is necessary if return name is part of serialization for user defined function format like [Native](/reference/formats/Native) or [JSONEachRow](/reference/formats/JSON/JSONEachRow)                                                                                                                                              | Optional | `result`               |
| `type`                        | An executable type. If `type` is set to `executable` then single command is started. If it is set to `executable_pool` then a pool of commands is created                                                                                                                                                                                                                        | Yes      | -                      |
| `max_command_execution_time`  | Maximum execution time in seconds for processing block of data. This setting is valid for `executable_pool` commands only                                                                                                                                                                                                                                                        | Optional | `10`                   |
| `command_termination_timeout` | Time in seconds during which a command should finish after its pipe is closed. After that time `SIGTERM` is sent to the process executing the command                                                                                                                                                                                                                            | Optional | `10`                   |
| `command_read_timeout`        | Timeout for reading data from command stdout in milliseconds                                                                                                                                                                                                                                                                                                                     | Optional | `10000`                |
| `command_write_timeout`       | Timeout for writing data to command stdin in milliseconds                                                                                                                                                                                                                                                                                                                        | Optional | `10000`                |
| `pool_size`                   | The size of a command pool                                                                                                                                                                                                                                                                                                                                                       | Optional | `16`                   |
| `send_chunk_header`           | Controls whether to send row count before sending a chunk of data to process                                                                                                                                                                                                                                                                                                     | Optional | `false`                |
| `execute_direct`              | If `execute_direct` = `1`, then `command` will be searched inside user\_scripts folder specified by [user\_scripts\_path](/reference/settings/server-settings/settings#user_scripts_path). Additional script arguments can be specified using whitespace separator. Example: `script_name arg1 arg2`. If `execute_direct` = `0`, `command` is passed as argument for `bin/sh -c` | Optional | `1`                    |
| `lifetime`                    | The reload interval of a function in seconds. If it is set to `0` then the function is not reloaded                                                                                                                                                                                                                                                                              | Optional | `0`                    |
| `deterministic`               | If the function is deterministic (returns the same result for the same input)                                                                                                                                                                                                                                                                                                    | Optional | `false`                |
| `stderr_reaction`             | How to handle the command's stderr output. Values: `none` (ignore), `log` (log all stderr immediately), `log_first` (log first 4 KiB after exit), `log_last` (log last 4 KiB after exit), `throw` (throw exception immediately on any stderr output). When using `log_first` or `log_last` with a non-zero exit code, the stderr content is included in the exception message    | Optional | `log_last`             |
| `check_exit_code`             | If true, ClickHouse will check the exit code of the command. A non-zero exit code causes an exception                                                                                                                                                                                                                                                                            | Optional | `true`                 |

The command must read arguments from `STDIN` and must output the result to `STDOUT`. The command must process arguments iteratively. That is after processing a chunk of arguments it must wait for the next chunk.

<h2 id="executable-user-defined-functions">
  Executable User Defined Functions
</h2>

<h2 id="examples">
  Examples
</h2>

<h3 id="udf-inline">
  UDF from inline script
</h3>

Create `test_function_sum` manually specifying `execute_direct` to `0` using either XML or YAML configuration.

<Tabs>
  <Tab title="XML">
    File `test_function.xml` (`/etc/clickhouse-server/test_function.xml` with default path settings).

    ```xml title="/etc/clickhouse-server/test_function.xml" theme={null}
    <functions>
        <function>
            <type>executable</type>
            <name>test_function_sum</name>
            <return_type>UInt64</return_type>
            <argument>
                <type>UInt64</type>
                <name>lhs</name>
            </argument>
            <argument>
                <type>UInt64</type>
                <name>rhs</name>
            </argument>
            <format>TabSeparated</format>
            <command>cd /; clickhouse-local --input-format TabSeparated --output-format TabSeparated --structure 'x UInt64, y UInt64' --query "SELECT x + y FROM table"</command>
            <execute_direct>0</execute_direct>
            <deterministic>true</deterministic>
        </function>
    </functions>
    ```
  </Tab>

  <Tab title="YAML">
    File `test_function.yaml` (`/etc/clickhouse-server/test_function.yaml` with default path settings).

    ```yml title="/etc/clickhouse-server/test_function.yaml" theme={null}
    functions:
      type: executable
      name: test_function_sum
      return_type: UInt64
      argument:
        - type: UInt64
          name: lhs
        - type: UInt64
          name: rhs
      format: TabSeparated
      command: 'cd /; clickhouse-local --input-format TabSeparated --output-format TabSeparated --structure ''x UInt64, y UInt64'' --query "SELECT x + y FROM table"'
      execute_direct: 0
      deterministic: true
    ```
  </Tab>
</Tabs>

<br />

```sql title="Query" theme={null}
SELECT test_function_sum(2, 2);
```

```text title="Result" theme={null}
┌─test_function_sum(2, 2)─┐
│                       4 │
└─────────────────────────┘
```

<h3 id="udf-python">
  UDF from Python script
</h3>

In this example we create a UDF which reads a value from `STDIN` and returns it as a string.

Create `test_function` using either XML OR YAML configuration.

<Tabs>
  <Tab title="XML">
    File `test_function.xml` (`/etc/clickhouse-server/test_function.xml` with default path settings).

    ```xml title="/etc/clickhouse-server/test_function.xml" theme={null}
    <functions>
        <function>
            <type>executable</type>
            <name>test_function_python</name>
            <return_type>String</return_type>
            <argument>
                <type>UInt64</type>
                <name>value</name>
            </argument>
            <format>TabSeparated</format>
            <command>test_function.py</command>
        </function>
    </functions>
    ```
  </Tab>

  <Tab title="YAML">
    File `test_function.yaml` (`/etc/clickhouse-server/test_function.yaml` with default path settings).

    ```yml title="/etc/clickhouse-server/test_function.yaml" theme={null}
    functions:
      type: executable
      name: test_function_python
      return_type: String
      argument:
        - type: UInt64
          name: value
      format: TabSeparated
      command: test_function.py
    ```
  </Tab>
</Tabs>

<br />

Create a script file `test_function.py` inside `user_scripts` folder (`/var/lib/clickhouse/user_scripts/test_function.py` with default path settings).

```python theme={null}
#!/usr/bin/python3

import sys

if __name__ == '__main__':
    for line in sys.stdin:
        print("Value " + line, end='')
        sys.stdout.flush()
```

```sql title="Query" theme={null}
SELECT test_function_python(toUInt64(2));
```

```text title="Result" theme={null}
┌─test_function_python(2)─┐
│ Value 2                 │
└─────────────────────────┘
```

<h3 id="udf-stdin">
  Read two values from `STDIN` and return their sum as a JSON object
</h3>

Create `test_function_sum_json` with named arguments and format [JSONEachRow](/reference/formats/JSON/JSONEachRow) using either XML or YAML configuration.

<Tabs>
  <Tab title="XML">
    File `test_function.xml` (`/etc/clickhouse-server/test_function.xml` with default path settings).

    ```xml title="/etc/clickhouse-server/test_function.xml" theme={null}
    <functions>
        <function>
            <type>executable</type>
            <name>test_function_sum_json</name>
            <return_type>UInt64</return_type>
            <return_name>result_name</return_name>
            <argument>
                <type>UInt64</type>
                <name>argument_1</name>
            </argument>
            <argument>
                <type>UInt64</type>
                <name>argument_2</name>
            </argument>
            <format>JSONEachRow</format>
            <command>test_function_sum_json.py</command>
        </function>
    </functions>
    ```
  </Tab>

  <Tab title="YAML">
    File `test_function.yaml` (`/etc/clickhouse-server/test_function.yaml` with default path settings).

    ```yml title="/etc/clickhouse-server/test_function.yaml" theme={null}
    functions:
      type: executable
      name: test_function_sum_json
      return_type: UInt64
      return_name: result_name
      argument:
        - type: UInt64
          name: argument_1
        - type: UInt64
          name: argument_2
      format: JSONEachRow
      command: test_function_sum_json.py
    ```
  </Tab>
</Tabs>

<br />

Create script file `test_function_sum_json.py` inside the `user_scripts` folder (`/var/lib/clickhouse/user_scripts/test_function_sum_json.py` with default path settings).

```python theme={null}
#!/usr/bin/python3

import sys
import json

if __name__ == '__main__':
    for line in sys.stdin:
        value = json.loads(line)
        first_arg = int(value['argument_1'])
        second_arg = int(value['argument_2'])
        result = {'result_name': first_arg + second_arg}
        print(json.dumps(result), end='\n')
        sys.stdout.flush()
```

```sql title="Query" theme={null}
SELECT test_function_sum_json(2, 2);
```

```text title="Result" theme={null}
┌─test_function_sum_json(2, 2)─┐
│                            4 │
└──────────────────────────────┘
```

<h3 id="udf-parameters-in-command">
  Use parameters in `command` setting
</h3>

Executable user defined functions can take constant parameters configured in `command` setting (this works only for user defined functions with `executable` type).
It also requires the `execute_direct` option to ensure no shell argument expansion vulnerability.

<Tabs>
  <Tab title="XML">
    File `test_function_parameter_python.xml` (`/etc/clickhouse-server/test_function_parameter_python.xml` with default path settings).

    ```xml title="/etc/clickhouse-server/test_function_parameter_python.xml" theme={null}
    <functions>
        <function>
            <type>executable</type>
            <execute_direct>true</execute_direct>
            <name>test_function_parameter_python</name>
            <return_type>String</return_type>
            <argument>
                <type>UInt64</type>
            </argument>
            <format>TabSeparated</format>
            <command>test_function_parameter_python.py {test_parameter:UInt64}</command>
        </function>
    </functions>
    ```
  </Tab>

  <Tab title="YAML">
    File `test_function_parameter_python.yaml` (`/etc/clickhouse-server/test_function_parameter_python.yaml` with default path settings).

    ```yml title="/etc/clickhouse-server/test_function_parameter_python.yaml" theme={null}
    functions:
      type: executable
      execute_direct: true
      name: test_function_parameter_python
      return_type: String
      argument:
        - type: UInt64
      format: TabSeparated
      command: test_function_parameter_python.py {test_parameter:UInt64}
    ```
  </Tab>
</Tabs>

<br />

Create script file `test_function_parameter_python.py` inside the `user_scripts` folder (`/var/lib/clickhouse/user_scripts/test_function_parameter_python.py` with default path settings).

```python theme={null}
#!/usr/bin/python3

import sys

if __name__ == "__main__":
    for line in sys.stdin:
        print("Parameter " + str(sys.argv[1]) + " value " + str(line), end="")
        sys.stdout.flush()
```

```sql title="Query" theme={null}
SELECT test_function_parameter_python(1)(2);
```

```text title="Result" theme={null}
┌─test_function_parameter_python(1)(2)─┐
│ Parameter 1 value 2                  │
└──────────────────────────────────────┘
```

<h3 id="udf-shell-script">
  UDF from shell script
</h3>

In this example, we create a shell script that multiplies each value by 2.

<Tabs>
  <Tab title="XML">
    File `test_function_shell.xml` (`/etc/clickhouse-server/test_function_shell.xml` with default path settings).

    ```xml title="/etc/clickhouse-server/test_function_shell.xml" theme={null}
    <functions>
        <function>
            <type>executable</type>
            <name>test_shell</name>
            <return_type>String</return_type>
            <argument>
                <type>UInt8</type>
                <name>value</name>
            </argument>
            <format>TabSeparated</format>
            <command>test_shell.sh</command>
        </function>
    </functions>
    ```
  </Tab>

  <Tab title="YAML">
    File `test_function_shell.yaml` (`/etc/clickhouse-server/test_function_shell.yaml` with default path settings).

    ```yml title="/etc/clickhouse-server/test_function_shell.yaml" theme={null}
    functions:
      type: executable
      name: test_shell
      return_type: String
      argument:
        - type: UInt8
          name: value
      format: TabSeparated
      command: test_shell.sh
    ```
  </Tab>
</Tabs>

<br />

Create a script file `test_shell.sh` inside the `user_scripts` folder (`/var/lib/clickhouse/user_scripts/test_shell.sh` with default path settings).

```bash title="/var/lib/clickhouse/user_scripts/test_shell.sh" theme={null}
#!/bin/bash

while read read_data;
    do printf "$(expr $read_data \* 2)\n";
done
```

```sql title="Query" theme={null}
SELECT test_shell(number) FROM numbers(10);
```

```text title="Result" theme={null}
    ┌─test_shell(number)─┐
 1. │ 0                  │
 2. │ 2                  │
 3. │ 4                  │
 4. │ 6                  │
 5. │ 8                  │
 6. │ 10                 │
 7. │ 12                 │
 8. │ 14                 │
 9. │ 16                 │
10. │ 18                 │
    └────────────────────┘
```

<h2 id="error-handling">
  Error Handling
</h2>

Some functions might throw an exception if the data is invalid.
In this case, the query is canceled and an error text is returned to the client.
For distributed processing, when an exception occurs on one of the servers, the other servers also attempt to abort the query.

<h2 id="evaluation-of-argument-expressions">
  Evaluation of Argument Expressions
</h2>

In almost all programming languages, one of the arguments might not be evaluated for certain operators.
This is usually the operators `&&`, `||`, and `?:`.
In ClickHouse, arguments of functions (operators) are always evaluated.
This is because entire parts of columns are evaluated at once, instead of calculating each row separately.

<h2 id="performing-functions-for-distributed-query-processing">
  Performing Functions for Distributed Query Processing
</h2>

For distributed query processing, as many stages of query processing as possible are performed on remote servers, and the rest of the stages (merging intermediate results and everything after that) are performed on the requestor server.

This means that functions can be performed on different servers.
For example, in the query `SELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y),`

* if a `distributed_table` has at least two shards, the functions 'g' and 'h' are performed on remote servers, and the function 'f' is performed on the requestor server.
* if a `distributed_table` has only one shard, all the 'f', 'g', and 'h' functions are performed on this shard's server.

The result of a function usually does not depend on which server it is performed on. However, sometimes this is important.
For example, functions that work with dictionaries use the dictionary that exists on the server they are running on.
Another example is the `hostName` function, which returns the name of the server it is running on in order to make `GROUP BY` by servers in a `SELECT` query.

If a function in a query is performed on the requestor server, but you need to perform it on remote servers, you can wrap it in an 'any' aggregate function or add it to a key in `GROUP BY`.

<h2 id="sql-user-defined-functions">
  SQL User Defined Functions
</h2>

Custom functions from lambda expressions can be created using the [CREATE FUNCTION](/reference/statements/create/function) statement. To delete these functions use the [DROP FUNCTION](/reference/statements/drop#drop-function) statement.

<h2 id="webassembly-user-defined-functions">
  WebAssembly User Defined Functions
</h2>

WebAssembly User Defined Functions (WASM UDFs) allow you to run custom code compiled to WebAssembly inside the ClickHouse server process.

### Quick Start

Enable experimental WebAssembly support in your ClickHouse configuration:

```xml theme={null}
<clickhouse>
    <allow_experimental_webassembly_udf>true</allow_experimental_webassembly_udf>
</clickhouse>
```

Insert your compiled WASM module into the system table:

```sql theme={null}
INSERT INTO system.webassembly_modules (name, code)
SELECT 'my_module', base64Decode('AGFzbQEAAAA...');
```

Create a function using your WASM module:

```sql theme={null}
CREATE FUNCTION my_function
LANGUAGE WASM
ABI ROW_DIRECT
FROM 'my_module'
ARGUMENTS (x UInt32, y UInt32)
RETURNS UInt32;
```

Use the function in your queries:

```sql theme={null}
SELECT my_function(10, 20);
```

### More Information

Refer to the documentation on [WebAssembly User Defined Functions](/reference/functions/regular-functions/wasm_udf) for more details.

<h2 id="related-content">
  Related Content
</h2>

* [User-defined functions in ClickHouse Cloud](https://clickhouse.com/blog/user-defined-functions-clickhouse-udfs)
