pingz-oai commented on code in PR #24684:
URL: https://github.com/apache/datafusion/pull/24684#discussion_r3877161511


##########
datafusion/spark/src/function/map/utils.rs:
##########
@@ -225,23 +243,38 @@ fn map_deduplicate_keys(
                     );
                 }
                 keys_mask_builder.append_value(true);
+                values_mask_builder.append_value(true);
                 key_to_output_idx.insert(key, value_indices.len());
                 value_indices.push(abs_value_idx);
                 new_last_offset += 1;
             }
         } else {
             // The result entry is NULL — no keys/values emitted. Still pad the
-            // mask so it stays aligned with `flat_keys`.
+            // masks so they stay aligned with their respective flat arrays.
             keys_mask_builder.append_n(num_keys_entries, false);
+            values_mask_builder.append_n(num_values_entries, false);
         }
         new_offsets.push(new_last_offset);
         cur_keys_offset += num_keys_entries;
         cur_values_offset += num_values_entries;
     }
     let keys_mask = keys_mask_builder.finish();
+    let values_mask = values_mask_builder.finish();
     let needed_keys = filter(&flat_keys, &keys_mask)?;
-    let value_indices_array = Int32Array::from(value_indices);
-    let needed_values = take(&flat_values, &value_indices_array, None)?;
+    let needed_values = if needs_value_take {
+        let value_indices_array = Int32Array::from(value_indices);
+        take(&flat_values, &value_indices_array, None)?
+    } else {
+        // Values lists can be sliced independently of keys lists. Align the
+        // relative mask with their first offset, without allocating a slice
+        // wrapper for the common case where values start at zero.
+        let flat_values = if values_start_offset == 0 {
+            Cow::Borrowed(flat_values)
+        } else {
+            Cow::Owned(flat_values.slice(values_start_offset, 
values_mask.len()))

Review Comment:
   [P2] Preserve large child offsets in the new filter path
   
   A valid `map_from_arrays` input can now panic when its `LargeList` values 
start at child offset `2_147_483_648` and no duplicate overwrite occurs. A key 
row `[7]` and a `LargeList<Null>` value row with offsets `[2_147_483_648, 
2_147_483_649]` previously produce `{7: NULL}`; this slice instead fails its 
bounds assertion. Both input arrays pass Arrow's `validate_full()`, and a 
`NullArray` child makes this reproducible without allocating a huge buffer.
   
   The existing `get_list_offsets` conversion narrows the offsets to negative 
`i32` values. The base's `take` still works because Arrow 59.2.0 reinterprets 
its `Int32` indices as `UInt32`, recovering the intended child index. This new 
path instead passes the sign-extended `usize` (`18446744071562067968` on 64-bit 
builds) directly to `slice`.
   
   Minimal helper reproduction using the caller's actual offset conversion, 
inside the existing utils test module:
   
   ```rust
   use arrow::array::{LargeListArray, NullArray};
   
   let start = 1_i64 << 31;
   let keys: ArrayRef = Arc::new(Int32Array::from(vec![7]));
   let values: ArrayRef = Arc::new(LargeListArray::new(
       Arc::new(Field::new("item", DataType::Null, true)),
       OffsetBuffer::new(vec![start, start + 1].into()),
       Arc::new(NullArray::new(start as usize + 1)),
       None,
   ));
   values.to_data().validate_full().unwrap();
   map_from_keys_values_offsets_nulls(
       &keys,
       get_list_values(&values).unwrap(),
       &[0, 1],
       &get_list_offsets(&values).unwrap(),
       None,
       None,
       false,
   ).unwrap();
   ```
   
   A focused comparison of the base 
(`4fcaa01c721ba18c10a5ac65446aa48ddf68e9b0`) and this head's helper bodies, 
using the locked Arrow dependencies, confirms base success and head panic under 
both `EXCEPTION` and `LAST_WIN`. Preserve the wide offset when slicing, or 
retain the previous `take` path for narrowed negative offsets.



-- 
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