Следующий снипп отлично работает в Spark 2.2.1, но дает довольно загадочное исключение во время выполнения Spark 2.3.0:
import sparkSession.implicits._
import org.apache.spark.sql.functions._
case class X(xid: Long, yid: Int)
case class Y(yid: Int, zid: Long)
case class Z(zid: Long, b: Boolean)
val xs = Seq(X(1L, 10)).toDS()
val ys = Seq(Y(10, 100L)).toDS()
val zs = Seq.empty[Z].toDS()
val j = xs
.join(ys, "yid")
.join(zs, Seq("zid"), "left")
.withColumn("BAM", when('b, "B").otherwise("NB"))
j.show()
В Spark 2.2.1 он печатает на консоли
+---+---+---+----+---+
|zid|yid|xid| b|BAM|
+---+---+---+----+---+
|100| 10| 1|null| NB|
+---+---+---+----+---+
В Spark 2.3.0 это приводит к:
org.apache.spark.sql.catalyst.analysis.UnresolvedException: Invalid call to dataType on unresolved object, tree: 'BAM
at org.apache.spark.sql.catalyst.analysis.UnresolvedAttribute.dataType(unresolved.scala:105)
at org.apache.spark.sql.types.StructType$$anonfun$fromAttributes$1.apply(StructType.scala:435)
at org.apache.spark.sql.types.StructType$$anonfun$fromAttributes$1.apply(StructType.scala:435)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:234)
at scala.collection.immutable.List.foreach(List.scala:392)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:234)
at scala.collection.immutable.List.map(List.scala:296)
at org.apache.spark.sql.types.StructType$.fromAttributes(StructType.scala:435)
at org.apache.spark.sql.catalyst.plans.QueryPlan.schema$lzycompute(QueryPlan.scala:157)
...
Кажется, что виновником является Dataset
, созданный из пустого Seq[Z]
. Когда вы меняете это на то, что также приведет к пусту Dataset[Z]
оно работает как в Spark 2.2.1, например
val zs = Seq(Z(10L, true)).toDS().filter('zid === 999L)
В руководстве по миграции от 2.2 до 2.3 указано:
Начиная с Spark 2.3, детерминированные предикаты Join/Filters, которые после первых недетерминированных предикатов также, если это возможно, также сдвигаются вниз/через дочерние операторы. В предыдущих версиях Spark эти фильтры не имеют права на преданное нажатие.
Связана ли эта ошибка или (известная) ошибка?