Permalink
Browse files

Fix

  • Loading branch information...
maropu committed Apr 12, 2018
1 parent 264f129 commit 3da287be685a018b1148bbc634e6462fc112b846
@@ -17,6 +17,10 @@
package org.apache.spark.sql.catalyst
import java.lang.reflect.Constructor
import org.apache.commons.lang3.reflect.ConstructorUtils
import org.apache.spark.sql.catalyst.analysis.{GetColumnByOrdinal, UnresolvedAttribute, UnresolvedExtractValue}
import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.expressions.objects._
@@ -781,6 +785,15 @@ object ScalaReflection extends ScalaReflection {
}
}
/**
* Finds an accessible constructor with compatible parameters. This is a more flexible search
* than the exact matching algorithm in `Class.getConstructor`. The first assignment-compatible
* matching constructor is returned. Otherwise, it returns `None`.
*/
def findConstructor(cls: Class[_], paramTypes: Seq[Class[_]]): Option[Constructor[_]] = {
Option(ConstructorUtils.getMatchingAccessibleConstructor(cls, paramTypes: _*))
}
/**
* Whether the fields of the given type is defined entirely by its constructor parameters.
*/
@@ -439,34 +439,22 @@ case class NewInstance(
childrenResolved && !needOuterPointer
}
private lazy val constructor: (Seq[AnyRef]) => Any = {
val paramTypes = arguments.map { expr =>
CallMethodViaReflection.typeMapping.getOrElse(expr.dataType,
Seq(expr.dataType.asInstanceOf[ObjectType].cls))
}
val findConstructor = (types: Seq[Seq[Class[_]]]) => {
val constructorOption = cls.getConstructors.find { c =>
if (c.getParameterCount == types.length) {
c.getParameterTypes.zip(types).forall { case (constructorType, candidateTypes) =>
candidateTypes.exists {
case tpe => constructorType.isAssignableFrom(tpe)
}
}
} else {
false
}
@transient private lazy val constructor: (Seq[AnyRef]) => Any = {
val paramTypes = ScalaReflection.expressionJavaClasses(arguments)
val getConstructor = (paramClazz: Seq[Class[_]]) => {
ScalaReflection.findConstructor(cls, paramClazz).getOrElse {
sys.error(s"Couldn't find a valid constructor on $cls")
}
assert(constructorOption.isDefined)
constructorOption.get
}
outerPointer.map { p =>
val outerObj = p()
val c = findConstructor(Seq(outerObj.getClass) +: paramTypes)
val d = outerObj.getClass +: paramTypes
val c = getConstructor(outerObj.getClass +: paramTypes)
(args: Seq[AnyRef]) => {
c.newInstance(outerObj +: args: _*)
}
}.getOrElse {
val c = findConstructor(paramTypes)
val c = getConstructor(paramTypes)
(args: Seq[AnyRef]) => {
c.newInstance(args: _*)
}

0 comments on commit 3da287b

Please sign in to comment.