sunchao commented on code in PR #5414:
URL: https://github.com/apache/datafusion-comet/pull/5414#discussion_r3836460165


##########
spark/src/main/scala/org/apache/comet/DataTypeSupport.scala:
##########
@@ -54,8 +54,9 @@ trait DataTypeSupport {
           CalendarIntervalType =>
         true
       case StructType(fields) =>
-        fields.nonEmpty && fields.forall(f =>
-          isTypeSupported(f.dataType, f.name, fallbackReasons))
+        // A struct's `fields` can be empty -- e.g. Iceberg's `_partition` 
metadata column is
+        // exactly that on an unpartitioned table. It's still a value Comet 
can represent.
+        fields.forall(f => isTypeSupported(f.dataType, f.name, 
fallbackReasons))

Review Comment:
   [P2] Guard empty structs in FIRST_VALUE/LAST_VALUE windows
   
   This also admits empty-struct inputs to native windows that cannot handle 
them. Using the `marker: struct<>` LocalRelation from the new tests, enable 
`spark.comet.exec.localTableScan.enabled=true` with native shuffle and run 
`SELECT first_value(marker) OVER () FROM t` (no `ORDER BY`). The input can now 
stay native through `CometWindowExec`, which maps this to DataFusion 54.1's 
`FirstValue`. Its accumulator calls `ScalarValue::compact()`, whose 
`compact_view_buffers` struct branch reconstructs the array with 
`StructArray::new` even when there are no child fields, causing an Arrow panic. 
I reproduced this through the dependency's `WindowExpr::evaluate` on a valid 
three-row empty-struct batch; Spark returns three empty structs. `LAST_VALUE` 
fails identically, and the compaction is recursive, so 
nested/list/map-contained empty structs also fail. The old type gates kept 
these inputs on Spark. Please keep these windows on Spark for schemas 
containing empty structs until scalar compactio
 n is fixed.



##########
native/spark-expr/src/json_funcs/from_json.rs:
##########
@@ -150,27 +150,35 @@ fn json_string_to_struct(arr: &Arc<dyn Array>, schema: 
&DataType) -> Result<Arra
         } else {
             let json_str = string_array.value(row_idx);
 
-            // Parse JSON (PERMISSIVE mode: return null fields on error)
-            match serde_json::from_str::<serde_json::Value>(json_str) {
-                Ok(json_value) => {
-                    if let serde_json::Value::Object(obj) = json_value {
-                        // Struct is not null, extract each field
-                        *struct_null = true;
-                        for (field, builder) in 
fields.iter().zip(field_builders.iter_mut()) {
-                            let field_value = obj.get(field.name());
-                            append_field_value(builder, field, field_value)?;
+            if json_str.trim().is_empty() {

Review Comment:
   [P2] Restrict blank-input detection to JSON whitespace
   
   With `spark.comet.expression.JsonToStructs.allowIncompatible=true`, `trim()` 
also treats non-JSON whitespace such as NBSP (U+00A0), vertical tab and form 
feed as a blank document. For a column containing only NBSP, the exact-head 
native expression now makes `from_json(col, 'struct<>') IS NULL` true, while 
Spark 3.5.2 and 4.0.4 return a non-null empty struct. This also regresses 
already-supported schemas such as `a INT`: both the base and previous native 
head return the non-null, all-null-fields struct, but this new branch returns 
SQL NULL. Restrict the blank check to JSON whitespace (space, tab, CR and LF) 
and add a non-JSON-whitespace regression row alongside the ordinary blank-input 
cases.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


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

Reply via email to