所以我发现SparkSQL UDF隐式地解包了UDF返回的Option
。
scala> sqlContext.udf.register("canUnwrapOption", (n: java.lang.Integer) => Option(n).map(_ + 1))
res4: org.apache.spark.sql.UserDefinedFunction = UserDefinedFunction(<function1>,IntegerType,List(IntegerType))
scala> sqlContext.sql("select canUnwrapOption(null)").show
+----+
| _c0|
+----+
|null|
+----+
scala> sqlContext.sql("select canUnwrapOption(1)").show
+---+
|_c0|
+---+
| 2|
+---+
这似乎真的有助于处理null
值。但它无法隐式包装Option
。
scala> sqlContext.udf.register("cannotWrapWithOption", (n: Option[java.lang.Integer]) => n.map(_ + 1))
res8: org.apache.spark.sql.UserDefinedFunction = UserDefinedFunction(<function1>,IntegerType,List(IntegerType))
scala> sqlContext.sql("select cannotWrapWithOption(1)").show
16/03/10 18:18:55 ERROR Executor: Exception in task 0.0 in stage 3.0 (TID 3)
java.lang.ClassCastException: java.lang.Integer cannot be cast to scala.Option
at $line28.$read$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$iwC$$anonfun$1.apply(<console>:26)
...
为什么支持那个而另一个不支持?