This is an automated email from the ASF dual-hosted git repository. yangjie01 pushed a commit to branch branch-3.5 in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-3.5 by this push: new ad370115609 [SPARK-44525][SQL] Improve error message when Invoke method is not found ad370115609 is described below commit ad370115609cf302abb486d31c5460468979bd33 Author: Cheng Pan <cheng...@apache.org> AuthorDate: Wed Jul 26 16:34:08 2023 +0800 [SPARK-44525][SQL] Improve error message when Invoke method is not found ### What changes were proposed in this pull request? This PR aims to improve the error message when `Invoke`'s `method` is not found. ### Why are the changes needed? Currently, the error message is not clear when `Invoke`'s `method` is not found. There is one error message I have encountered, which is not much helpful to find the root cause. ``` org.apache.spark.SparkException: [INTERNAL_ERROR] A method named "invoke" is not declared in any enclosing class nor any supertype at org.apache.spark.SparkException$.internalError(SparkException.scala:77) at org.apache.spark.SparkException$.internalError(SparkException.scala:81) at org.apache.spark.sql.errors.QueryExecutionErrors$.methodNotDeclaredError(QueryExecutionErrors.scala:452) at org.apache.spark.sql.catalyst.expressions.objects.InvokeLike.findMethod(objects.scala:173) at org.apache.spark.sql.catalyst.expressions.objects.InvokeLike.findMethod$(objects.scala:170) at org.apache.spark.sql.catalyst.expressions.objects.Invoke.findMethod(objects.scala:363) at org.apache.spark.sql.catalyst.expressions.objects.Invoke.method$lzycompute(objects.scala:391) at org.apache.spark.sql.catalyst.expressions.objects.Invoke.method(objects.scala:389) at org.apache.spark.sql.catalyst.expressions.objects.Invoke.eval(objects.scala:401) at org.apache.spark.sql.catalyst.expressions.HashExpression.eval(hash.scala:292) at org.apache.spark.sql.catalyst.expressions.Pmod.eval(arithmetic.scala:1054) ``` ### Does this PR introduce _any_ user-facing change? Yes, Spark returns a more clear error message. ### How was this patch tested? Add UT. Closes #42128 from pan3793/SPARK-44525. Authored-by: Cheng Pan <cheng...@apache.org> Signed-off-by: yangjie01 <yangji...@baidu.com> (cherry picked from commit a84e2b1eee3bb868f140bffeba4e19b1a56fa3fb) Signed-off-by: yangjie01 <yangji...@baidu.com> --- .../sql/catalyst/expressions/objects/objects.scala | 2 +- .../spark/sql/errors/QueryExecutionErrors.scala | 9 ++++++ .../expressions/ObjectExpressionsSuite.scala | 34 +++++++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala index fec60aef1bf..32bcdaf8609 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala @@ -185,7 +185,7 @@ trait InvokeLike extends Expression with NonSQLExpression with ImplicitCastInput final def findMethod(cls: Class[_], functionName: String, argClasses: Seq[Class[_]]): Method = { val method = MethodUtils.getMatchingAccessibleMethod(cls, functionName, argClasses: _*) if (method == null) { - throw QueryExecutionErrors.methodNotDeclaredError(functionName) + throw QueryExecutionErrors.methodNotFoundError(cls, functionName, argClasses) } else { method } diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala index 2e65d672698..2d0e29b1032 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/errors/QueryExecutionErrors.scala @@ -464,6 +464,15 @@ private[sql] object QueryExecutionErrors extends QueryErrorsBase { s"""A method named "$name" is not declared in any enclosing class nor any supertype""") } + def methodNotFoundError( + cls: Class[_], + functionName: String, + argClasses: Seq[Class[_]]): Throwable = { + SparkException.internalError( + s"Couldn't find method $functionName with arguments " + + s"${argClasses.mkString("(", ", ", ")")} on $cls.") + } + def constructorNotFoundError(cls: String): SparkRuntimeException = { new SparkRuntimeException( errorClass = "_LEGACY_ERROR_TEMP_2020", diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ObjectExpressionsSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ObjectExpressionsSuite.scala index 63edba80ec8..73da5f4d3af 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ObjectExpressionsSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ObjectExpressionsSuite.scala @@ -25,7 +25,7 @@ import scala.reflect.ClassTag import scala.reflect.runtime.universe.TypeTag import scala.util.Random -import org.apache.spark.{SparkConf, SparkFunSuite, SparkRuntimeException} +import org.apache.spark.{SparkConf, SparkException, SparkFunSuite, SparkRuntimeException} import org.apache.spark.serializer.{JavaSerializer, KryoSerializer} import org.apache.spark.sql.{RandomDataGenerator, Row} import org.apache.spark.sql.catalyst.{CatalystTypeConverters, InternalRow, ScalaReflection, ScroogeLikeExample} @@ -73,6 +73,38 @@ class ObjectExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper { checkEvaluationWithMutableProjection(invoke, null, inputRow) } + test("SPARK-44525: Invoke could not find method") { + val inputRow = InternalRow(new Object) + val inputObject = BoundReference(0, ObjectType(classOf[Object]), nullable = false) + + checkError( + exception = intercept[SparkException] { + Invoke(inputObject, "zeroArgNotExistMethod", IntegerType).eval(inputRow) + }, + errorClass = "INTERNAL_ERROR", + parameters = Map("message" -> + ("Couldn't find method zeroArgNotExistMethod with arguments " + + "() on class java.lang.Object.") + ) + ) + + checkError( + exception = intercept[SparkException] { + Invoke( + inputObject, + "oneArgNotExistMethod", + IntegerType, + Seq(Literal.fromObject(UTF8String.fromString("dummyInputString"))), + Seq(StringType)).eval(inputRow) + }, + errorClass = "INTERNAL_ERROR", + parameters = Map("message" -> + ("Couldn't find method oneArgNotExistMethod with arguments " + + "(class org.apache.spark.unsafe.types.UTF8String) on class java.lang.Object.") + ) + ) + } + test("MapObjects should make copies of unsafe-backed data") { // test UnsafeRow-backed data val structEncoder = ExpressionEncoder[Array[Tuple2[java.lang.Integer, java.lang.Integer]]] --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org For additional commands, e-mail: commits-h...@spark.apache.org