Share via


Door de gebruiker gedefinieerde scalaire functies - Scala

Dit artikel bevat voorbeelden van een door de gebruiker gedefinieerde functie (UDF) van Scala. Het laat zien hoe u UDF's registreert, UDF's aanroept en opmerkingen maakt met betrekking tot de evaluatievolgorde van subexpressies in Spark SQL. Zie Door de gebruiker gedefinieerde scalaire functies (UDF's) voor meer informatie.

Belangrijk

Ondersteuning voor Scala UDF's in clusters met gedeelde toegang met gedeelde toegang is beschikbaar in openbare preview en vereist Databricks Runtime 14.2 en hoger.

Notitie

Een functie registreren als een UDF

val squared = (s: Long) => {
  s * s
}
spark.udf.register("square", squared)

De UDF aanroepen in Spark SQL

spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test

UDF gebruiken met 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"))

Evaluatievolgorde en null-controle

Spark SQL (inclusief SQL en dataframe- en gegevensset-API's) garandeert niet de volgorde van evaluatie van subexpressies. Met name worden de invoer van een operator of functie niet noodzakelijkerwijs van links naar rechts of in een andere vaste volgorde geƫvalueerd. Logische en OR expressies hebben bijvoorbeeld AND geen semantiek van links-naar-rechts 'kortsluiting'.

Daarom is het gevaarlijk om te vertrouwen op de bijwerkingen of de volgorde van evaluatie van Boole-expressies, en de volgorde van WHERE en HAVING componenten, omdat dergelijke expressies en componenten tijdens queryoptimalisatie en -planning opnieuw kunnen worden gerangschikt. Als een UDF afhankelijk is van kortsluitingssemantiek in SQL voor null-controle, is er geen garantie dat de null-controle plaatsvindt voordat de UDF wordt aanroepen. Bijvoorbeeld:

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

Deze WHERE component garandeert niet dat de strlen UDF wordt aangeroepen nadat null-waarden zijn uitgefilterd.

Als u de juiste null-controle wilt uitvoeren, raden we u aan een van de volgende handelingen uit te voeren:

  • De UDF zelf null-aware maken en null-controle uitvoeren in de UDF zelf
  • Gebruik IF of CASE WHEN expressies om de null-controle uit te voeren en de UDF aan te roepen in een voorwaardelijke vertakking
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