Limitações de UDFs de JavaScript

Para garantir a estabilidade no ambiente Snowflake, o Snowflake coloca as seguintes limitações nas UDFs de JavaScript. Estas limitações não são invocadas no momento da criação da UDF, mas sim em tempo de execução, quando a UDF é chamada. Este tópico cobre os requisitos gerais da UDF (função definida pelo usuário) de JavaScript e detalhes de uso, bem como limitações que são específicas para as UDFs de JavaScript.

Neste tópico:

Tamanho máximo do código-fonte de JavaScript

O Snowflake limita o tamanho máximo do código-fonte JavaScript no corpo de uma UDF de JavaScript. O Snowflake recomenda limitar o tamanho a 100 KB. (O código é armazenado de forma compactada, e o limite exato depende da capacidade de compactação do código).

Consumir muita memória causará a falha da UDF

UDFs de JavaScript falharão se consumirem muita memória. O limite específico está sujeito a alterações. Usar muita memória resultará em um erro sendo retornado.

Demorar muito para concluir fará com que uma UDF seja inativada e retorne um erro

UDFs de JavaScript que demoram muito para serem concluídas serão eliminadas e um erro será retornado ao usuário. Além disso, as UDFs de JavaScript que entram em loops infinitos resultarão em erros.

O excesso de profundidade da pilha resultará em um erro

Um excesso de profundidade da pilha devido a recursão resultará em um erro.

Estado global

O Snowflake geralmente preserva o estado global do JavaScript entre as iterações de uma UDF. Entretanto, você não deve confiar que modificações anteriores ao estado global estejam disponíveis entre chamadas à função. Além disso, você não deve supor que todas as linhas serão executadas dentro do mesmo ambiente de JavaScript.

Na prática, o estado global é relevante com:

  • Lógica de inicialização complexa/cara. Por padrão, o código fornecido da UDF é avaliado para cada linha processada. Se esse código contiver uma lógica complexa, isso pode ser ineficiente.

  • Funções que contêm código que não é idempotente. Um padrão típico seria:

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

    A primeira vez que este código é executado, ele muda o estado de toString e _originalToString. Essas mudanças são preservadas no estado global, e na segunda vez que o código é executado, os valores são novamente alterados de forma a criar recursividade. A segunda vez que toString é chamado, o código é recursivo infinitamente (até esgotar o espaço da pilha).

Para estas situações, um padrão recomendado é garantir que o código relevante seja avaliado apenas uma vez, usando a semântica global da variável de JavaScript. Por exemplo:

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

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

Observe que esse mecanismo é seguro apenas para armazenar em cache os efeitos da avaliação do código. Não é garantido que, após uma inicialização, o contexto global seja preservado para todas as linhas e nenhuma lógica de negócios deve depender disso.

Bibliotecas JavaScript

As UDFs de JavaScript oferecem suporte ao acesso à biblioteca padrão JavaScript. Observe que isto exclui muitos objetos e métodos normalmente fornecidos por navegadores. Não há nenhum mecanismo para importar, incluir ou chamar bibliotecas adicionais. Todos os códigos necessários devem ser incorporados dentro da UDF.

Além disso, a função interna eval() do JavaScript está desativada.

Tamanho e profundidade da variante retornada

Objetos da variante retornada estão sujeitos a limitações de tamanho e profundidade de aninhamento:

Tamanho:

Atualmente limitado a vários megabytes, mas sujeito a mudanças.

Profundidade:

Atualmente limitado a uma profundidade de aninhamento de 1.000, mas sujeito a mudanças.

Se qualquer objeto for grande ou profundo demais, um erro será retornado quando a UDF for chamada.

As restrições de tipo de argumento e retorno às vezes são ignoradas

Certas características de tipo declaradas para um valor de retorno ou argumento serão ignoradas quando a UDF é chamada. Nesses casos, o valor recebido pode ser usado como recebido, esteja ou não em conformidade com as restrições especificadas na declaração.

Os seguintes são ignorados para UDFs cuja lógica está escrita em JavaScript:

  • Comprimento para argumentos do tipo VARCHAR

Exemplo

O código no exemplo a seguir declara que o argumento arg1 e o valor de retorno deve ser um VARCHAR com apenas um caractere. No entanto, chamar essa função com um arg1 cujo valor é maior que um caractere terá sucesso como se a restrição não tivesse sido especificada.

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