|
| 1 | +// SPDX-License-Identifier: Apache-2.0 |
| 2 | +// SPDX-FileCopyrightText: Copyright the Vortex contributors |
| 3 | + |
| 4 | +use rstest::rstest; |
| 5 | +use vortex_array::ArrayProbe; |
| 6 | +use vortex_array::ArrayRef; |
| 7 | +use vortex_array::IntoArray; |
| 8 | +use vortex_array::RepeatedArrayProbe; |
| 9 | +use vortex_array::VortexSessionExecute; |
| 10 | +use vortex_array::arrays::PrimitiveArray; |
| 11 | +use vortex_array::assert_arrays_eq; |
| 12 | +use vortex_array::builders::builder_with_capacity_in; |
| 13 | +use vortex_array::builtins::ArrayBuiltins; |
| 14 | +use vortex_array::scalar_fn::fns::operators::Operator; |
| 15 | +use vortex_array::validity::Validity; |
| 16 | +use vortex_error::VortexResult; |
| 17 | + |
| 18 | +use crate::RLE; |
| 19 | +use crate::RLEData; |
| 20 | + |
| 21 | +/// A one-off or retained probe over `array`, the retained one living in `retained`. |
| 22 | +fn probe_for<'a>( |
| 23 | + array: &'a ArrayRef, |
| 24 | + retained: &'a mut Option<RepeatedArrayProbe>, |
| 25 | + repeated: bool, |
| 26 | +) -> ArrayProbe<'a> { |
| 27 | + if repeated { |
| 28 | + retained.insert(array.repeated_probe()).as_probe() |
| 29 | + } else { |
| 30 | + array.probe() |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +#[rstest] |
| 35 | +fn random_access_across_chunks_and_nulls( |
| 36 | + #[values(false, true)] repeated: bool, |
| 37 | + #[values(false, true)] sliced: bool, |
| 38 | +) -> VortexResult<()> { |
| 39 | + let mut ctx = crate::test::SESSION.create_execution_ctx(); |
| 40 | + let input = |
| 41 | + PrimitiveArray::from_option_iter((0..8192u32).map(|i| (i % 11 != 0).then_some(i / 16))); |
| 42 | + let encoded = RLEData::encode(input.as_view(), &mut ctx)?.into_array(); |
| 43 | + let range = if sliced { 1777..7333 } else { 0..8192 }; |
| 44 | + let source = if sliced { |
| 45 | + encoded |
| 46 | + .slice(range.clone())? |
| 47 | + .execute::<ArrayRef>(&mut ctx)? |
| 48 | + } else { |
| 49 | + encoded |
| 50 | + }; |
| 51 | + assert!(source.is::<RLE>()); |
| 52 | + let input = input.slice(range)?; |
| 53 | + let indices = [0u32, 1, 1023, 1024, 2048, 2047, 4097, 11, 33, 17, 0]; |
| 54 | + let mut actual = builder_with_capacity_in(source.dtype(), indices.len(), ctx.allocator()); |
| 55 | + let mut retained = None; |
| 56 | + let mut probe = probe_for(&source, &mut retained, repeated); |
| 57 | + for index in indices { |
| 58 | + actual.append_scalar(&probe.execute_scalar(index as usize, &mut ctx)?)?; |
| 59 | + } |
| 60 | + assert_arrays_eq!( |
| 61 | + actual.finish(), |
| 62 | + input.take(PrimitiveArray::from_iter(indices).into_array())?, |
| 63 | + &mut ctx |
| 64 | + ); |
| 65 | + assert!(probe.execute_scalar(source.len(), &mut ctx).is_err()); |
| 66 | + Ok(()) |
| 67 | +} |
| 68 | + |
| 69 | +#[rstest] |
| 70 | +fn lazy_validity_does_not_evaluate_unrequested_rows( |
| 71 | + #[values(false, true)] repeated: bool, |
| 72 | +) -> VortexResult<()> { |
| 73 | + let mut ctx = crate::test::SESSION.create_execution_ctx(); |
| 74 | + let numerators = PrimitiveArray::from_iter(vec![1u32; 1024]).into_array(); |
| 75 | + let denominators = |
| 76 | + PrimitiveArray::from_iter((0..1024).map(|i| u32::from(i != 1023))).into_array(); |
| 77 | + let validity = numerators |
| 78 | + .binary(denominators, Operator::Div)? |
| 79 | + .binary(numerators, Operator::Eq)?; |
| 80 | + let array = RLE::try_new( |
| 81 | + PrimitiveArray::from_iter([42u32]).into_array(), |
| 82 | + PrimitiveArray::new(vec![0u16; 1024], Validity::Array(validity)).into_array(), |
| 83 | + PrimitiveArray::from_iter([0u64]).into_array(), |
| 84 | + 0, |
| 85 | + 1024, |
| 86 | + )? |
| 87 | + .into_array(); |
| 88 | + let expected = array.execute_scalar(0, &mut ctx)?; |
| 89 | + let mut retained = None; |
| 90 | + let mut probe = probe_for(&array, &mut retained, repeated); |
| 91 | + assert_eq!(probe.execute_scalar(0, &mut ctx)?, expected); |
| 92 | + assert!(probe.execute_scalar(1023, &mut ctx).is_err()); |
| 93 | + Ok(()) |
| 94 | +} |
0 commit comments