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 renvoi 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