diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/generators.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/generators.scala index 5214bff3543af..1079f0a333dd0 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/generators.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/generators.scala @@ -444,7 +444,8 @@ case class Inline(child: Expression) extends UnaryExpression with CollectionGene } override def elementSchema: StructType = child.dataType match { - case ArrayType(st: StructType, _) => st + case ArrayType(st: StructType, false) => st + case ArrayType(st: StructType, true) => st.asNullable } override def collectionType: DataType = child.dataType diff --git a/sql/core/src/test/scala/org/apache/spark/sql/GeneratorFunctionSuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/GeneratorFunctionSuite.scala index 436ccb08294b3..ef87e10946b62 100644 --- a/sql/core/src/test/scala/org/apache/spark/sql/GeneratorFunctionSuite.scala +++ b/sql/core/src/test/scala/org/apache/spark/sql/GeneratorFunctionSuite.scala @@ -388,6 +388,31 @@ class GeneratorFunctionSuite extends QueryTest with SharedSparkSession { Row(0, 1) :: Row(3, 4) :: Row(6, 7) :: Row(null, null) :: Row(null, null) :: Nil) } } + + test("SPARK-39061: inline should handle null struct") { + val df = sql( + """select * from values + |( + | 1, + | array( + | named_struct('c1', 0, 'c2', 1), + | null, + | named_struct('c1', 2, 'c2', 3), + | null + | ) + |) + |as tbl(a, b) + """.stripMargin) + df.createOrReplaceTempView("t1") + + checkAnswer( + sql("select inline(b) from t1"), + Row(0, 1) :: Row(null, null) :: Row(2, 3) :: Row(null, null) :: Nil) + + checkAnswer( + sql("select a, inline(b) from t1"), + Row(1, 0, 1) :: Row(1, null, null) :: Row(1, 2, 3) :: Row(1, null, null) :: Nil) + } } case class EmptyGenerator() extends Generator with LeafLike[Expression] {