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.

  • 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.

  • Si la définition d’UDF appelle la fonction CURRENT_DATABASE ou CURRENT_SCHEMA, la fonction évalue la base de données ou le schéma qui contient l’UDF, et non la base de données ou le schéma de la session que vous spécifiez avec une commande USE <objet> ou que vous sélectionnez avec le sélecteur de contexte dans Snowsight.

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
$$;
Copy

Le code de l’exemple suivant exécute l’UDF addone.

SELECT addone(3);
Copy

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 :

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

1

Pour plus d’informations sur les limites du partage d’UDFs Java , voir Limitations générales.

2

Pour plus d’informations sur les limites du partage d’UDFs Python, voir Limitations générales.

3

Pour plus d’informations sur les limites du partage d’UDFs Scala, voir Limites liées aux UDF Scala.

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 :

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.