Пользовательские функции UDF
Исполняемые пользовательские функции
Эта функция поддерживается в частном превью в ClickHouse Cloud. Пожалуйста, свяжитесь с поддержкой ClickHouse по адресу https://clickhouse.cloud/support для доступа.
ClickHouse может вызывать любую внешнюю исполняемую программу или скрипт для обработки данных.
Конфигурация исполняемых пользовательских функций может находиться в одном или нескольких xml-файлах. Путь к конфигурации указывается в параметре user_defined_executable_functions_config.
Конфигурация функции содержит следующие настройки:
name
- имя функции.command
- имя скрипта для выполнения или команда, еслиexecute_direct
равно false.argument
- описание аргумента сtype
и необязательнымname
аргумента. Каждый аргумент описывается в отдельной настройке. Указание имени необходимо, если имена аргументов являются частью сериализации для формата пользовательской функции, такого как Native или JSONEachRow. Значение имени аргумента по умолчанию -c
+ номер_аргумента.format
- формат передачи аргументов в команду.return_type
- тип возвращаемого значения.return_name
- имя возвращаемого значения. Указание имени возврата необходимо, если имя возврата является частью сериализации для формата пользовательской функции, такого как Native или JSONEachRow. Необязательно. Значение по умолчанию -result
.type
- исполняемый тип. Еслиtype
установлен вexecutable
, то запускается одна команда. Если установлен вexecutable_pool
, то создается пул команд.max_command_execution_time
- максимальное время выполнения в секундах для обработки блока данных. Эта настройка действительна только для командexecutable_pool
. Необязательно. Значение по умолчанию -10
.command_termination_timeout
- время в секундах, в течение которого команда должна завершиться после закрытия ее канала. По истечении этого времени к процессу, выполняющему команду, отправляетсяSIGTERM
. Необязательно. Значение по умолчанию -10
.command_read_timeout
- таймаут для чтения данных из stdout команды в миллисекундах. Значение по умолчанию 10000. Необязательный параметр.command_write_timeout
- таймаут для записи данных в stdin команды в миллисекундах. Значение по умолчанию 10000. Необязательный параметр.pool_size
- размер пула команд. Необязательно. Значение по умолчанию -16
.send_chunk_header
- управляет тем, нужно ли отправлять количество строк перед отправкой блока данных для обработки. Необязательно. Значение по умолчанию -false
.execute_direct
- Еслиexecute_direct
=1
, тоcommand
будет искаться в папке user_scripts, указанной переменной user_scripts_path. Дополнительные аргументы скрипта могут быть указаны через пробел. Пример:script_name arg1 arg2
. Еслиexecute_direct
=0
,command
передается в качестве аргумента дляbin/sh -c
. Значение по умолчанию -1
. Необязательный параметр.lifetime
- интервал перезагрузки функции в секундах. Если он установлен в0
, то функция не перезагружается. Значение по умолчанию -0
. Необязательный параметр.deterministic
- является ли функция детерминированной (возвращает один и тот же результат для одного и того же ввода). Значение по умолчанию -false
. Необязательный параметр.
Команда должна читать аргументы из STDIN
и выводить результат в STDOUT
. Команда должна обрабатывать аргументы итеративно. То есть после обработки блока аргументов она должна ждать следующий блок.
Примеры
Встроенный скрипт
Создание test_function_sum
с ручным указанием execute_direct
равным 0
с использованием конфигурации XML.
Файл test_function.xml
(/etc/clickhouse-server/test_function.xml
с настройками пути по умолчанию).
Запрос:
Результат:
Python скрипт
Читает значение из STDIN
и возвращает его как строку:
Создание test_function
с использованием конфигурации XML.
Файл test_function.xml
(/etc/clickhouse-server/test_function.xml
с настройками пути по умолчанию).
Файл скрипта в папке user_scripts
test_function.py
(/var/lib/clickhouse/user_scripts/test_function.py
с настройками пути по умолчанию).
Запрос:
Результат:
Читает два значения из STDIN
и возвращает их сумму в виде JSON-объекта:
Создание test_function_sum_json
с именованными аргументами и форматом JSONEachRow с использованием конфигурации XML.
Файл test_function.xml
(/etc/clickhouse-server/test_function.xml
с настройками пути по умолчанию).
Файл скрипта в папке user_scripts
test_function_sum_json.py
(/var/lib/clickhouse/user_scripts/test_function_sum_json.py
с настройками пути по умолчанию).
Запрос:
Результат:
Используйте параметры в настройке command
:
Исполняемые пользовательские функции могут принимать постоянные параметры, настроенные в настройке command
(работает только для пользовательских функций типа executable
). Это также требует опции execute_direct
(чтобы избежать уязвимости в расширении аргументов оболочки).
Файл test_function_parameter_python.xml
(/etc/clickhouse-server/test_function_parameter_python.xml
с настройками пути по умолчанию).
Файл скрипта в папке user_scripts
test_function_parameter_python.py
(/var/lib/clickhouse/user_scripts/test_function_parameter_python.py
с настройками пути по умолчанию).
Запрос:
Результат:
Shell скрипт
Shell скрипт, который умножает каждое значение на 2:
Исполняемые пользовательские функции могут использоваться с shell-скриптом.
Файл test_function_shell.xml
(/etc/clickhouse-server/test_function_shell.xml
с настройками пути по умолчанию).
Файл скрипта в папке user_scripts
test_shell.sh
(/var/lib/clickhouse/user_scripts/test_shell.sh
с настройками пути по умолчанию).
Запрос:
Результат:
Обработка ошибок
Некоторые функции могут выбросить исключение, если данные недопустимы. В этом случае запрос отменяется, и текст ошибки возвращается клиенту. При распределенной обработке, когда исключение возникает на одном из серверов, другие серверы также пытаются прервать запрос.
Оценка выражений аргументов
Почти во всех языках программирования одно из аргументов может не быть оценено для определенных операторов. Обычно это операторы &&
, ||
и ?:
.
Но в ClickHouse аргументы функций (операторов) всегда оцениваются. Это связано с тем, что целые части колонок оцениваются сразу, вместо того чтобы вычислять каждую строку отдельно.
Выполнение функций для распределенной обработки запросов
При распределенной обработке запросов как можно больше этапов обработки запроса выполняется на удаленных серверах, а остальные этапы (слияние промежуточных результатов и все, что идет после этого) выполняются на сервере запрашивающего клиента.
Это означает, что функции могут выполняться на разных серверах.
Например, в запросе SELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y),
- если
distributed_table
имеет как минимум два шарда, функции 'g' и 'h' выполняются на удаленных серверах, а функция 'f' выполняется на сервере запрашивающего клиента. - если
distributed_table
имеет только один шард, все функции 'f', 'g' и 'h' выполняются на сервере этого шарда.
Результат функции обычно не зависит от того, на каком сервере она выполняется. Однако это иногда важно.
Например, функции, работающие со словарями, используют словарь, который существует на сервере, на котором они выполняются.
Другой пример - это функция hostName
, которая возвращает имя сервера, на котором она выполняется, чтобы сделать GROUP BY
по серверам в запросе SELECT
.
Если функция в запросе выполняется на сервере запрашивающего клиента, но нужно выполнить ее на удаленных серверах, вы можете обернуть её в агрегатную функцию 'any' или добавить её в ключ в GROUP BY
.
SQL пользовательские функции
Пользовательские функции из лямбда-выражений могут быть созданы с помощью оператора CREATE FUNCTION. Для удаления этих функций используйте оператор DROP FUNCTION.