diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala index 79b2985adc1d..6c72afae91e9 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/literals.scala @@ -243,7 +243,9 @@ object Literal { v.isInstanceOf[InternalRow] && { val row = v.asInstanceOf[InternalRow] st.fields.map(_.dataType).zipWithIndex.forall { - case (fieldDataType, i) => doValidate(row.get(i, fieldDataType), fieldDataType) + case (fieldDataType, i) => + // Do not need to validate null values. + row.isNullAt(i) || doValidate(row.get(i, fieldDataType), fieldDataType) } } case _ => false diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/LiteralExpressionSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/LiteralExpressionSuite.scala index f63b60f5ebba..d42e0b7d681d 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/LiteralExpressionSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/LiteralExpressionSuite.scala @@ -478,6 +478,24 @@ class LiteralExpressionSuite extends SparkFunSuite with ExpressionEvalHelper { UTF8String.fromString("Spark SQL")) } + // A generic internal row that throws exception when accessing null values + class NullAccessForbiddenGenericInternalRow(override val values: Array[Any]) + extends GenericInternalRow(values) { + override def get(ordinal: Int, dataType: DataType): AnyRef = { + if (values(ordinal) == null) { + throw new RuntimeException(s"Should not access null field at $ordinal!") + } + super.get(ordinal, dataType) + } + } + + test("SPARK-46634: literal validation should not drill down to null fields") { + val exceptionInternalRow = new NullAccessForbiddenGenericInternalRow(Array(null, 1)) + val schema = StructType.fromDDL("id INT, age INT") + // This should not fail because it should check whether the field is null before drilling down + Literal.validateLiteralValue(exceptionInternalRow, schema) + } + test("SPARK-46604: Literal support immutable ArraySeq") { import org.apache.spark.util.ArrayImplicits._ val immArraySeq = Array(1.0, 4.0).toImmutableArraySeq