UDFs Fonctions définies par l’utilisateur
- Executable UDFs lancent un programme externe ou un script (Python, Bash, etc.) et lui transmettent des blocs de données en flux via STDIN / STDOUT. Utilisez-les pour intégrer du code ou des outils existants sans recompiler ClickHouse. Leur surcoût par appel est plus élevé que celui des options exécutées dans le processus, et elles conviennent mieux à une logique plus lourde ou aux cas où un environnement d’exécution différent est nécessaire.
- SQL UDFs sont définies avec
CREATE FUNCTIONuniquement en SQL. Elles sont intégrées/dépliées dans le plan de requête (sans passer par un processus distinct), ce qui les rend légères et idéales pour réutiliser une logique d’expression ou simplifier des colonnes calculées complexes. - Experimental WebAssembly UDFs exécutent du code compilé en WebAssembly dans un sandbox au sein du processus serveur. Elles offrent un surcoût par appel plus faible que les exécutables externes, avec une meilleure isolation que les extensions natives, ce qui les rend adaptées aux algorithmes personnalisés écrits dans des langages pouvant cibler WASM (par ex. C/C++/Rust).
Fonctions exécutables définies par l’utilisateur
Cette fonctionnalité est disponible en aperçu privé dans ClickHouse Cloud.
Veuillez contacter ClickHouse Support à l’adresse https://clickhouse.cloud/support pour y accéder.
user_defined_executable_functions_config.
Une configuration de fonction contient les paramètres suivants :
| Paramètre | Description | Obligatoire | Valeur par défaut |
|---|---|---|---|
name | Nom de la fonction | Oui | - |
command | Nom du script à exécuter, ou commande si execute_direct vaut false | Oui | - |
argument | Description d’un argument avec son type et, éventuellement, son name. Chaque argument est décrit dans un paramètre distinct. Indiquer un nom est nécessaire si les noms d’arguments font partie de la sérialisation pour un format de fonction définie par l’utilisateur tel que Native ou JSONEachRow | Oui | c + argument_number |
format | Format dans lequel les arguments sont transmis à la commande. La sortie de la commande doit également utiliser ce même format | Oui | - |
return_type | Type de la valeur renvoyée | Oui | - |
return_name | Nom de la valeur renvoyée. Indiquer un nom de retour est nécessaire si ce nom fait partie de la sérialisation pour un format de fonction définie par l’utilisateur tel que Native ou JSONEachRow | Facultatif | result |
type | Type d’exécutable. Si type est défini sur executable, une seule commande est lancée. S’il est défini sur executable_pool, un pool de commandes est créé | Oui | - |
max_command_execution_time | Temps d’exécution maximal, en secondes, pour le traitement d’un bloc de données. Ce paramètre s’applique uniquement aux commandes executable_pool | Facultatif | 10 |
command_termination_timeout | Délai, en secondes, pendant lequel une commande doit se terminer après la fermeture de son pipe. Au-delà, SIGTERM est envoyé au processus qui exécute la commande | Facultatif | 10 |
command_read_timeout | Délai d’attente pour la lecture des données depuis le stdout de la commande, en millisecondes | Facultatif | 10000 |
command_write_timeout | Délai d’attente pour l’écriture des données vers le stdin de la commande, en millisecondes | Facultatif | 10000 |
pool_size | Taille du pool de commandes | Facultatif | 16 |
send_chunk_header | Indique s’il faut envoyer le nombre de lignes avant d’envoyer un fragment de données au processus | Facultatif | false |
execute_direct | Si execute_direct = 1, command est recherchée dans le dossier user_scripts spécifié par user_scripts_path. Des arguments de script supplémentaires peuvent être indiqués en les séparant par des espaces. Exemple : script_name arg1 arg2. Si execute_direct = 0, command est transmise comme argument à bin/sh -c | Facultatif | 1 |
lifetime | Intervalle de rechargement d’une fonction, en secondes. S’il est défini sur 0, la fonction n’est pas rechargée | Facultatif | 0 |
deterministic | Indique si la fonction est déterministe (renvoie le même résultat pour la même entrée) | Facultatif | false |
stderr_reaction | Façon de gérer la sortie stderr de la commande. Valeurs : none (ignorer), log (journaliser immédiatement toute la sortie stderr), log_first (journaliser les 4 premiers KiB après la fin), log_last (journaliser les 4 derniers KiB après la fin), throw (lever immédiatement une exception à la moindre sortie sur stderr). Lors de l’utilisation de log_first ou log_last avec un code de sortie non nul, le contenu de stderr est inclus dans le message d’exception | Facultatif | log_last |
check_exit_code | Si true, ClickHouse vérifie le code de sortie de la commande. Un code de sortie non nul provoque une exception | Facultatif | true |
STDIN et écrire le résultat sur STDOUT. Elle doit traiter les arguments de manière itérative. Autrement dit, après avoir traité un fragment d’arguments, elle doit attendre le fragment suivant.
Fonctions exécutables définies par l’utilisateur
Exemples
UDF à partir d’un script intégré
test_function_sum en définissant execute_direct sur 0, à l’aide d’une configuration XML ou YAML.
- XML
- YAML
Fichier
test_function.xml (/etc/clickhouse-server/test_function.xml avec la configuration de chemin par défaut)./etc/clickhouse-server/test_function.xml
Query
Result
UDF à partir d’un script Python
STDIN et la renvoie sous forme de chaîne de caractères.
Créez test_function à l’aide d’une configuration XML ou YAML.
- XML
- YAML
Fichier
test_function.xml (/etc/clickhouse-server/test_function.xml avec le chemin par défaut)./etc/clickhouse-server/test_function.xml
Créez un fichier script
test_function.py dans le dossier user_scripts (/var/lib/clickhouse/user_scripts/test_function.py avec le chemin par défaut).
Query
Result
Lire deux valeurs à partir de STDIN et renvoyer leur somme sous forme d’objet JSON
test_function_sum_json avec des arguments nommés et le format JSONEachRow à l’aide d’une configuration XML ou YAML.
- XML
- YAML
Fichier
test_function.xml (/etc/clickhouse-server/test_function.xml avec les paramètres de chemin par défaut)./etc/clickhouse-server/test_function.xml
Créez le fichier de script
test_function_sum_json.py dans le dossier user_scripts (/var/lib/clickhouse/user_scripts/test_function_sum_json.py avec les paramètres de chemin par défaut).
Query
Result
Utiliser des paramètres dans le paramètre command
command (cela fonctionne uniquement pour les fonctions définies par l’utilisateur de type executable).
Cela nécessite également l’option execute_direct pour éviter toute vulnérabilité liée à l’expansion des arguments par le shell.
- XML
- YAML
Fichier
test_function_parameter_python.xml (/etc/clickhouse-server/test_function_parameter_python.xml avec les chemins par défaut)./etc/clickhouse-server/test_function_parameter_python.xml
Créez le script
test_function_parameter_python.py dans le dossier user_scripts (/var/lib/clickhouse/user_scripts/test_function_parameter_python.py avec les chemins par défaut).
Query
Result
UDF à partir d’un script shell
- XML
- YAML
Fichier
test_function_shell.xml (/etc/clickhouse-server/test_function_shell.xml si vous utilisez les chemins par défaut)./etc/clickhouse-server/test_function_shell.xml
Créez le fichier de script
test_shell.sh dans le dossier user_scripts (/var/lib/clickhouse/user_scripts/test_shell.sh si vous utilisez les chemins par défaut).
/var/lib/clickhouse/user_scripts/test_shell.sh
Query
Result
Gestion des erreurs
Évaluation des expressions des arguments
&&, || et ?:.
Dans ClickHouse, les arguments des fonctions (opérateurs) sont toujours évalués.
Cela s’explique par le fait que des parties entières de colonnes sont évaluées en une seule fois, au lieu de calculer chaque ligne séparément.
Exécution des fonctions pour le traitement distribué des requêtes
SELECT f(sum(g(x))) FROM distributed_table GROUP BY h(y),
- si
distributed_tablea au moins deux shards, les fonctions ‘g’ et ‘h’ sont exécutées sur des serveurs distants, et la fonction ‘f’ est exécutée sur le serveur à l’origine de la requête. - si
distributed_tablen’a qu’un seul shard, toutes les fonctions ‘f’, ‘g’ et ‘h’ sont exécutées sur le serveur de ce shard.
hostName, qui renvoie le nom du serveur sur lequel elle s’exécute, afin de permettre un GROUP BY par serveurs dans une requête SELECT.
Si une fonction d’une requête est exécutée sur le serveur à l’origine de la requête, mais que vous devez l’exécuter sur des serveurs distants, vous pouvez l’encapsuler dans une fonction d’agrégation ‘any’ ou l’ajouter à une clé du GROUP BY.