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

lgbo-ustc pushed a commit to branch bug_12169
in repository https://gitbox.apache.org/repos/asf/gluten.git

commit 400856800948aa259d0e595abb61951fcc5ce2b6
Author: lgbo-ustc <[email protected]>
AuthorDate: Thu May 28 19:42:59 2026 +0800

    [CH] Fix str_to_map nullable input null-map access
    
    SparkFunctionStrToMap iterates rows with index i, but the nullable string 
path checked null_map[n], where n is offsets.size(). For any non-empty nullable 
input this reads one element past the null map and can produce an incorrect 
null decision, undefined behavior, or a crash.
    
    Use the current row index when reading the nullable null map. Add a 
ClickHouse backend regression test that evaluates str_to_map over a nullable 
string expression containing both null and non-null rows, then compares the 
result with vanilla Spark.
---
 .../gluten/execution/GlutenFunctionValidateSuite.scala     | 14 ++++++++++++++
 cpp-ch/local-engine/Functions/SparkFunctionStrToMap.cpp    |  2 +-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git 
a/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenFunctionValidateSuite.scala
 
b/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenFunctionValidateSuite.scala
index 6a0196e2b1..66ea6c9866 100644
--- 
a/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenFunctionValidateSuite.scala
+++ 
b/backends-clickhouse/src/test/scala/org/apache/gluten/execution/GlutenFunctionValidateSuite.scala
@@ -489,6 +489,20 @@ class GlutenFunctionValidateSuite extends 
GlutenClickHouseWholeStageTransformerS
     runQueryAndCompare(sql1)(checkGlutenPlan[ProjectExecTransformer])
   }
 
+  test("test str2map with nullable string input") {
+    val sql =
+      """
+        |select id, str_to_map(str, ',', ':')
+        |from (
+        |  select id,
+        |    if(id = 1, cast(null as string), concat('k:', cast(id as 
string))) as str
+        |  from range(4)
+        |)
+        |order by id
+        |""".stripMargin
+    runQueryAndCompare(sql)(checkGlutenPlan[ProjectExecTransformer])
+  }
+
   test("test parse_url") {
     val sql1 =
       """
diff --git a/cpp-ch/local-engine/Functions/SparkFunctionStrToMap.cpp 
b/cpp-ch/local-engine/Functions/SparkFunctionStrToMap.cpp
index 8936ea0d04..e9c1d80c06 100644
--- a/cpp-ch/local-engine/Functions/SparkFunctionStrToMap.cpp
+++ b/cpp-ch/local-engine/Functions/SparkFunctionStrToMap.cpp
@@ -240,7 +240,7 @@ public:
 
         for (size_t i = 0, n = offsets.size(); i < n; ++i)
         {
-            if (null_map && (*null_map)[n] != 0)
+            if (null_map && (*null_map)[i] != 0)
                 col_map->insertDefault();
             else
             {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to