Lignes directrices générales pour le codage de gestionnaires d’UDF Scala

Cette rubrique décrit les lignes directrices générales pour l’écriture de lignes de code pour le gestionnaire au format Scala. Pour des informations spécifiques aux gestionnaires de fonctions scalaires, voir Écriture d’une UDF scalaire en Scala.

Pour des suggestions sur la structuration de votre projet, l’empaquetage de votre code et la gestion des dépendances, reportez-vous à Projet de gestionnaire et empaquetage des UDF Scala.

Meilleures pratiques

  • Écrivez du code indépendant de la plate-forme.

    • Évitez le code qui suppose une architecture CPU spécifique (par exemple, x86).

    • Évitez le code qui suppose un système d’exploitation spécifique.

  • Si vous devez exécuter un code d’initialisation et que vous ne souhaitez pas l’inclure dans la méthode que vous appelez, vous pouvez placer le code d’initialisation dans un objet compagnon de votre classe de gestionnaire.

Écriture d’un gestionnaire

Vous pouvez écrire une UDF scalaire avec un gestionnaire écrit en Scala.

Le gestionnaire est appelé une fois pour chaque ligne transmise à l’UDF Scala. Une nouvelle instance de la classe n’est pas créée pour chaque ligne ; Snowflake peut appeler plusieurs fois la méthode du gestionnaire de la même instance.

Pour optimiser l’exécution de votre code, les seuils de temporisation de Snowflake diffèrent entre le temps nécessaire à l’initialisation de votre classe ou objet de gestionnaire et le temps nécessaire à l’exécution de sa méthode de gestionnaire. Snowflake accorde plus de temps pour initialiser la classe ou l’objet du gestionnaire en partant du principe que l’initialisation peut prendre plus de temps. Cela inclut le temps de chargement de votre UDF et le temps d’appel du constructeur de la classe contenant la méthode du gestionnaire, si un constructeur est défini.

Gestion des erreurs

Vous pouvez gérer les exceptions à l’aide des techniques courantes de gestion des exceptions afin de rattraper les erreurs dans la méthode du gestionnaire.

Si une exception se produit à l’intérieur de la méthode et n’est pas récupérée par celle-ci, Snowflake génère une erreur qui inclut la trace de la pile pour l’exception.

Vous pouvez explicitement lancer une erreur sans la capturer afin de terminer la requête et de produire une erreur SQL. Par exemple :

if (x < 0) throw new IllegalArgumentException("x must be non-negative.")
Copy

Lors du débogage, vous pouvez inclure des valeurs dans le texte du message d’erreur SQL. Pour ce faire :

  • Placez un corps de méthode Scala entier dans un bloc try-catch ;

  • Ajoutez les valeurs des arguments au message de l’erreur détectée ; et

  • Lancez une exception avec le message étendu.

Pour éviter de révéler des données sensibles, supprimez les valeurs des arguments avant de déployer les fichiers JAR dans un environnement de production.

Choisir les types de données

Lorsque vous écrivez votre gestionnaire, vous devez déclarer des types de données de paramètre et de retour (dans le langage du gestionnaire) qui correspondent bien aux types de données de paramètre et de retour des UDF (de SQL).

Lorsque l’UDF est appelée, Snowflake convertit les arguments de l’UDF des types de paramètres SQL vers les types de paramètres du gestionnaire. Lors du retour d’une valeur, Snowflake convertit la valeur de retour du type de retour du gestionnaire vers le type de retour de l’UDF.

Snowflake convertit les valeurs entre les types selon les mappages pris en charge entre les types de SQL et les types Scala. Pour plus d’informations sur ces mappages, voir Mappages de type de données SQL-Scala.

Lorsque vous choisissez les types de données des variables Scala, tenez compte des valeurs maximales et minimales possibles des données qui pourraient être envoyées de (et retournées à) Snowflake.

Création de l’UDF avec CREATE FUNCTION

Vous créez une UDF avec SQL en utilisant la commande CREATE FUNCTION, en spécifiant le code que vous avez écrit comme gestionnaire. Pour la référence de la commande, voir CREATE FUNCTION.

CREATE OR REPLACE FUNCTION <name> ( [ <arguments> ] )
  RETURNS <type>
  LANGUAGE SCALA
  [ IMPORTS = ( '<imports>' ) ]
  RUNTIME_VERSION = 2.12
  [ PACKAGES = ( '<package_name>' [, '<package_name>' . . .] ) ]
  [ TARGET_PATH = '<stage_path_and_file_name_to_write>' ]
  HANDLER = '<handler_class>.<handler_method>'
  [ AS '<scala_code>' ]
Copy

Pour associer le code du gestionnaire que vous avez écrit avec l’UDF, vous faites ce qui suit lors de l’exécution de CREATE FUNCTION :

  • Définissez LANGUAGE sur SCALA.

  • Définissez la valeur de la clause IMPORTS sur le chemin et le nom de la classe du gestionnaire si la classe se trouve dans un emplacement externe, par exemple sur une zone de préparation.

  • Définissez RUNTIME_VERSION sur la version de l’environnement d’exécution Scala requise par votre code.

  • Définissez la valeur de la clause PACKAGES sur le nom d’un ou plusieurs paquets, le cas échéant, requis par la classe du gestionnaire.

  • Définissez la valeur de la clause HANDLER comme étant le nom de l’objet et de la méthode du gestionnaire.

  • La clause AS '<scala_code>' est requise si le code du gestionnaire est spécifié en ligne avec CREATE FUNCTION.