aboutsummaryrefslogtreecommitdiff
path: root/sql/catalyst/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'sql/catalyst/src/main')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala40
1 files changed, 39 insertions, 1 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala
index ad218cf88d..7f7dd51aa2 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/ScalaReflection.scala
@@ -312,12 +312,50 @@ object ScalaReflection extends ScalaReflection {
"array",
ObjectType(classOf[Array[Any]]))
- StaticInvoke(
+ val wrappedArray = StaticInvoke(
scala.collection.mutable.WrappedArray.getClass,
ObjectType(classOf[Seq[_]]),
"make",
array :: Nil)
+ if (localTypeOf[scala.collection.mutable.WrappedArray[_]] <:< t.erasure) {
+ wrappedArray
+ } else {
+ // Convert to another type using `to`
+ val cls = mirror.runtimeClass(t.typeSymbol.asClass)
+ import scala.collection.generic.CanBuildFrom
+ import scala.reflect.ClassTag
+
+ // Some canBuildFrom methods take an implicit ClassTag parameter
+ val cbfParams = try {
+ cls.getDeclaredMethod("canBuildFrom", classOf[ClassTag[_]])
+ StaticInvoke(
+ ClassTag.getClass,
+ ObjectType(classOf[ClassTag[_]]),
+ "apply",
+ StaticInvoke(
+ cls,
+ ObjectType(classOf[Class[_]]),
+ "getClass"
+ ) :: Nil
+ ) :: Nil
+ } catch {
+ case _: NoSuchMethodException => Nil
+ }
+
+ Invoke(
+ wrappedArray,
+ "to",
+ ObjectType(cls),
+ StaticInvoke(
+ cls,
+ ObjectType(classOf[CanBuildFrom[_, _, _]]),
+ "canBuildFrom",
+ cbfParams
+ ) :: Nil
+ )
+ }
+
case t if t <:< localTypeOf[Map[_, _]] =>
// TODO: add walked type path for map
val TypeRef(_, _, Seq(keyType, valueType)) = t