Skip to content

StructArray::try_new validation incorrectly returns an error when logical_nulls() returns Some() && null_count == 0 #7435

@phillipleblanc

Description

@phillipleblanc

Describe the bug
This logic in StructArray::try_new validates that if one of the child arrays in the StructArray has a null value that isn't properly masked by the parent, then it will be rejected with the error Found unmasked nulls for non-nullable StructArray field.

if !f.is_nullable() {
    if let Some(a) = a.logical_nulls() {
        !nulls.as_ref().map(|n| n.contains(&a)).unwrap_or_default() {
            return Err(ArrowError::InvalidArgumentError(format!(
                "Found unmasked nulls for non-nullable StructArray field {:?}",
                f.name()
            )));
        }
    }
}

However, it is possible for a.logical_nulls() to return Some(_) and the NullBuffer itself to report that there aren't any nulls (null_count == 0), which leads StructArray::try_new to incorrectly report that it found unmasked nulls.

To Reproduce

#[test]
fn test_struct_array_logical_nulls() {
    // Field is non-nullable
    let field = Field::new("a", DataType::Int32, false);
    let values = vec![1, 2, 3];
    // Create a NullBuffer with all bits set to valid (true)
    let nulls = NullBuffer::from(vec![true, true, true]);
    let array = Int32Array::new(values.into(), Some(nulls));
    let child = Arc::new(array) as ArrayRef;
    assert!(child.logical_nulls().is_some());
    assert_eq!(child.logical_nulls().unwrap().null_count(), 0);

    let fields = Fields::from(vec![field]);
    let arrays = vec![child];
    let nulls = None;

    drop(StructArray::try_new(fields, arrays, nulls).expect("should not error"));
}

Expected behavior
The validation succeeds.

Additional context

I will raise a PR for this fix shortly.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions