Limites liées aux UDF JavaScript

Pour assurer la stabilité dans l’environnement Snowflake, Snowflake impose les limites suivantes aux UDFs JavaScript. Ces limitations ne sont pas appelées lors de la création d’UDF, mais plutôt lors de l’exécution au moment de l’appel de l’UDF. Cette rubrique couvre les exigences générales et les détails d’utilisation des UDF (fonctions définies par l’utilisateur) JavaScript, ainsi que les limitations spécifiques aux UDFs JavaScript.

Dans ce chapitre :

Taille maximale du code source JavaScript

Snowflake limite la taille maximale du code source JavaScript dans le corps d’une UDF JavaScript. Snowflake recommande de limiter la taille à 100 KB. (Le code est stocké sous une forme compressée et la limite exacte dépend de la capacité de compression du code).

La consommation d’une trop grande quantité de mémoire entraînera l’échec de l’UDF

Les UDFs JavaScript échoueront si elles consomment trop de mémoire. La limite spécifique est susceptible d’être modifiée. L’utilisation d’une trop grande quantité de mémoire entraînera le retour d’une erreur.

Un délai d’exécution trop long entraînera l’arrêt de l’UDF et l’envoi d’un message d’erreur

Les UDFs JavaScript qui prennent trop de temps à se terminer seront arrêtées et une erreur sera retournée à l’utilisateur. De plus, les UDFs JavaScript qui commencent des boucles sans fin entraîneront des erreurs.

Une profondeur de pile excessive entraîne une erreur

Une profondeur de pile excessive due à la récursion entraînera une erreur.

État global

Snowflake préserve généralement l’état global JavaScript entre les itérations d’une UDF. Cependant, vous ne devez pas vous fier aux modifications précédentes de l’état global disponibles entre les appels de fonctions. De plus, vous ne devez pas supposer que toutes les lignes s’exécuteront dans le même environnement JavaScript.

Dans la pratique, l’état global est pertinent dans les cas suivants :

  • Logique d’initialisation complexe/coûteuse. Par défaut, le code de l’UDF fourni est évalué pour chaque ligne traitée. Si ce code contient une logique complexe, cela pourrait être inefficace.

  • Les fonctions qui contiennent du code qui n’est pas idempotent. Un modèle typique serait celui-ci :

    Date.prototype._originalToString = Date.prototype.toString;
    Date.prototype.toString = function() {
      /* ... SOME CUSTOM CODE ... */
      this._originalToString()
      }
    
    Copy

    La première fois que ce code est exécuté, il change l’état de toString et _originalToString. Ces changements sont conservés dans l’état global, et la deuxième fois que ce code est exécuté, les valeurs sont à nouveau modifiées de manière à créer une récursion. La deuxième fois que toString est appelé, le code se répète à l’infini (jusqu’à ce qu’il n’y ait plus d’espace de pile).

Pour ces situations, un modèle recommandé est de garantir que le code pertinent n’est évalué qu’une seule fois, en utilisant la sémantique des variables globales de JavaScript. Par exemple :

var setup = function() {
/* SETUP LOGIC */
};

if (typeof(setup_done) === "undefined") {
  setup();
  setup_done = true;  // setting global variable to true
}
Copy

Notez que ce mécanisme n’est sûr que pour la mise en cache des effets de l’évaluation du code. Il n’est pas garanti qu’après une initialisation, le contexte global sera préservé pour toutes les lignes, et aucune logique métier ne doit en dépendre.

Bibliothèques JavaScript

Les UDFs JavaScript acceptent l’accès à la bibliothèque JavaScript standard. Notez que ceci exclut de nombreux objets et de nombreuses méthodes généralement fournis par les navigateurs. Il n’existe aucun mécanisme pour importer, inclure ou appeler des bibliothèques supplémentaires. Tout le code requis doit être incorporé dans l’UDF.

De plus, la fonction eval() JavaScript intégrée est désactivée.

Taille et profondeur de la variante retournée

Les objets de variantes renvoyés sont soumis à des limitations de taille et de profondeur d’imbrication :

Taille

Actuellement limité à plusieurs mégaoctets, mais sujet à changement.

Profondeur

Actuellement limité à une profondeur d’imbrication de 1 000, mais sujet à changement.

Si un objet est trop grand ou trop profond, une erreur est retournée lorsque l’UDF est appelé.

Les contraintes de type d’argument et de retour sont parfois ignorées

Certaines caractéristiques de type déclarées pour un argument ou une valeur de retour seront ignorées lors de l’appel de l’UDF. Dans ces cas, la valeur reçue peut être utilisée telle quelle, qu’elle soit ou non conforme aux contraintes spécifiées dans la déclaration.

Les éléments suivants sont ignorés pour les UDFs dont la logique est écrite en JavaScript :

  • Longueur des arguments de type VARCHAR

Exemple

Le code de l’exemple suivant déclare que l’argument arg1 et la valeur de retour doivent être un VARCHAR d’une longueur maximale d’un caractère. Cependant, l’appel à cette fonction avec un arg1 dont la valeur est supérieure à un caractère aboutira comme si la contrainte n’était pas spécifiée.

CREATE OR REPLACE FUNCTION tf (arg1 VARCHAR(1))
RETURNS VARCHAR(1)
LANGUAGE JAVASCRIPT AS 'return A.substr(3, 3);';
Copy