viirya opened a new issue, #5768:
URL: https://github.com/apache/datafusion-comet/issues/5768

   ## Is your feature request related to a problem or challenge?
   
   Two places implement the same Spark rule — a field of a null struct is null, 
so the parent's
   null mask has to reach the children before the children are used — and they 
do it differently.
   
   `struct_funcs/get_struct_field.rs`, from #4432:
   
   ```rust
   fn project_field(struct_array: &StructArray, ordinal: usize) -> 
DataFusionResult<ArrayRef> {
       let child = struct_array.column(ordinal);
       match struct_array.nulls() {
           Some(_) => {
               let combined = NullBuffer::union(struct_array.nulls(), 
child.nulls());
               let data = 
child.to_data().into_builder().nulls(combined).build()?;
               Ok(make_array(data))
           }
           None => Ok(Arc::clone(child)),
       }
   }
   ```
   
   `hash_funcs/utils.rs`, from #5754:
   
   ```rust
   let columns: Vec<ArrayRef> = match struct_array.nulls() {
       Some(nulls) if nulls.null_count() > 0 => struct_array.flatten().1,
       _ => struct_array.columns().to_vec(),
   };
   ```
   
   Both are correct today, so this is not a bug report. The concern is drift: 
the next time this
   rule needs adjusting, or another edge case turns up, only one of them is 
likely to be updated,
   and the checked-versus-unchecked reasoning lives in two places rather than 
one.
   
   ## Describe the solution you'd like
   
   A single helper both can call. Three decisions to settle first, which is why 
this is filed
   separately rather than folded into #5754:
   
   1. **Shape.** `project_field` extracts one field; the hash path needs all of 
them. One helper
      returning a single child, with the caller mapping over the fields, or one 
returning the whole
      `Vec<ArrayRef>`, or both built on a shared core.
   
   2. **Checked or unchecked.** `project_field` goes through the checked 
`ArrayData` builder;
      `flatten` uses `build_unchecked` with the safety argument that the union 
only ever adds nulls
      so the data buffers are unchanged. Unifying on unchecked means making 
that argument for
      `project_field` too. Unifying on checked reintroduces revalidation of 
every child buffer on
      the hash path, which runs once per element for `array<struct<..>>` — for 
a string child that
      is the whole UTF-8 values buffer.
   
   3. **Whether `project_field` should take the `null_count() > 0` guard.** The 
hash path skips the
      union when the buffer is present but all valid, which is what slicing 
leaves behind.
      `project_field` currently does the work whenever a buffer exists.
   
   ## Describe alternatives you've considered
   
   Leaving both in place. They work, and the duplication is small; but the 
reasoning behind the
   unchecked path is only recorded at one of the two call sites, which is the 
part likely to be
   lost.
   
   ## Additional context
   
   Raised by @andygrove reviewing #5754.
   


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