Skip to content

Commit ae131b4

Browse files
Mark Andreevmrk-andreev
Mark Andreev
authored andcommitted
SPARK-XXXXX ValidateExternalType should return child in error
1 parent f70d41a commit ae131b4

File tree

2 files changed

+38
-2
lines changed

2 files changed

+38
-2
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/objects/objects.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -2057,14 +2057,14 @@ case class ValidateExternalType(child: Expression, expected: DataType, externalD
20572057
if (checkType(input)) {
20582058
input
20592059
} else {
2060-
throw new RuntimeException(s"${input.getClass.getName}$errMsg")
2060+
throw new RuntimeException(s"${input.getClass.getName}$errMsg at $child")
20612061
}
20622062
}
20632063

20642064
override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
20652065
// Use unnamed reference that doesn't create a local field here to reduce the number of fields
20662066
// because errMsgField is used only when the type doesn't match.
2067-
val errMsgField = ctx.addReferenceObj("errMsg", errMsg)
2067+
val errMsgField = ctx.addReferenceObj("errMsg", errMsg + " at " + child)
20682068
val input = child.genCode(ctx)
20692069
val obj = input.value
20702070
def genCheckTypes(classes: Seq[Class[_]]): String = {

sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/ObjectExpressionsSuite.scala

+36
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,42 @@ class ObjectExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
556556
"java.lang.Integer is not a valid external type for schema of double")
557557
}
558558

559+
test("SPARK-XXXXX ValidateExternalType should return child in error") {
560+
val inputObject = BoundReference(0, ObjectType(classOf[Row]), nullable = true)
561+
Seq(
562+
(true, BooleanType),
563+
(2.toByte, ByteType),
564+
(5.toShort, ShortType),
565+
(23, IntegerType),
566+
(61L, LongType),
567+
(1.0f, FloatType),
568+
(10.0, DoubleType),
569+
("abcd".getBytes, BinaryType),
570+
("abcd", StringType),
571+
(BigDecimal.valueOf(10), DecimalType.IntDecimal),
572+
(IntervalUtils.stringToInterval(UTF8String.fromString("interval 3 day")),
573+
CalendarIntervalType),
574+
(java.math.BigDecimal.valueOf(10), DecimalType.BigIntDecimal),
575+
(Array(3, 2, 1), ArrayType(IntegerType))
576+
).foreach { case (input, dt) =>
577+
val enc = RowEncoder.encoderForDataType(dt, lenient = false)
578+
val validateType = ValidateExternalType(
579+
GetExternalRowField(inputObject, index = 0, fieldName = "c0"),
580+
dt,
581+
EncoderUtils.lenientExternalDataTypeFor(enc))
582+
checkObjectExprEvaluation(validateType, input, InternalRow.fromSeq(Seq(Row(input))))
583+
}
584+
585+
checkExceptionInExpression[RuntimeException](
586+
ValidateExternalType(
587+
GetExternalRowField(inputObject, index = 0, fieldName = "c0"),
588+
DoubleType,
589+
DoubleType),
590+
InternalRow.fromSeq(Seq(Row(1))),
591+
"java.lang.Integer is not a valid external type for schema of double" +
592+
" at getexternalrowfield(input[0, org.apache.spark.sql.Row, true], 0, c0)")
593+
}
594+
559595
private def javaMapSerializerFor(
560596
keyClazz: Class[_],
561597
valueClazz: Class[_])(inputObject: Expression): Expression = {

0 commit comments

Comments
 (0)