次の方法で共有


ユーザー定義スカラー関数 - Scala

この記事には、Scala ユーザー定義関数 (UDF) の例が含まれています。 ここでは、UDF の登録方法、UDF の呼び出し方法、Spark SQL での部分式の評価順序に関する注意点を示します。 詳しくは、「外部ユーザー定義スカラー関数 (UDF)」をご覧ください。

重要

共有アクセス モードの Unity Catalog 対応クラスターでの Scala UDF のサポートは、パブリック プレビューの段階にあり、Databricks Runtime 14.2 以降が必要です。

Note

関数を UDF として登録する

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

Spark SQL で UDF を呼び出す

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

DataFrame で UDF を使用する

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"))

評価順序と null チェック

Spark SQL (SQL、DataFrame、Dataset API を含む) では、部分式の評価の順序は保証されません。 特に、演算子や関数の入力は、必ずしも左から右へ、またはその他の決まった順序で評価されるとは限りません。 たとえば、AND および OR 論理式には、左から右への "短絡" セマンティクスはありません。

したがって、クエリの最適化および計画の際に式や句の順序は並べ替えられる可能性があるため、ブール式の副作用や評価の順序および WHEREHAVING 句の順序に依存することは危険です。 具体的には、UDF が null チェックのために SQL の短絡セマンティクスに依存している場合、UDF を呼び出す前に、null チェックが行われる保証はありません。 たとえば、次のように入力します。

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

この WHERE 句を使用しても、null を除外した後に strlen UDF が呼び出されることは保証されません。

適切な null チェックを実行するには、次のいずれかを実行することをお勧めします。

  • UDF 自体を null で認識し、UDF 自体の内部で null チェックを実行する
  • IF または CASE WHEN 式を使用して null チェックを実行し、条件分岐で UDF を呼び出す
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