Skip to content

Commit

Permalink
Refine documentation to Array::is_null (apache#4838)
Browse files Browse the repository at this point in the history
* Add documentation and Array::is_logical_null

* Remove code change, refine comments

* fix docs

* Apply suggestions from code review

Co-authored-by: Raphael Taylor-Davies <1781103+tustvold@users.noreply.github.com>

* Fix link formatting

---------

Co-authored-by: Raphael Taylor-Davies <1781103+tustvold@users.noreply.github.com>
  • Loading branch information
alamb and tustvold authored Sep 20, 2023
1 parent 407e575 commit f9cd26f
Showing 1 changed file with 22 additions and 18 deletions.
40 changes: 22 additions & 18 deletions arrow-array/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,52 +173,56 @@ pub trait Array: std::fmt::Debug + Send + Sync {
/// ```
fn offset(&self) -> usize;

/// Returns the null buffer of this array if any
/// Returns the null buffer of this array if any.
///
/// Note: some arrays can encode their nullability in their children, for example,
/// The null buffer encodes the "physical" nulls of an array.
/// However, some arrays can also encode nullability in their children, for example,
/// [`DictionaryArray::values`] values or [`RunArray::values`], or without a null buffer,
/// such as [`NullArray`]. Use [`Array::logical_nulls`] to obtain a computed mask encoding this
/// such as [`NullArray`]. To determine if each element of such an array is logically null,
/// you can use the slower [`Array::logical_nulls`] to obtain a computed mask .
fn nulls(&self) -> Option<&NullBuffer>;

/// Returns the logical null buffer of this array if any
/// Returns a potentially computed [`NullBuffer`] that represent the logical null values of this array, if any.
///
/// In most cases this will be the same as [`Array::nulls`], except for:
///
/// * DictionaryArray where [`DictionaryArray::values`] contains nulls
/// * RunArray where [`RunArray::values`] contains nulls
/// * NullArray where all indices are nulls
/// * [`DictionaryArray`] where [`DictionaryArray::values`] contains nulls
/// * [`RunArray`] where [`RunArray::values`] contains nulls
/// * [`NullArray`] where all indices are nulls
///
/// In these cases a logical [`NullBuffer`] will be computed, encoding the logical nullability
/// of these arrays, beyond what is encoded in [`Array::nulls`]
fn logical_nulls(&self) -> Option<NullBuffer> {
self.nulls().cloned()
}

/// Returns whether the element at `index` is null.
/// When using this function on a slice, the index is relative to the slice.
/// Returns whether the element at `index` is null according to [`Array::nulls`]
///
/// Note: this method returns the physical nullability, i.e. that encoded in [`Array::nulls`]
/// see [`Array::logical_nulls`] for logical nullability
/// Note: For performance reasons, this method returns nullability solely as determined by the
/// null buffer. This difference can lead to surprising results, for example, [`NullArray::is_null`] always
/// returns `false` as the array lacks a null buffer. Similarly [`DictionaryArray`] and [`RunArray`] may
/// encode nullability in their children. See [`Self::logical_nulls`] for more information.
///
/// # Example:
///
/// ```
/// use arrow_array::{Array, Int32Array};
/// use arrow_array::{Array, Int32Array, NullArray};
///
/// let array = Int32Array::from(vec![Some(1), None]);
///
/// assert_eq!(array.is_null(0), false);
/// assert_eq!(array.is_null(1), true);
///
/// // NullArrays do not have a null buffer, and therefore always
/// // return false for is_null.
/// let array = NullArray::new(1);
/// assert_eq!(array.is_null(0), false);
/// ```
fn is_null(&self, index: usize) -> bool {
self.nulls().map(|n| n.is_null(index)).unwrap_or_default()
}

/// Returns whether the element at `index` is not null.
/// When using this function on a slice, the index is relative to the slice.
///
/// Note: this method returns the physical nullability, i.e. that encoded in [`Array::nulls`]
/// see [`Array::logical_nulls`] for logical nullability
/// Returns whether the element at `index` is *not* null, the
/// opposite of [`Self::is_null`].
///
/// # Example:
///
Expand Down

0 comments on commit f9cd26f

Please sign in to comment.