Funções escalares definidas pelo usuário - Scala
Este artigo contém exemplos de função definida pelo usuário (UDF) do Scala. Ele mostra como registrar UDFs, como invocar UDFs e advertências sobre a ordem de avaliação de subexpressões no Spark SQL. Consulte Funções escalares definidas pelo usuário externo (UDFs) para obter mais detalhes.
Importante
O suporte para UDFs Scala em clusters habilitados para Unity Catalog com modo de acesso compartilhado está em Visualização Pública e requer Databricks Runtime 14.2 e superior.
Nota
Registrar uma função como UDF
val squared = (s: Long) => {
s * s
}
spark.udf.register("square", squared)
Chamar o UDF no Spark SQL
spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test
Usar UDF com DataFrames
import org.apache.spark.sql.functions.{col, udf}
val squared = udf((s: Long) => s * s)
display(spark.range(1, 20).select(squared(col("id")) as "id_squared"))
Ordem de avaliação e verificação nula
O Spark SQL (incluindo SQL e as APIs DataFrame e Dataset) não garante a ordem de avaliação das subexpressões. Em particular, as entradas de um operador ou função não são necessariamente avaliadas da esquerda para a direita ou em qualquer outra ordem fixa. Por exemplo, a lógica AND
e OR
as expressões não têm semântica de "curto-circuito" da esquerda para a direita.
Portanto, é perigoso confiar nos efeitos colaterais ou na ordem de avaliação das expressões booleanas, e na ordem das e HAVING
cláusulas, uma vez que tais expressões e cláusulas podem ser reordenadas durante a otimização e o planejamento da WHERE
consulta. Especificamente, se um UDF depende de semântica de curto-circuito no SQL para verificação nula, não há garantia de que a verificação nula acontecerá antes de invocar o UDF. Por exemplo,
spark.udf.register("strlen", (s: String) => s.length)
spark.sql("select s from test1 where s is not null and strlen(s) > 1") // no guarantee
Esta WHERE
cláusula não garante que o strlen
UDF seja invocado após filtrar nulos.
Para executar a verificação nula adequada, recomendamos que você siga um destes procedimentos:
- Tornar a própria UDF nula e fazer verificação nula dentro da própria UDF
- Use
IF
ouCASE WHEN
expressões para fazer a verificação nula e invocar a UDF em uma ramificação condicional
spark.udf.register("strlen_nullsafe", (s: String) => if (s != null) s.length else -1)
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1") // ok
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários