Como chamar uma UDF¶
Você pode chamar uma função definida pelo usuário (UDF) ou uma função de tabela definida pelo usuário (UDTF) da mesma forma que você chama outras funções.
Neste tópico:
Como chamar uma UDF¶
Em geral, você chama uma UDF da mesma forma que você chama outras funções.
O código no exemplo a seguir chama uma UDF chamada my_udf
, especificando column_1
de my_table
como um argumento.
SELECT my_udf(column_1) FROM my_table;
Como chamar uma UDTF¶
Você pode chamar uma UDTF da mesma forma como você chamaria qualquer função de tabela. Ao chamar uma UDTF na cláusula FROM de uma consulta, especifique o nome e os argumentos da UDTF dentro dos parênteses que seguem a palavra-chave TABLE.
Em outras palavras, use um formulário como o seguinte para a palavra-chave TABLE quando chamar uma UDTF:
SELECT ...
FROM TABLE ( udtf_name (udtf_arguments) )
O código no exemplo a seguir chama a função de tabela my_java_udtf
, especificando um literal DATE no argumento '2021-01-16'::DATE
.
SELECT ...
FROM TABLE(my_java_udtf('2021-01-16'::DATE));
O argumento para uma função de tabela pode ser uma expressão e não apenas um literal. Por exemplo, uma função de tabela pode ser chamada usando uma coluna de uma tabela. Alguns exemplos estão abaixo, inclusive na seção Exemplos.
Para obter mais informações sobre as funções de tabela em geral, consulte função de tabela.
Nota
Você não pode chamar uma UDF dentro da cláusula DEFAULT de uma instrução CREATE TABLE.
Como usar uma tabela ou UDTF como entrada para uma UDTF¶
A entrada para uma função de tabela pode vir de uma tabela ou de outra UDTF, como documentado em Como usar uma tabela como entrada para uma função de tabela.
O exemplo abaixo mostra como utilizar uma tabela para fornecer entrada para a UDTF split_file_into_words
:
create table file_names (file_name varchar);
insert into file_names (file_name) values ('sample.txt'),
('sample_2.txt');
select f.file_name, w.word
from file_names as f, table(split_file_into_words(f.file_name)) as w;
A saída se assemelha ao seguinte:
+-------------------+------------+
| FILE_NAME | WORD |
+-------------------+------------+
| sample_data.txt | some |
| sample_data.txt | words |
| sample_data_2.txt | additional |
| sample_data_2.txt | words |
+-------------------+------------+
A cláusula IMPORTS da UDTF deve especificar o nome e o caminho de cada arquivo passado para a UDTF. Por exemplo:
create function split_file_into_words(inputFileName string)
...
imports = ('@inline_jars/sample.txt', '@inline_jars/sample_2.txt')
...
Cada arquivo já deve ter sido copiado para um estágio (neste caso, o estágio denominado @inline_jars
) antes que a UDTF leia o arquivo.
Para obter um exemplo de uso de uma UDTF como entrada para outra UDTF, consulte Exemplos estendidos usando valores de tabela e outras UDTFs como entrada na documentação UDTF de JavaScript.
Funções de tabela e partições¶
Antes que linhas sejam passadas para funções de tabela, elas podem ser agrupadas em partições. A criação de partições tem dois benefícios principais:
A criação de partições permite que o Snowflake divida a carga de trabalho para melhorar a paralelização e, assim, o desempenho.
A criação de partições permite que o Snowflake processe todas as linhas com uma característica comum como um grupo. Você pode retornar resultados que são baseados em todas as linhas do grupo e não apenas em linhas individuais.
Por exemplo, você pode particionar dados de preços de ações em um grupo por ação. Todos os preços de ações de uma empresa individual podem ser analisados em conjunto, enquanto os preços das ações de cada empresa podem ser analisados independentemente de qualquer outra empresa.
Dados podem ser particionados de forma explícita ou implícita.
Particionamento explícito¶
Particionamento explícito em vários grupos
A instrução a seguir chama a UDTF chamada my_udtf
em partições individuais. Cada partição contém todas as linhas para as quais a expressão PARTITION BY
é avaliada como o mesmo valor (por exemplo, a mesma empresa ou símbolo de ação).
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol))
Particionamento explícito em um único grupo
A instrução a seguir chama a UDTF chamada my_udtf
em uma partição. A cláusula PARTITION BY <constante>
(neste caso PARTITION BY 1
) coloca todas as linhas na mesma partição.
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY 1))
Para obter um exemplo mais completo e realista, consulte Exemplos de como chamar UDTFs de Java em consultas, em particular a subseção intitulada Partição única.
Como ordenar linhas para partições
Para processar as linhas de cada partição em uma ordem especificada, inclua uma cláusula ORDER BY. Isso diz ao Snowflake para passar as linhas para o método do manipulador por linha na ordem especificada.
Por exemplo, se você quiser calcular a média móvel do preço de uma ação ao longo do tempo, ordene os preços das ações por carimbo de data/hora (e particione por símbolo de ação). O exemplo a seguir mostra como fazer isso:
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
Uma cláusula OVER pode conter uma cláusula ORDER BY mesmo sem uma cláusula PARTITION BY.
Lembre-se de que incluir uma cláusula ORDER BY dentro de uma cláusula OVER não é o mesmo que colocar uma cláusula ORDER BY no nível mais externo da consulta. Se você quiser que todos os resultados da consulta sejam encomendados, você precisa de uma cláusula ORDER BY separada. Por exemplo:
SELECT *
FROM stocks_table AS st,
TABLE(my_udtf(st.symbol, st.transaction_date, st.price) OVER (PARTITION BY st.symbol ORDER BY st.transaction_date))
ORDER BY st.symbol, st.transaction_date, st.transaction_time;
Notas de uso para particionamento explícito
Ao utilizar uma UDTF com uma cláusula PARTITION BY, a cláusula PARTITION BY deve utilizar uma referência de coluna ou uma expressão literal, não uma expressão geral. Por exemplo, o seguinte não é permitido:
SELECT * FROM udtf_table, TABLE(my_func(col1) OVER (PARTITION BY udtf_table.col2 * 2)); -- NO!
Particionamento implícito¶
Se uma função de tabela não particiona explicitamente as linhas usando uma cláusula PARTITION BY, o Snowflake normalmente divide as linhas implicitamente para usar processamento paralelo para melhorar o desempenho.
O número de partições normalmente é baseado em fatores como o tamanho do warehouse que processa a função e a cardinalidade da relação de entrada. As linhas normalmente são atribuídas a partições específicas com base em fatores como a localização física das linhas (por exemplo, por micropartição), de modo que o agrupamento da partição não tem significado.