diff --git a/encodings/runend-bool/src/compute/mod.rs b/encodings/runend-bool/src/compute/mod.rs index 57a6bf6cd9..1e533963d4 100644 --- a/encodings/runend-bool/src/compute/mod.rs +++ b/encodings/runend-bool/src/compute/mod.rs @@ -69,16 +69,52 @@ impl TakeFn for RunEndBoolEncoding { impl SliceFn for RunEndBoolEncoding { fn slice(&self, array: &RunEndBoolArray, start: usize, stop: usize) -> VortexResult { - let slice_begin = array.find_physical_index(start)?; - let slice_end = array.find_physical_index(stop)?; + let new_length = stop - start; + + let (slice_begin, slice_end) = if new_length == 0 { + let ends_len = array.ends().len(); + (ends_len, ends_len) + } else { + let physical_begin = array.find_physical_index(start)?; + let physical_end = array.find_physical_index(stop)?; + (physical_begin, physical_end + 1) + }; Ok(RunEndBoolArray::with_offset_and_size( - slice(array.ends(), slice_begin, slice_end + 1)?, + slice(array.ends(), slice_begin, slice_end)?, value_at_index(slice_begin, array.start()), - array.validity().slice(slice_begin, slice_end + 1)?, - stop - start, - start + array.offset(), + array.validity().slice(start, stop)?, + new_length, + if new_length == 0 { + 0 + } else { + start + array.offset() + }, )? .into_array()) } } + +#[cfg(test)] +mod tests { + use vortex_array::compute::slice; + use vortex_array::validity::Validity; + use vortex_array::{ArrayLen, IntoArrayData}; + + use crate::RunEndBoolArray; + + #[test] + fn slice_at_end() { + let re_array = + RunEndBoolArray::try_new(vec![7_u64, 10].into_array(), false, Validity::NonNullable) + .unwrap(); + + assert_eq!(re_array.len(), 10); + + let sliced_array = slice(&re_array, re_array.len(), re_array.len()).unwrap(); + assert!(sliced_array.is_empty()); + + let re_slice = RunEndBoolArray::try_from(sliced_array).unwrap(); + assert!(re_slice.ends().is_empty()); + } +} diff --git a/encodings/runend/src/array.rs b/encodings/runend/src/array.rs index 8230a91962..f8efb87b12 100644 --- a/encodings/runend/src/array.rs +++ b/encodings/runend/src/array.rs @@ -68,7 +68,7 @@ impl RunEndArray { ); } - if offset != 0 && !ends.is_empty() { + if offset != 0 { let first_run_end: usize = scalar_at(&ends, 0)?.as_ref().try_into()?; if first_run_end <= offset { vortex_bail!("First run end {first_run_end} must be bigger than offset {offset}"); diff --git a/encodings/runend/src/compute/mod.rs b/encodings/runend/src/compute/mod.rs index 328693f9f7..67a5eaa225 100644 --- a/encodings/runend/src/compute/mod.rs +++ b/encodings/runend/src/compute/mod.rs @@ -132,7 +132,11 @@ impl SliceFn for RunEndEncoding { slice(array.ends(), slice_begin, slice_end)?, slice(array.values(), slice_begin, slice_end)?, array.validity().slice(start, stop)?, - start + array.offset(), + if new_length == 0 { + 0 + } else { + start + array.offset() + }, new_length, )? .into_array())