Skip to content

Commit 6696266

Browse files
authored
fix: Support slicing RunEndBool arrays to 0 elements (#1511)
1 parent 9a78dd4 commit 6696266

File tree

3 files changed

+48
-8
lines changed

3 files changed

+48
-8
lines changed

encodings/runend-bool/src/compute/mod.rs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,52 @@ impl TakeFn<RunEndBoolArray> for RunEndBoolEncoding {
6969

7070
impl SliceFn<RunEndBoolArray> for RunEndBoolEncoding {
7171
fn slice(&self, array: &RunEndBoolArray, start: usize, stop: usize) -> VortexResult<ArrayData> {
72-
let slice_begin = array.find_physical_index(start)?;
73-
let slice_end = array.find_physical_index(stop)?;
72+
let new_length = stop - start;
73+
74+
let (slice_begin, slice_end) = if new_length == 0 {
75+
let ends_len = array.ends().len();
76+
(ends_len, ends_len)
77+
} else {
78+
let physical_begin = array.find_physical_index(start)?;
79+
let physical_end = array.find_physical_index(stop)?;
80+
(physical_begin, physical_end + 1)
81+
};
7482

7583
Ok(RunEndBoolArray::with_offset_and_size(
76-
slice(array.ends(), slice_begin, slice_end + 1)?,
84+
slice(array.ends(), slice_begin, slice_end)?,
7785
value_at_index(slice_begin, array.start()),
78-
array.validity().slice(slice_begin, slice_end + 1)?,
79-
stop - start,
80-
start + array.offset(),
86+
array.validity().slice(start, stop)?,
87+
new_length,
88+
if new_length == 0 {
89+
0
90+
} else {
91+
start + array.offset()
92+
},
8193
)?
8294
.into_array())
8395
}
8496
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use vortex_array::compute::slice;
101+
use vortex_array::validity::Validity;
102+
use vortex_array::{ArrayLen, IntoArrayData};
103+
104+
use crate::RunEndBoolArray;
105+
106+
#[test]
107+
fn slice_at_end() {
108+
let re_array =
109+
RunEndBoolArray::try_new(vec![7_u64, 10].into_array(), false, Validity::NonNullable)
110+
.unwrap();
111+
112+
assert_eq!(re_array.len(), 10);
113+
114+
let sliced_array = slice(&re_array, re_array.len(), re_array.len()).unwrap();
115+
assert!(sliced_array.is_empty());
116+
117+
let re_slice = RunEndBoolArray::try_from(sliced_array).unwrap();
118+
assert!(re_slice.ends().is_empty());
119+
}
120+
}

encodings/runend/src/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ impl RunEndArray {
6868
);
6969
}
7070

71-
if offset != 0 && !ends.is_empty() {
71+
if offset != 0 {
7272
let first_run_end: usize = scalar_at(&ends, 0)?.as_ref().try_into()?;
7373
if first_run_end <= offset {
7474
vortex_bail!("First run end {first_run_end} must be bigger than offset {offset}");

encodings/runend/src/compute/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@ impl SliceFn<RunEndArray> for RunEndEncoding {
132132
slice(array.ends(), slice_begin, slice_end)?,
133133
slice(array.values(), slice_begin, slice_end)?,
134134
array.validity().slice(start, stop)?,
135-
start + array.offset(),
135+
if new_length == 0 {
136+
0
137+
} else {
138+
start + array.offset()
139+
},
136140
new_length,
137141
)?
138142
.into_array())

0 commit comments

Comments
 (0)