This is an automated email from the ASF dual-hosted git repository.

gengliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/master by this push:
     new 46a8f1f0df8 [SPARK-39818][SQL] Fix bug in ARRAY, STRUCT, MAP types 
with DEFAULT values with NULL field(s)
46a8f1f0df8 is described below

commit 46a8f1f0df83deeda6309f8377988a66ba059c10
Author: Daniel Tenedorio <daniel.tenedo...@databricks.com>
AuthorDate: Tue Jul 19 18:53:23 2022 -0700

    [SPARK-39818][SQL] Fix bug in ARRAY, STRUCT, MAP types with DEFAULT values 
with NULL field(s)
    
    ### What changes were proposed in this pull request?
    
    Fix bug in SQL string generation for literal values of ARRAY, STRUCT, MAP 
types with DEFAULT values with NULL field(s). Specifically, prevent Scala 
`MatchError`s from getting raised when attempting to call the `sql` method of 
the `Literal` expression for such values when one of their fields is `null`.
    
    ### Why are the changes needed?
    
    This fixes a bug by preventing exceptions from being inappropriately raised.
    
    ### Does this PR introduce _any_ user-facing change?
    
    No.
    
    ### How was this patch tested?
    
    This PR adds new unit test coverage.
    
    Closes #37229 from dtenedor/fix-bug-sql.
    
    Authored-by: Daniel Tenedorio <daniel.tenedo...@databricks.com>
    Signed-off-by: Gengliang Wang <gengli...@apache.org>
---
 .../apache/spark/sql/catalyst/expressions/literals.scala  | 14 +++++++-------
 .../catalyst/analysis/ExpressionTypeCheckingSuite.scala   | 15 +++++++++++++++
 2 files changed, 22 insertions(+), 7 deletions(-)

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 03678773ccc..a8c877a29de 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
@@ -494,20 +494,20 @@ case class Literal (value: Any, dataType: DataType) 
extends LeafExpression {
     case (row: GenericInternalRow, structType: StructType) =>
       val structNames: Array[String] = structType.fields.map(_.name)
       val structValues: Array[String] =
-        row.values.zip(structType.fields.map(_.dataType)).map {
-          case (value: Any, fieldType: DataType) =>
-            Literal(value, fieldType).sql
+        row.values.zip(structType.fields.map(_.dataType)).map { kv =>
+          Literal(kv._1, kv._2).sql
         }
       val structFields: Array[String] =
-        structNames.zip(structValues).map { kv => s"${kv._1}, ${kv._2}" }
+        structNames.zip(structValues).map {
+          kv => s"${kv._1}, ${kv._2}"
+        }
       s"NAMED_STRUCT(${structFields.mkString(", ")})"
     case (data: ArrayBasedMapData, mapType: MapType) =>
       val keyData = data.keyArray.asInstanceOf[GenericArrayData]
       val valueData = data.valueArray.asInstanceOf[GenericArrayData]
       val keysAndValues: Array[String] =
-        keyData.array.zip(valueData.array).map {
-          case (key: Any, value: Any) =>
-            s"${Literal(key, mapType.keyType).sql}, ${Literal(value, 
mapType.valueType).sql}"
+        keyData.array.zip(valueData.array).map { kv =>
+          s"${Literal(kv._1, mapType.keyType).sql}, ${Literal(kv._2, 
mapType.valueType).sql}"
         }
       s"MAP(${keysAndValues.mkString(", ")})"
     case _ => value.toString
diff --git 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ExpressionTypeCheckingSuite.scala
 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ExpressionTypeCheckingSuite.scala
index 9225a7dcbe4..0969089bd92 100644
--- 
a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ExpressionTypeCheckingSuite.scala
+++ 
b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/ExpressionTypeCheckingSuite.scala
@@ -240,4 +240,19 @@ class ExpressionTypeCheckingSuite extends SparkFunSuite 
with SQLHelper {
         "does not support ordering")
     }
   }
+
+  test("check types for SQL string generation") {
+    assert(Literal.create(Array(1, 2, 3), ArrayType(IntegerType)).sql ==
+      "ARRAY(1, 2, 3)")
+    assert(Literal.create(Array(1, 2, null), ArrayType(IntegerType)).sql ==
+      "ARRAY(1, 2, CAST(NULL AS INT))")
+    assert(Literal.default(StructType(Seq(StructField("col", 
StringType)))).sql ==
+      "NAMED_STRUCT(col, '')")
+    assert(Literal.default(StructType(Seq(StructField("col", NullType)))).sql 
==
+      "NAMED_STRUCT(col, NULL)")
+    assert(Literal.create(Map(42L -> true), MapType(LongType, 
BooleanType)).sql ==
+      "MAP(42L, true)")
+    assert(Literal.create(Map(42L -> null), MapType(LongType, NullType)).sql ==
+      "MAP(42L, NULL)")
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@spark.apache.org
For additional commands, e-mail: commits-h...@spark.apache.org

Reply via email to