You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by ya...@apache.org on 2023/07/26 08:34:46 UTC
[spark] branch branch-3.5 updated: [SPARK-44525][SQL] Improve error message when Invoke method is not found
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 <ch...@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 <ch...@apache.org>
Signed-off-by: yangjie01 <ya...@baidu.com>
(cherry picked from commit a84e2b1eee3bb868f140bffeba4e19b1a56fa3fb)
Signed-off-by: yangjie01 <ya...@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-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org