Skip to content

Commit 55a5d13

Browse files
committed
fix
Signed-off-by: Andrew Duffy <andrew@a10y.dev>
1 parent 8d28c86 commit 55a5d13

2 files changed

Lines changed: 44 additions & 3 deletions

File tree

vortex-array/src/arrays/patched/array.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,9 +231,13 @@ impl PatchedArray {
231231
let indices = self.indices.clone();
232232
let values = self.values.clone();
233233

234-
// Find the new start/end for slicing range.
235-
let begin = (chunks.start * 1024).max(self.offset);
236-
let end = (chunks.end * 1024).min(self.len);
234+
// Find the new start/end for slicing the inner array.
235+
// The inner array has already been sliced to start at position `offset` in absolute terms,
236+
// so we need to convert chunk boundaries to inner-relative coordinates.
237+
let begin = (chunks.start * 1024).saturating_sub(self.offset);
238+
let end = (chunks.end * 1024)
239+
.saturating_sub(self.offset)
240+
.min(self.len);
237241

238242
let offset = if chunks.start == 0 { self.offset } else { 0 };
239243

vortex-array/src/arrays/patched/compute/filter.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,43 @@ mod tests {
221221
Ok(())
222222
}
223223

224+
#[test]
225+
fn test_filter_with_offset_nonuniform() -> VortexResult<()> {
226+
// Test filtering with offset > 0 using non-uniform base values.
227+
// This catches slice_chunks bugs where inner coordinates are miscalculated.
228+
let mut ctx = ExecutionCtx::new(LEGACY_SESSION.clone());
229+
230+
// Use non-uniform values so that incorrect slicing is detectable.
231+
let base_values: Vec<u16> = (0u16..4096).collect();
232+
let array = PrimitiveArray::from_iter(base_values).into_array();
233+
234+
// Patch at index 5 (value becomes 9999) and index 1030 (value becomes 8888).
235+
let patched_indices = buffer![5u16, 1030].into_array();
236+
let patched_values = buffer![9999u16, 8888].into_array();
237+
238+
let patches = Patches::new(4096, 0, patched_indices, patched_values, None)?;
239+
let array = PatchedArray::from_array_and_patches(array, &patches, &mut ctx)?.into_array();
240+
241+
// Slice to create offset > 0.
242+
// After slice(5..4096), logical position 0 = original position 5 (patched to 9999).
243+
let sliced = array.slice(5..4096)?.optimize()?;
244+
assert_eq!(sliced.len(), 4091);
245+
246+
// Filter that touches the first 2 chunks.
247+
// Logical indices: 0 (was 5, patched), 1 (was 6, value 6), 1025 (was 1030, patched).
248+
let mask = Mask::from_indices(4091, vec![0, 1, 1025]);
249+
let filtered = sliced
250+
.filter(mask)?
251+
.optimize()?
252+
.execute::<PrimitiveArray>(&mut ctx)?;
253+
254+
// Expected: 9999 (patched at logical 0), 6 (original at logical 1), 8888 (patched at logical 1025).
255+
let expected = PrimitiveArray::from_iter([9999u16, 6, 8888]);
256+
assert_arrays_eq!(expected, filtered);
257+
258+
Ok(())
259+
}
260+
224261
#[test]
225262
fn test_filter_with_offset_last_chunk() -> VortexResult<()> {
226263
// Test filtering with offset > 0 where the mask touches the last chunk.

0 commit comments

Comments
 (0)