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