Vue d’ensemble des fonctions définies par l’utilisateur¶
Vous pouvez écrire des fonctions définies par l’utilisateur (UDFs) pour étendre le système pour effectuer des opérations qui ne sont pas disponibles grâce aux fonctions intégrées et définies par le système fournies par Snowflake. Une fois que vous avez créé une UDF, vous pouvez la réutiliser plusieurs fois.
Une UDF n’est qu’une façon d’étendre Snowflake. Pour les autres, voir ce qui suit :
Note
Une UDF ressemble à une procédure stockée, mais les deux diffèrent sur des points importants. Pour plus d’informations, voir Choisir d’écrire une procédure stockée ou une fonction définie par l’utilisateur.
Dans ce chapitre :
Qu’est-ce qu’une fonction définie par l’utilisateur (UDF) ?¶
Une fonction définie par l’utilisateur (UDF) est une fonction que vous définissez pour pouvoir l’appeler à partir de SQL. Comme pour les fonctions intégrées que vous pouvez appeler à partir de SQL, la logique d’une UDF étend ou optimise généralement SQL avec des fonctionnalités que SQL n’a pas ou ne fait pas bien. Une UDF vous permet également d’encapsuler une fonctionnalité afin de pouvoir l’appeler de manière répétée à plusieurs endroits du code.
Vous écrivez la logique d’une UDF (son gestionnaire) dans l’un des langages pris en charge. Une fois que vous avez un gestionnaire, vous pouvez créer une UDF avec une commande CREATE FUNCTION, puis appeler l’UDF avec une instruction SELECT.
Fonctions scalaires et tabulaires¶
Vous pouvez écrire une UDF qui renvoie une valeur unique (une UDF scalaire) ou qui renvoie une valeur tabulaire (une fonction de table définie par l’utilisateur ou UDTF).
Une fonction scalaire (UDF) renvoie une ligne de sortie pour chaque ligne d’entrée. La ligne renvoyée est constituée d’une seule colonne/valeur.
Une fonction tabulaire (UDTF) renvoie une valeur tabulaire pour chaque ligne d’entrée. Dans le gestionnaire d’une UDTF, vous écrivez des méthodes conformes à une interface requise par Snowflake. Ces méthodes permettront :
De traiter chaque ligne d’une partition (obligatoire).
D’initialiser le gestionnaire une fois pour chaque partition (facultatif).
De finaliser le traitement de chaque partition (facultatif).
Les noms des méthodes varient selon le langage du gestionnaire. Pour une liste des langages pris en charge, voir Langues acceptées.
Considérations¶
Si une requête appelle une UDF pour accéder à des fichiers en zone de préparation, l’opération échoue avec une erreur utilisateur si l’instruction SQL interroge également une vue qui appelle une UDF ou une UDTF, peu importe si la fonction de la vue accède ou non à des fichiers en zone de préparation.
Les UDTFs peuvent traiter plusieurs fichiers en parallèle ; cependant, les UDFs traitent actuellement les fichiers en série. Comme solution de rechange, regroupez les lignes dans une sous-requête en utilisant la clause GROUP BY. Voir Traiter un fichier CSV avec une UDTF pour un exemple.
Actuellement, si les fichiers en zone de préparation référencés dans une requête sont modifiés ou supprimés pendant l’exécution de la requête, l’appel de la fonction renvoie une erreur.
Prise en main¶
Pour un tutoriel dans lequel vous écrivez une UDTF avec un gestionnaire écrit en SQL, voir Démarrage rapide : Premiers pas avec les fonctions SQL définies par l’utilisateur
Exemple UDF¶
Le code de l’exemple suivant crée une UDF appelée addone
avec un gestionnaire écrit en Python. La fonction du gestionnaire est addone_py
. Cette UDF renvoie un int
.
CREATE OR REPLACE FUNCTION addone(i int)
RETURNS INT
LANGUAGE PYTHON
RUNTIME_VERSION = '3.8'
HANDLER = 'addone_py'
as
$$
def addone_py(i):
return i+1
$$;
Le code de l’exemple suivant exécute l’UDF addone
.
SELECT addone(3);
Langues acceptées¶
Vous écrivez le gestionnaire d’une fonction (sa logique) dans l’un des nombreux langages de programmation. Chaque langage permet de manipuler des données en respectant les contraintes du langage et de son environnement d’exécution. Quel que soit le langage du gestionnaire, vous créez la procédure elle-même de la même manière en utilisant SQL, en spécifiant votre gestionnaire et le langage du gestionnaire.
Vous pouvez écrire un gestionnaire dans l’un des langages suivants :
Langage |
Guides du développeur |
---|---|
Java |
|
JavaScript |
|
Python |
|
Scala |
|
SQL |
Choix du langage¶
Vous écrivez le gestionnaire d’une UDF (sa logique) dans l’un des nombreux langages de programmation. Chaque langage permet de manipuler des données en respectant les contraintes du langage et de son environnement d’exécution.
Vous pouvez choisir un langage particulier si :
Vous disposez déjà de code dans ce langage.
Par exemple, si vous disposez déjà d’une méthode Java qui fonctionnera en tant que gestionnaire et que l’objet de la méthode se trouve dans un fichier .jar, vous pouvez copier le fichier .jar dans une zone de préparation, spécifier le gestionnaire en tant que classe et méthode, puis choisir Java comme langage.
Le langage possède des capacités que d’autres n’ont pas.
Le langage possède des bibliothèques qui peuvent vous aider à effectuer le traitement dont vous avez besoin.
Lorsque vous choisissez un langage, tenez également compte des éléments suivants :
Emplacements du gestionnaire pris en charge. Tous les langages ne permettent pas de faire référence au gestionnaire sur une zone de préparation (le code du gestionnaire doit être en ligne). Pour plus d’informations, voir Conserver le code du gestionnaire en ligne ou dans une zone de préparation.
Si le gestionnaire produit une UDF qui peut être partagée. Une UDF partageable peut être utilisée avec la fonctionnalité Secure Data Sharing de Snowflake.
Langage |
Emplacement du gestionnaire |
Partageable |
---|---|---|
Java |
En ligne ou en zone de préparation |
Non [1] |
JavaScript |
En ligne |
Oui |
Python |
En ligne ou en zone de préparation |
Non [2] |
Scala |
En ligne ou en zone de préparation |
Non [3] |
SQL |
En ligne |
Oui |
Guides du développeur¶
Lignes directrices et contraintes¶
- Contraintes liées à Snowflake:
Vous pouvez assurer la stabilité de l’environnement Snowflake en vous développant dans le cadre des contraintes de Snowflake. Pour plus d’informations, consultez Concevoir des gestionnaires qui respectent les contraintes imposées par Snowflake.
- Nommage:
Veillez à nommer les fonctions de manière à éviter les collisions avec d’autres fonctions. Pour plus d’informations, consultez Nommage et surcharge de procédures et d’UDFs.
- Arguments:
Spécifiez les arguments et indiquez ceux qui sont facultatifs. Pour plus d’informations, consultez Définition des arguments pour UDFs et les procédures stockées.
- Mappages de types de données:
Pour chaque langage de traitement, il existe un ensemble distinct de mappages entre les types de données du langage et les types SQL utilisés pour les arguments et les valeurs de retour. Pour plus d’informations sur les mappages pour chaque langage, voir Mappage des types de données entre SQL et les langages de traitement.
Écriture du gestionnaire¶
- Langues du gestionnaire:
Pour du contenu spécifique à une langage sur l’écriture d’un gestionnaire, voir Langues acceptées.
- Accès au réseau externe:
Vous pouvez accéder aux emplacements réseau externes avec un accès au réseau externe. Vous pouvez créer un accès sécurisé à des emplacements réseau spécifiques externes à Snowflake, puis utiliser cet accès à partir du code du gestionnaire.
- Journalisation et traçage:
Vous pouvez enregistrer l’activité du code en capturant les messages du journal et les événements de trace, en stockant les données dans une base de données que vous pouvez interroger ultérieurement.
Sécurité¶
Vous pouvez accorder des privilèges aux objets nécessaires pour qu’ils effectuent des actions SQL spécifiques avec une UDF ou une UDTF. Pour plus d’informations, voir Granting Privileges for User-Defined Functions
Les fonctions partagent certains problèmes de sécurité avec les procédures stockées. Pour plus d’informations, voir ci-dessous :
Vous pouvez aider le code du gestionnaire d’une procédure à s’exécuter en toute sécurité en suivant les bonnes pratiques décrites dans la section Pratiques de sécurité pour UDFs et procédures
Veillez à ce que les informations sensibles soient dissimulées aux utilisateurs qui ne devraient pas y avoir accès. Pour plus d’informations, voir Protection des informations sensibles avec les UDFs et les procédures stockées sécurisées
Déploiement du code du gestionnaire¶
Lors de la création d’une fonction, vous pouvez spécifier son gestionnaire (qui met en œuvre la logique de la fonction) en tant que code en ligne avec l’instruction CREATE FUNCTION ou en tant que code externe à l’instruction, tel que du code compilé et copié dans une zone de préparation.
Pour plus d’informations, voir Conserver le code du gestionnaire en ligne ou dans une zone de préparation.
Créer et appeler des fonctions¶
Vous utilisez SQL pour créer et appeler une fonction définie par l’utilisateur.
Pour créer une fonction, exécutez l’instruction CREATE FUNCTION, en spécifiant le gestionnaire de la fonction. Pour plus d’informations, voir Création d’une UDF.
Pour appeler une fonction, il faut exécuter une instruction SQL SELECT qui spécifie la fonction en tant que paramètre. Pour plus d’informations, voir Appel d’une UDF.