diff --git a/encodings/alp/src/alp/array.rs b/encodings/alp/src/alp/array.rs index 3e2010a1ad5..1e9570a5969 100644 --- a/encodings/alp/src/alp/array.rs +++ b/encodings/alp/src/alp/array.rs @@ -481,6 +481,7 @@ impl ValidityChild for ALP { #[cfg(test)] mod tests { + #![expect(deprecated)] use std::f64::consts::PI; use std::sync::LazyLock; diff --git a/encodings/alp/src/alp/ops.rs b/encodings/alp/src/alp/ops.rs index a8850744056..6bd271c0939 100644 --- a/encodings/alp/src/alp/ops.rs +++ b/encodings/alp/src/alp/ops.rs @@ -15,6 +15,9 @@ use crate::ALPFloat; use crate::match_each_alp_float_ptype; impl OperationsVTable for ALP { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ALP>, index: usize, diff --git a/encodings/alp/src/alp_rd/ops.rs b/encodings/alp/src/alp_rd/ops.rs index edb2fb21186..1c585ba060e 100644 --- a/encodings/alp/src/alp_rd/ops.rs +++ b/encodings/alp/src/alp_rd/ops.rs @@ -14,6 +14,9 @@ use crate::ALPRDArrayExt; use crate::ALPRDArraySlotsExt; impl OperationsVTable for ALPRD { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ALPRD>, index: usize, diff --git a/encodings/bytebool/src/array.rs b/encodings/bytebool/src/array.rs index faa1fea81fa..8ea8c755931 100644 --- a/encodings/bytebool/src/array.rs +++ b/encodings/bytebool/src/array.rs @@ -312,6 +312,8 @@ impl ValidityVTable for ByteBool { } impl OperationsVTable for ByteBool { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, ByteBool>, index: usize, @@ -347,6 +349,7 @@ mod tests { }); #[test] + #[expect(deprecated)] fn test_validity_construction() { let v = vec![true, false]; let v_len = v.len(); diff --git a/encodings/datetime-parts/src/ops.rs b/encodings/datetime-parts/src/ops.rs index d99e55c7542..14bd9088f6a 100644 --- a/encodings/datetime-parts/src/ops.rs +++ b/encodings/datetime-parts/src/ops.rs @@ -17,6 +17,9 @@ use crate::timestamp; use crate::timestamp::TimestampParts; impl OperationsVTable for DateTimeParts { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, DateTimeParts>, index: usize, diff --git a/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs b/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs index d5b0024f5b7..c2a9e5a0794 100644 --- a/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs +++ b/encodings/decimal-byte-parts/src/decimal_byte_parts/mod.rs @@ -289,6 +289,9 @@ fn to_canonical_decimal( } impl OperationsVTable for DecimalByteParts { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, DecimalByteParts>, index: usize, @@ -334,6 +337,7 @@ mod tests { use crate::DecimalByteParts; #[test] + #[expect(deprecated)] fn test_scalar_at_decimal_parts() { let decimal_dtype = DecimalDType::new(8, 2); let dtype = DType::Decimal(decimal_dtype, Nullability::Nullable); diff --git a/encodings/fastlanes/src/bitpacking/array/bitpack_decompress.rs b/encodings/fastlanes/src/bitpacking/array/bitpack_decompress.rs index 0684aea5e6a..63659112b28 100644 --- a/encodings/fastlanes/src/bitpacking/array/bitpack_decompress.rs +++ b/encodings/fastlanes/src/bitpacking/array/bitpack_decompress.rs @@ -485,6 +485,7 @@ mod tests { /// This test ensures that the mask is properly appended to the range, not the builder. #[test] + #[expect(deprecated)] fn test_unpack_into_with_validity_mask() -> VortexResult<()> { // Create an array with some null values. let values = Buffer::from_iter([1u32, 0, 3, 4, 0]); @@ -596,6 +597,7 @@ mod tests { /// Test unpacking with nullability and validity masks. #[test] + #[expect(deprecated)] fn test_unpack_to_primitive_nullability() { // Test with null values at various positions. let values = Buffer::from_iter([100u32, 0, 200, 0, 300, 0, 400]); diff --git a/encodings/fastlanes/src/bitpacking/compute/take.rs b/encodings/fastlanes/src/bitpacking/compute/take.rs index 86e97623cf6..373a6825e30 100644 --- a/encodings/fastlanes/src/bitpacking/compute/take.rs +++ b/encodings/fastlanes/src/bitpacking/compute/take.rs @@ -238,6 +238,7 @@ mod test { #[test] #[cfg_attr(miri, ignore)] // This test is too slow on miri + #[expect(deprecated)] fn take_random_indices() { let mut ctx = SESSION.create_execution_ctx(); let num_patches: usize = 128; diff --git a/encodings/fastlanes/src/bitpacking/vtable/operations.rs b/encodings/fastlanes/src/bitpacking/vtable/operations.rs index e14b27323c1..2a152ed3981 100644 --- a/encodings/fastlanes/src/bitpacking/vtable/operations.rs +++ b/encodings/fastlanes/src/bitpacking/vtable/operations.rs @@ -11,6 +11,8 @@ use crate::BitPacked; use crate::bitpack_decompress; use crate::bitpacking::array::BitPackedArrayExt; impl OperationsVTable for BitPacked { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, BitPacked>, index: usize, @@ -235,6 +237,7 @@ mod test { } #[test] + #[expect(deprecated)] fn scalar_at_invalid_patches() { let packed_array = BitPacked::try_new( BufferHandle::new_host(ByteBuffer::copy_from_aligned( @@ -268,6 +271,7 @@ mod test { } #[test] + #[expect(deprecated)] fn scalar_at() { let mut ctx = SESSION.create_execution_ctx(); let values = (0u32..257).collect::>(); diff --git a/encodings/fastlanes/src/delta/array/delta_compress.rs b/encodings/fastlanes/src/delta/array/delta_compress.rs index c2ef38ceb79..0d68280e374 100644 --- a/encodings/fastlanes/src/delta/array/delta_compress.rs +++ b/encodings/fastlanes/src/delta/array/delta_compress.rs @@ -127,6 +127,7 @@ where #[cfg(test)] mod tests { + #![expect(deprecated)] use std::iter; use std::sync::LazyLock; diff --git a/encodings/fastlanes/src/delta/vtable/operations.rs b/encodings/fastlanes/src/delta/vtable/operations.rs index 7ed57a0886d..616d094974a 100644 --- a/encodings/fastlanes/src/delta/vtable/operations.rs +++ b/encodings/fastlanes/src/delta/vtable/operations.rs @@ -11,6 +11,9 @@ use vortex_error::VortexResult; use super::Delta; impl OperationsVTable for Delta { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Delta>, index: usize, @@ -219,6 +222,7 @@ mod tests { #[test] #[should_panic] + #[expect(deprecated)] fn test_scalar_at_non_jagged_array_oob() { let delta = da(&(0u32..2048).collect()).into_array(); delta @@ -235,6 +239,7 @@ mod tests { #[test] #[should_panic] + #[expect(deprecated)] fn test_scalar_at_jagged_array_oob() { let delta = da(&(0u32..2000).collect()).into_array(); delta diff --git a/encodings/fastlanes/src/for/array/for_compress.rs b/encodings/fastlanes/src/for/array/for_compress.rs index 62c23b7ba21..61ba035ad58 100644 --- a/encodings/fastlanes/src/for/array/for_compress.rs +++ b/encodings/fastlanes/src/for/array/for_compress.rs @@ -104,6 +104,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_zeros() { let mut ctx = SESSION.create_execution_ctx(); let array = PrimitiveArray::new(buffer![0i32; 100], Validity::NonNullable); @@ -153,6 +154,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_overflow() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let array = PrimitiveArray::from_iter(i8::MIN..=i8::MAX); diff --git a/encodings/fastlanes/src/for/vtable/operations.rs b/encodings/fastlanes/src/for/vtable/operations.rs index 36dac998cbe..383a86ce696 100644 --- a/encodings/fastlanes/src/for/vtable/operations.rs +++ b/encodings/fastlanes/src/for/vtable/operations.rs @@ -13,6 +13,9 @@ use super::FoR; use crate::r#for::array::FoRArrayExt; use crate::r#for::array::FoRArraySlotsExt; impl OperationsVTable for FoR { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, FoR>, index: usize, diff --git a/encodings/fastlanes/src/rle/array/mod.rs b/encodings/fastlanes/src/rle/array/mod.rs index 2805b999a4f..420f7dcd2e9 100644 --- a/encodings/fastlanes/src/rle/array/mod.rs +++ b/encodings/fastlanes/src/rle/array/mod.rs @@ -93,6 +93,7 @@ pub trait RLEArrayExt: RLEArraySlotsExt { clippy::expect_used, reason = "expect is safe here as scalar_at returns a valid primitive" )] + #[expect(deprecated)] fn values_idx_offset(&self, chunk_idx: usize, ctx: &mut ExecutionCtx) -> usize { self.values_idx_offsets() .execute_scalar(chunk_idx, ctx) @@ -164,6 +165,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_try_new_with_validity() { let values = PrimitiveArray::from_iter([10u32, 20]).into_array(); let values_idx_offsets = PrimitiveArray::from_iter([0u64]).into_array(); diff --git a/encodings/fastlanes/src/rle/array/rle_compress.rs b/encodings/fastlanes/src/rle/array/rle_compress.rs index f623b84d778..c3822c9dfcd 100644 --- a/encodings/fastlanes/src/rle/array/rle_compress.rs +++ b/encodings/fastlanes/src/rle/array/rle_compress.rs @@ -442,6 +442,7 @@ mod tests { /// This simulates a compressor that doesn't preserve index values at null /// positions, which can happen when indices are further compressed and the /// compressor clobbers invalid entries with arbitrary data. + #[expect(deprecated)] fn with_random_invalid_indices( rle: &RLEArray, ctx: &mut ExecutionCtx, diff --git a/encodings/fastlanes/src/rle/vtable/operations.rs b/encodings/fastlanes/src/rle/vtable/operations.rs index ca4d2d39545..f4fe4df2bad 100644 --- a/encodings/fastlanes/src/rle/vtable/operations.rs +++ b/encodings/fastlanes/src/rle/vtable/operations.rs @@ -14,6 +14,9 @@ use crate::rle::RLEArrayExt; use crate::rle::RLEArraySlotsExt; impl OperationsVTable for RLE { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, RLE>, index: usize, @@ -185,6 +188,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_scalar_at_multiple_chunks() { let mut ctx = SESSION.create_execution_ctx(); // Test accessing elements around chunk boundaries @@ -212,6 +216,7 @@ mod tests { #[test] #[should_panic] + #[expect(deprecated)] fn test_scalar_at_out_of_bounds() { let array = fixture::rle_array(); array @@ -221,6 +226,7 @@ mod tests { #[test] #[should_panic] + #[expect(deprecated)] fn test_scalar_at_slice_out_of_bounds() { let array = fixture::rle_array().slice(0..1).unwrap(); array diff --git a/encodings/fastlanes/src/transposed_bool.rs b/encodings/fastlanes/src/transposed_bool.rs index efb3443cdfc..338af911bc6 100644 --- a/encodings/fastlanes/src/transposed_bool.rs +++ b/encodings/fastlanes/src/transposed_bool.rs @@ -256,6 +256,9 @@ impl VTable for TransposedBool { } impl OperationsVTable for TransposedBool { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, TransposedBool>, index: usize, @@ -325,6 +328,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn slice_stays_lazy_and_translates_scalars() -> VortexResult<()> { let expected = test_bits(); let array = TransposedBool::try_new(transposed_bool_array(expected.clone()))?; diff --git a/encodings/fsst/src/array.rs b/encodings/fsst/src/array.rs index 86b8fd0c34d..835bd05db93 100644 --- a/encodings/fsst/src/array.rs +++ b/encodings/fsst/src/array.rs @@ -791,6 +791,7 @@ impl FSSTData { /// Validate using the decomposed components (codes bytes + offsets + nullability). #[expect(clippy::too_many_arguments)] + #[expect(deprecated)] fn validate_parts( symbols: &[Symbol], symbol_lengths: &[u8], diff --git a/encodings/fsst/src/ops.rs b/encodings/fsst/src/ops.rs index b630508ed9e..c6c265da713 100644 --- a/encodings/fsst/src/ops.rs +++ b/encodings/fsst/src/ops.rs @@ -14,6 +14,9 @@ use crate::FSST; use crate::FSSTArrayExt; impl OperationsVTable for FSST { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, FSST>, index: usize, diff --git a/encodings/onpair/src/decode.rs b/encodings/onpair/src/decode.rs index 7aac8c3963f..15c9dc1dc3e 100644 --- a/encodings/onpair/src/decode.rs +++ b/encodings/onpair/src/decode.rs @@ -32,6 +32,7 @@ pub(crate) fn collect_widened( .into_buffer::()) } +#[expect(deprecated)] pub(crate) fn code_boundary_at( codes_offsets: &ArrayRef, index: usize, diff --git a/encodings/onpair/src/ops.rs b/encodings/onpair/src/ops.rs index 728e5a0e6f2..ca9a22f75d5 100644 --- a/encodings/onpair/src/ops.rs +++ b/encodings/onpair/src/ops.rs @@ -18,6 +18,9 @@ use crate::decode::code_boundary_at; use crate::decode::collect_widened; impl OperationsVTable for OnPair { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, OnPair>, index: usize, diff --git a/encodings/onpair/src/tests.rs b/encodings/onpair/src/tests.rs index 7dac64befc2..cd1adcea4e0 100644 --- a/encodings/onpair/src/tests.rs +++ b/encodings/onpair/src/tests.rs @@ -108,6 +108,7 @@ fn test_onpair_rejects_100k_token_dictionary() -> vortex_error::VortexResult<()> /// decodes or searches through it, including on derived (sliced) arrays. #[cfg_attr(miri, ignore)] #[test] +#[expect(deprecated)] fn test_corrupt_dictionary_rejected_on_first_use() -> vortex_error::VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let arr = compress_onpair(&sample_input().into_array(), &mut ctx)?; @@ -267,6 +268,7 @@ fn test_onpair_nullable_canonicalize() -> vortex_error::VortexResult<()> { #[cfg_attr(miri, ignore)] #[test] +#[expect(deprecated)] fn test_onpair_scalar_at() -> vortex_error::VortexResult<()> { let input = sample_input(); let mut ctx = SESSION.create_execution_ctx(); @@ -285,6 +287,7 @@ fn test_onpair_scalar_at() -> vortex_error::VortexResult<()> { /// relative to the slice. #[cfg_attr(miri, ignore)] #[test] +#[expect(deprecated)] fn test_onpair_scalar_at_window() -> vortex_error::VortexResult<()> { let n = 2_000usize; let strings: Vec = (0..n) diff --git a/encodings/parquet-variant/src/array.rs b/encodings/parquet-variant/src/array.rs index 5d364cae0ef..c67dd26d1a3 100644 --- a/encodings/parquet-variant/src/array.rs +++ b/encodings/parquet-variant/src/array.rs @@ -809,6 +809,7 @@ mod tests { /// canonicalization performs: an object-shredded Parquet variant, once canonicalized and then /// rebuilt, must produce the same per-row values as the original. #[test] + #[expect(deprecated)] fn parquet_typed_value_inverse_roundtrips_object_shredding() -> VortexResult<()> { // Shred `$.a` as Int32 over conforming, non-conforming, and missing-field rows. let json: ArrowArrayRef = Arc::new(StringArray::from(vec![ diff --git a/encodings/parquet-variant/src/arrow.rs b/encodings/parquet-variant/src/arrow.rs index e1c03d704dc..843c40654ec 100644 --- a/encodings/parquet-variant/src/arrow.rs +++ b/encodings/parquet-variant/src/arrow.rs @@ -353,6 +353,7 @@ mod tests { } } + #[expect(deprecated)] fn assert_variant_scalars_eq( actual: &vortex_array::ArrayRef, expected: &vortex_array::ArrayRef, diff --git a/encodings/parquet-variant/src/json_to_variant_tests.rs b/encodings/parquet-variant/src/json_to_variant_tests.rs index 5bc09a426f7..312b0098fec 100644 --- a/encodings/parquet-variant/src/json_to_variant_tests.rs +++ b/encodings/parquet-variant/src/json_to_variant_tests.rs @@ -65,6 +65,7 @@ fn execute_json_to_variant(input: ArrayRef, shredding: ShreddingSpec) -> VortexR .execute::(&mut SESSION.create_execution_ctx()) } +#[expect(deprecated)] fn assert_variant_i64_rows(array: &ArrayRef, expected: &[Option]) -> VortexResult<()> { assert_eq!(array.len(), expected.len()); let mut ctx = SESSION.create_execution_ctx(); @@ -97,6 +98,7 @@ fn rejects_bare_utf8_input() { } #[test] +#[expect(deprecated)] fn converts_json_extension_rows() -> VortexResult<()> { let input = json_input( VarBinViewArray::from_iter_str([r#"{"a": 1}"#, "2", r#"{"a": 3}"#]).into_array(), @@ -158,6 +160,7 @@ fn dict_encoded_input_converts_each_row() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn null_rows_stay_null_and_json_null_becomes_variant_null() -> VortexResult<()> { let input = json_input( VarBinViewArray::from_iter_nullable_str([Some("1"), None, Some("null")]).into_array(), @@ -186,6 +189,7 @@ fn invalid_json_errors() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn shredding_produces_typed_value_child() -> VortexResult<()> { let input = json_input( VarBinViewArray::from_iter_str([ @@ -275,6 +279,7 @@ fn shredding_preserves_null_rows() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn shredding_root_path_shreds_top_level_values() -> VortexResult<()> { let input = json_input(VarBinViewArray::from_iter_str(["1", "2", r#""not-a-number""#]).into_array())?; diff --git a/encodings/parquet-variant/src/kernel.rs b/encodings/parquet-variant/src/kernel.rs index 90aa9eba548..e4f398c7ab2 100644 --- a/encodings/parquet-variant/src/kernel.rs +++ b/encodings/parquet-variant/src/kernel.rs @@ -544,9 +544,13 @@ mod tests { let mut ctx = SESSION.create_execution_ctx(); for (actual_idx, expected_idx) in expected_rows.into_iter().enumerate() { + #[expect(deprecated)] + let actual_scalar = actual.execute_scalar(actual_idx, &mut ctx)?; + #[expect(deprecated)] + let expected_scalar = expected.execute_scalar(expected_idx, &mut ctx)?; assert_eq!( - actual.execute_scalar(actual_idx, &mut ctx)?, - expected.execute_scalar(expected_idx, &mut ctx)?, + actual_scalar, + expected_scalar, "row {actual_idx} should match source row {expected_idx}", ); } @@ -561,8 +565,10 @@ mod tests { let mut ctx = SESSION.create_execution_ctx(); for (idx, is_null) in expected.into_iter().enumerate() { + #[expect(deprecated)] + let scalar = array.execute_scalar(idx, &mut ctx)?; assert_eq!( - array.execute_scalar(idx, &mut ctx)?.is_null(), + scalar.is_null(), is_null, "row {idx} nullness mismatch", ); @@ -673,6 +679,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_variant_get_unshredded_field_as_variant() -> VortexResult<()> { let arr = make_unshredded_json_array(vec![ Some(r#"{"a": "ok"}"#), @@ -900,6 +907,7 @@ mod tests { Ok(VariantArray::try_new(raw_core, Some(shredded))?.into_array()) } + #[expect(deprecated)] fn assert_variant_i32_scalars(array: &ArrayRef, expected: &[Option]) -> VortexResult<()> { assert_eq!(array.len(), expected.len()); let mut ctx = SESSION.create_execution_ctx(); @@ -921,6 +929,7 @@ mod tests { Ok(()) } + #[expect(deprecated)] fn assert_variant_object_a_b( array: &ArrayRef, expected_a: &[Option], diff --git a/encodings/parquet-variant/src/operations.rs b/encodings/parquet-variant/src/operations.rs index 8517df27f22..fe6e2100c12 100644 --- a/encodings/parquet-variant/src/operations.rs +++ b/encodings/parquet-variant/src/operations.rs @@ -31,11 +31,14 @@ use crate::ParquetVariantArraySlotsExt; use crate::vtable::ParquetVariant; impl OperationsVTable for ParquetVariant { + type ProbeState = (); + /// Resolves one row according to the Parquet Variant shredding rules. /// /// For valid data, a row with both `value` and struct `typed_value` is a partially /// shredded object: recursively reconstruct shredded fields and merge them with the /// raw-only fields from `value`. + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ParquetVariant>, index: usize, @@ -67,6 +70,7 @@ impl OperationsVTable for ParquetVariant { } } +#[expect(deprecated)] fn scalar_from_variant_storage( metadata: &[u8], value: Option<&ArrayRef>, @@ -92,6 +96,7 @@ fn scalar_from_variant_storage( Ok(Scalar::null(DType::Null)) } +#[expect(deprecated)] fn scalar_from_typed_value_array( metadata: &[u8], value: Option<&ArrayRef>, @@ -416,6 +421,7 @@ mod tests { Arc::new(builder.finish()) } + #[expect(deprecated)] fn assert_scalar_at_matches_arrow_try_value( arrow_variant: &ArrowVariantArray, rows: impl IntoIterator, @@ -438,6 +444,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_from_arrow_variant_nullable_validity() -> VortexResult<()> { let mut builder = VariantArrayBuilder::new(3); builder.append_variant(PqVariant::from(42i32)); @@ -479,6 +486,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_outer_null_and_variant_null_are_distinct() -> VortexResult<()> { let mut builder = VariantArrayBuilder::new(3); builder.append_variant(PqVariant::Null); @@ -517,6 +525,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_from_arrow_variant_all_nulls() -> VortexResult<()> { let mut builder = VariantArrayBuilder::new(2); builder.append_variant(PqVariant::from(1i32)); @@ -553,6 +562,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_from_arrow_variant_non_nullable() -> VortexResult<()> { let mut builder = VariantArrayBuilder::new(2); builder.append_variant(PqVariant::from(1i32)); @@ -644,6 +654,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_scalar_at_recursive_shredded_list() -> VortexResult<()> { // Spec basis: for arrays, "value must be null" when the value is an array, and array // elements cannot be missing. @@ -724,6 +735,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_scalar_at_partially_shredded_object_merges_fields() -> VortexResult<()> { // Spec basis: non-null `value` + non-null `typed_value` means a "partially shredded // object", so reconstruction must merge the shredded object with the fallback object. diff --git a/encodings/pco/src/array.rs b/encodings/pco/src/array.rs index 44a6a8e4045..2441cd435ad 100644 --- a/encodings/pco/src/array.rs +++ b/encodings/pco/src/array.rs @@ -778,6 +778,9 @@ impl ValidityVTable for Pco { } impl OperationsVTable for Pco { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Pco>, index: usize, diff --git a/encodings/runend/src/array.rs b/encodings/runend/src/array.rs index 3a0b10c5c4a..77e287a1564 100644 --- a/encodings/runend/src/array.rs +++ b/encodings/runend/src/array.rs @@ -308,6 +308,7 @@ impl RunEnd { } impl RunEndData { + #[expect(deprecated)] fn logical_len_from_ends(ends: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult { if ends.is_empty() { Ok(0) @@ -318,6 +319,7 @@ impl RunEndData { /// Validate that `ends` and `values` form a well-formed run-end array covering /// `offset..offset + length`. + #[expect(deprecated)] pub fn validate_parts( ends: &ArrayRef, values: &ArrayRef, diff --git a/encodings/runend/src/compute/cast.rs b/encodings/runend/src/compute/cast.rs index aa2dc5eb406..ccbd27c8cfc 100644 --- a/encodings/runend/src/compute/cast.rs +++ b/encodings/runend/src/compute/cast.rs @@ -60,6 +60,7 @@ mod tests { }); #[test] + #[expect(deprecated)] fn test_cast_runend_i32_to_i64() { let mut ctx = SESSION.create_execution_ctx(); let runend = RunEnd::try_new( diff --git a/encodings/runend/src/kernel.rs b/encodings/runend/src/kernel.rs index 2eed964e3a9..ff731f64078 100644 --- a/encodings/runend/src/kernel.rs +++ b/encodings/runend/src/kernel.rs @@ -57,6 +57,7 @@ impl ExecuteParentKernel for RunEndSliceKernel { } } +#[expect(deprecated)] fn slice( array: ArrayView<'_, RunEnd>, range: Range, diff --git a/encodings/runend/src/ops.rs b/encodings/runend/src/ops.rs index e2c2e3fc99b..1d99f5cb777 100644 --- a/encodings/runend/src/ops.rs +++ b/encodings/runend/src/ops.rs @@ -18,6 +18,9 @@ use crate::array::RunEndArrayExt; use crate::array::RunEndArraySlotsExt; impl OperationsVTable for RunEnd { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, RunEnd>, index: usize, @@ -184,6 +187,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn ree_scalar_at_end() { let mut ctx = SESSION.create_execution_ctx(); let scalar = RunEnd::encode( diff --git a/encodings/sequence/src/array.rs b/encodings/sequence/src/array.rs index 10a222544b6..c82e728feda 100644 --- a/encodings/sequence/src/array.rs +++ b/encodings/sequence/src/array.rs @@ -426,6 +426,8 @@ impl VTable for Sequence { } impl OperationsVTable for Sequence { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Sequence>, index: usize, @@ -587,6 +589,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_sequence_scalar_at() { let scalar = Sequence::try_new_typed(2i64, 3, Nullability::NonNullable, 4) .unwrap() @@ -727,6 +730,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn descending_step_unsigned_output() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let array = Sequence::try_new( @@ -775,6 +779,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn values_past_i64_max() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let step = 1u64 << 62; diff --git a/encodings/sequence/src/compute/cast.rs b/encodings/sequence/src/compute/cast.rs index fa5d3a7661d..aa16301081d 100644 --- a/encodings/sequence/src/compute/cast.rs +++ b/encodings/sequence/src/compute/cast.rs @@ -156,6 +156,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_cast_sequence_narrows_to_output_dtype() -> VortexResult<()> { let casted = Sequence::try_new_typed(100i32, -10i32, Nullability::NonNullable, 5)? .into_array() diff --git a/encodings/sequence/src/model_tests.rs b/encodings/sequence/src/model_tests.rs index eb93c4199c3..a6aff56b1a2 100644 --- a/encodings/sequence/src/model_tests.rs +++ b/encodings/sequence/src/model_tests.rs @@ -122,6 +122,7 @@ fn constant(value: i128, ptype: PType, len: usize) -> VortexResult { } #[test] +#[expect(deprecated)] fn sequence_kernels_match_exact_model() -> VortexResult<()> { let session = vortex_array::array_session(); crate::initialize(&session); diff --git a/encodings/sparse/src/compute/between.rs b/encodings/sparse/src/compute/between.rs index 46fcd7f1e59..a5a914d67e0 100644 --- a/encodings/sparse/src/compute/between.rs +++ b/encodings/sparse/src/compute/between.rs @@ -23,6 +23,7 @@ use crate::SparseExt as _; /// /// Declines (falls back to canonical) unless both bounds are constants. impl BetweenKernel for Sparse { + #[expect(deprecated)] fn between( array: ArrayView<'_, Self>, lower: &ArrayRef, diff --git a/encodings/sparse/src/compute/is_constant.rs b/encodings/sparse/src/compute/is_constant.rs index eee8683df0a..d2868be77dd 100644 --- a/encodings/sparse/src/compute/is_constant.rs +++ b/encodings/sparse/src/compute/is_constant.rs @@ -26,6 +26,7 @@ use crate::SparseExt as _; pub(crate) struct SparseIsConstantKernel; impl DynAggregateKernel for SparseIsConstantKernel { + #[expect(deprecated)] fn aggregate( &self, aggregate_fn: &AggregateFnRef, diff --git a/encodings/sparse/src/lib.rs b/encodings/sparse/src/lib.rs index 70f993c10ff..5b107832868 100644 --- a/encodings/sparse/src/lib.rs +++ b/encodings/sparse/src/lib.rs @@ -771,6 +771,7 @@ mod test { } #[test] + #[expect(deprecated)] pub fn test_scalar_at() { let array = sparse_array(nullable_fill()); @@ -796,6 +797,7 @@ mod test { #[test] #[should_panic(expected = "out of bounds")] + #[expect(deprecated)] fn test_scalar_at_oob() { let array = sparse_array(nullable_fill()); array @@ -804,6 +806,7 @@ mod test { } #[test] + #[expect(deprecated)] pub fn test_scalar_at_again() { let arr = Sparse::try_new( ConstantArray::new(10u32, 1).into_array(), @@ -833,6 +836,7 @@ mod test { } #[test] + #[expect(deprecated)] pub fn scalar_at_sliced() { let sliced = sparse_array(nullable_fill()).slice(2..7).unwrap(); assert_eq!( @@ -886,6 +890,7 @@ mod test { } #[test] + #[expect(deprecated)] pub fn scalar_at_sliced_twice() { let sliced_once = sparse_array(nullable_fill()).slice(1..8).unwrap(); assert_eq!( diff --git a/encodings/sparse/src/ops.rs b/encodings/sparse/src/ops.rs index 568d8d377d1..acabbb103d5 100644 --- a/encodings/sparse/src/ops.rs +++ b/encodings/sparse/src/ops.rs @@ -11,6 +11,8 @@ use crate::Sparse; use crate::SparseExt as _; impl OperationsVTable for Sparse { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Sparse>, index: usize, diff --git a/encodings/zigzag/src/array.rs b/encodings/zigzag/src/array.rs index ef3165132f4..1aa6cfb07fe 100644 --- a/encodings/zigzag/src/array.rs +++ b/encodings/zigzag/src/array.rs @@ -231,6 +231,9 @@ impl Default for ZigZagData { } impl OperationsVTable for ZigZag { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ZigZag>, index: usize, @@ -274,6 +277,7 @@ mod test { use crate::zigzag_encode; #[test] + #[expect(deprecated)] fn test_compute_statistics() -> VortexResult<()> { let mut ctx = array_session().create_execution_ctx(); let array = buffer![1i32, -5i32, 2, 3, 4, 5, 6, 7, 8, 9, 10] diff --git a/encodings/zigzag/src/compute/mod.rs b/encodings/zigzag/src/compute/mod.rs index 354593e284a..75e91b5ae2c 100644 --- a/encodings/zigzag/src/compute/mod.rs +++ b/encodings/zigzag/src/compute/mod.rs @@ -92,6 +92,7 @@ mod tests { }); #[test] + #[expect(deprecated)] pub fn nullable_scalar_at() -> VortexResult<()> { let zigzag = zigzag_encode( PrimitiveArray::new(buffer![-189, -160, 1], Validity::AllValid).as_view(), diff --git a/encodings/zstd/src/array.rs b/encodings/zstd/src/array.rs index fb3551e539b..f3f84ff3acf 100644 --- a/encodings/zstd/src/array.rs +++ b/encodings/zstd/src/array.rs @@ -1588,6 +1588,9 @@ impl ValidityVTable for Zstd { } impl OperationsVTable for Zstd { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Zstd>, index: usize, diff --git a/encodings/zstd/src/test.rs b/encodings/zstd/src/test.rs index fafbfcaf159..2d3f31a5782 100644 --- a/encodings/zstd/src/test.rs +++ b/encodings/zstd/src/test.rs @@ -79,6 +79,7 @@ fn test_zstd_empty() { } #[test] +#[expect(deprecated)] fn test_zstd_with_validity_and_multi_frame() { let mut ctx = array_session().create_execution_ctx(); let data: Vec = (0..200).collect(); diff --git a/encodings/zstd/src/zstd_buffers.rs b/encodings/zstd/src/zstd_buffers.rs index f21deee6f64..883f435f6cd 100644 --- a/encodings/zstd/src/zstd_buffers.rs +++ b/encodings/zstd/src/zstd_buffers.rs @@ -520,6 +520,9 @@ impl VTable for ZstdBuffers { } impl OperationsVTable for ZstdBuffers { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ZstdBuffers>, index: usize, @@ -686,6 +689,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_validity_delegates_for_nullable_input() -> VortexResult<()> { let input = make_nullable_primitive_array(); let compressed = ZstdBuffers::compress(&input, 3, &array_session())?.into_array(); diff --git a/fuzz/src/array/compare.rs b/fuzz/src/array/compare.rs index 03ce50a7170..6fe2b1a1051 100644 --- a/fuzz/src/array/compare.rs +++ b/fuzz/src/array/compare.rs @@ -23,6 +23,7 @@ use vortex_buffer::ByteBuffer; use vortex_error::VortexExpect; use vortex_error::vortex_panic; +#[expect(deprecated)] pub fn compare_canonical_array( array: &ArrayRef, value: &Scalar, diff --git a/fuzz/src/array/fill_null.rs b/fuzz/src/array/fill_null.rs index fd8d8ec88c3..2e6ee1f9d9a 100644 --- a/fuzz/src/array/fill_null.rs +++ b/fuzz/src/array/fill_null.rs @@ -198,6 +198,7 @@ fn fill_decimal_array( }) } +#[expect(deprecated)] fn fill_varbinview_array( array: VarBinViewArray, fill_value: &Scalar, diff --git a/fuzz/src/array/filter.rs b/fuzz/src/array/filter.rs index 5b90d1cecc8..bad5f860a1e 100644 --- a/fuzz/src/array/filter.rs +++ b/fuzz/src/array/filter.rs @@ -22,6 +22,7 @@ use vortex_error::VortexResult; use crate::array::take_canonical_array_non_nullable_indices; +#[expect(deprecated)] pub fn filter_canonical_array( array: &ArrayRef, filter: &[bool], diff --git a/fuzz/src/array/mask.rs b/fuzz/src/array/mask.rs index e59c2f4fed9..1bfe9829132 100644 --- a/fuzz/src/array/mask.rs +++ b/fuzz/src/array/mask.rs @@ -63,6 +63,7 @@ pub fn mask_validity(validity: &Validity, mask: &Mask, ctx: &mut ExecutionCtx) - /// Apply mask on the canonical form of the array to get a consistent baseline. /// This implementation manually applies the mask to each canonical type /// without using the mask_fn method, to serve as an independent baseline for testing. +#[expect(deprecated)] pub fn mask_canonical_array( canonical: Canonical, mask: &Mask, @@ -198,6 +199,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_mask_null_array() { let mut ctx = array_session().create_execution_ctx(); let array = NullArray::new(5); @@ -279,6 +281,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_mask_list_array() { let mut ctx = array_session().create_execution_ctx(); let elements = PrimitiveArray::from_iter([1i32, 2, 3, 4, 5, 6]).into_array(); @@ -300,6 +303,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_mask_fixed_size_list_array() { let mut ctx = array_session().create_execution_ctx(); let elements = PrimitiveArray::from_iter([1i32, 2, 3, 4, 5, 6]).into_array(); @@ -317,6 +321,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_mask_struct_array() { let mut ctx = array_session().create_execution_ctx(); let field1 = PrimitiveArray::from_iter([1i32, 2, 3]).into_array(); diff --git a/fuzz/src/array/mod.rs b/fuzz/src/array/mod.rs index e513c5daf81..1122a96c030 100644 --- a/fuzz/src/array/mod.rs +++ b/fuzz/src/array/mod.rs @@ -175,6 +175,7 @@ impl ExpectedValue { } impl<'a> Arbitrary<'a> for FuzzArrayAction { + #[expect(deprecated)] fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result { let array = ArbitraryArray::arbitrary_with_config( u, @@ -591,6 +592,7 @@ pub fn compress_array( /// - `Ok(false)` - reject from corpus /// - `Err(_)` - a bug was found #[expect(clippy::result_large_err)] +#[expect(deprecated)] pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> VortexFuzzResult { let FuzzArrayAction { array, actions } = fuzz_action; let mut current_array = array; @@ -739,6 +741,7 @@ fn assert_search_sorted( /// Uses `all_non_distinct` for an efficient buffer-level comparison on the happy path. /// Falls back to element-wise scalar comparison only on mismatch to produce a detailed error. #[expect(clippy::result_large_err)] +#[expect(deprecated)] pub fn assert_array_eq( lhs: &ArrayRef, rhs: &ArrayRef, diff --git a/fuzz/src/array/scalar_at.rs b/fuzz/src/array/scalar_at.rs index a391822f67e..de0c6f0b073 100644 --- a/fuzz/src/array/scalar_at.rs +++ b/fuzz/src/array/scalar_at.rs @@ -25,6 +25,7 @@ use vortex_error::VortexResult; /// Baseline implementation of scalar_at that works on canonical arrays. /// This implementation manually extracts the scalar value from each canonical type /// without using the scalar_at method, to serve as an independent baseline for testing. +#[expect(deprecated)] pub fn scalar_at_canonical_array( canonical: Canonical, index: usize, diff --git a/fuzz/src/array/search_sorted.rs b/fuzz/src/array/search_sorted.rs index 6eb0d63e93a..23efe253b15 100644 --- a/fuzz/src/array/search_sorted.rs +++ b/fuzz/src/array/search_sorted.rs @@ -59,6 +59,7 @@ impl IndexOrd> for SearchPrimitiveSlice { } } +#[expect(deprecated)] pub fn search_sorted_canonical_array( array: &ArrayRef, scalar: &Scalar, diff --git a/fuzz/src/array/slice.rs b/fuzz/src/array/slice.rs index e121337e5d3..2b977181cf1 100644 --- a/fuzz/src/array/slice.rs +++ b/fuzz/src/array/slice.rs @@ -23,6 +23,7 @@ use vortex_array::match_each_native_ptype; use vortex_array::validity::Validity; use vortex_error::VortexResult; +#[expect(deprecated)] pub fn slice_canonical_array( array: &ArrayRef, start: usize, diff --git a/fuzz/src/array/sort.rs b/fuzz/src/array/sort.rs index b0af8638898..b5772c9acd6 100644 --- a/fuzz/src/array/sort.rs +++ b/fuzz/src/array/sort.rs @@ -20,6 +20,7 @@ use vortex_error::VortexResult; use crate::array::take_canonical_array_non_nullable_indices; +#[expect(deprecated)] pub fn sort_canonical_array(array: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult { match array.dtype() { DType::Bool(_) => { diff --git a/fuzz/src/array/take.rs b/fuzz/src/array/take.rs index 460cdf1593c..def3e627b8f 100644 --- a/fuzz/src/array/take.rs +++ b/fuzz/src/array/take.rs @@ -40,6 +40,7 @@ pub fn take_canonical_array_non_nullable_indices( ) } +#[expect(deprecated)] pub fn take_canonical_array( array: &ArrayRef, indices: &[Option], diff --git a/fuzz/src/gpu/mod.rs b/fuzz/src/gpu/mod.rs index 92691949cdf..877aee80e88 100644 --- a/fuzz/src/gpu/mod.rs +++ b/fuzz/src/gpu/mod.rs @@ -96,6 +96,7 @@ fn arbitrary_gpu_primitive_dtype(u: &mut Unstructured) -> Result VortexFuzzResult { use vortex_cuda::CanonicalCudaExt; use vortex_cuda::CudaSession; diff --git a/vortex-array/benches/scalar_at_struct.rs b/vortex-array/benches/scalar_at_struct.rs index 2564120f12e..12546e1f8b4 100644 --- a/vortex-array/benches/scalar_at_struct.rs +++ b/vortex-array/benches/scalar_at_struct.rs @@ -32,6 +32,7 @@ const NUM_ACCESSES: usize = 100; static SESSION: LazyLock = LazyLock::new(array_session); #[divan::bench] +#[expect(deprecated)] fn execute_scalar_struct_simple(bencher: Bencher) { let mut rng = StdRng::seed_from_u64(0); let range = Uniform::new(0i64, 100_000_000).unwrap(); @@ -65,6 +66,7 @@ fn execute_scalar_struct_simple(bencher: Bencher) { } #[divan::bench] +#[expect(deprecated)] fn execute_scalar_struct_wide(bencher: Bencher) { let mut rng = StdRng::seed_from_u64(0); let range = Uniform::new(0i64, 100_000_000).unwrap(); diff --git a/vortex-array/benches/validity_is_valid.rs b/vortex-array/benches/validity_is_valid.rs index dc22fcb5478..0788254455e 100644 --- a/vortex-array/benches/validity_is_valid.rs +++ b/vortex-array/benches/validity_is_valid.rs @@ -41,6 +41,7 @@ static SESSION: LazyLock = LazyLock::new(array_session); /// Per-element validity check over array-backed validity (the antipattern). This mirrors the /// deprecated `Validity::is_valid(i)`: a fresh `ExecutionCtx` plus a scalar lookup on every call. #[divan::bench(args = SIZES)] +#[expect(deprecated)] fn is_valid_per_element(bencher: Bencher, len: usize) { let validity = array_validity(len); bencher diff --git a/vortex-array/src/aggregate_fn/fns/all_non_distinct/tests.rs b/vortex-array/src/aggregate_fn/fns/all_non_distinct/tests.rs index ab513670c18..2b29ad5fd8d 100644 --- a/vortex-array/src/aggregate_fn/fns/all_non_distinct/tests.rs +++ b/vortex-array/src/aggregate_fn/fns/all_non_distinct/tests.rs @@ -29,6 +29,7 @@ use crate::validity::Validity; /// Baseline oracle: compare two arrays element-wise using `execute_scalar`. /// Returns true iff every position has the same scalar (null == null is true). +#[expect(deprecated)] fn scalar_baseline(a: &ArrayRef, b: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResult { assert_eq!(a.len(), b.len()); for i in 0..a.len() { diff --git a/vortex-array/src/aggregate_fn/fns/all_non_distinct/variant.rs b/vortex-array/src/aggregate_fn/fns/all_non_distinct/variant.rs index 1576b8c3d6a..04476d3b72a 100644 --- a/vortex-array/src/aggregate_fn/fns/all_non_distinct/variant.rs +++ b/vortex-array/src/aggregate_fn/fns/all_non_distinct/variant.rs @@ -15,6 +15,7 @@ use crate::arrays::VariantArray; /// aggregate kernel that intercepts the comparison before it reaches this fallback. /// /// [`all_non_distinct`]: super::all_non_distinct +#[expect(deprecated)] pub(super) fn check_variant_identical( lhs: &VariantArray, rhs: &VariantArray, diff --git a/vortex-array/src/aggregate_fn/fns/first/mod.rs b/vortex-array/src/aggregate_fn/fns/first/mod.rs index c41e2575057..6ba7fe14138 100644 --- a/vortex-array/src/aggregate_fn/fns/first/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/first/mod.rs @@ -92,6 +92,7 @@ impl AggregateFnVTable for First { partial.value.is_some() } + #[expect(deprecated)] fn try_accumulate( &self, partial: &mut Self::Partial, diff --git a/vortex-array/src/aggregate_fn/fns/is_constant/mod.rs b/vortex-array/src/aggregate_fn/fns/is_constant/mod.rs index 96017c3ed92..b0907a2f7f4 100644 --- a/vortex-array/src/aggregate_fn/fns/is_constant/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/is_constant/mod.rs @@ -187,6 +187,7 @@ impl IsConstant { /// Kernels that compute `is_constant` by delegating to child arrays can call this /// to package the boolean result into the partial struct format expected by the /// accumulator, avoiding duplicated boilerplate. + #[expect(deprecated)] pub fn make_partial( batch: &ArrayRef, is_constant: bool, @@ -354,6 +355,7 @@ impl AggregateFnVTable for IsConstant { !partial.is_constant } + #[expect(deprecated)] fn accumulate( &self, partial: &mut Self::Partial, diff --git a/vortex-array/src/aggregate_fn/fns/is_sorted/mod.rs b/vortex-array/src/aggregate_fn/fns/is_sorted/mod.rs index 99a7b99128a..b61be19ddac 100644 --- a/vortex-array/src/aggregate_fn/fns/is_sorted/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/is_sorted/mod.rs @@ -70,6 +70,7 @@ pub fn is_strict_sorted(array: &ArrayRef, ctx: &mut ExecutionCtx) -> VortexResul is_sorted_impl(array, true, ctx) } +#[expect(deprecated)] fn is_sorted_impl(array: &ArrayRef, strict: bool, ctx: &mut ExecutionCtx) -> VortexResult { let stat = if strict { Stat::IsStrictSorted @@ -172,6 +173,7 @@ impl IsSorted { /// Kernels that compute `is_sorted` by delegating to child arrays can call this /// to package the boolean result into the partial struct format expected by the /// accumulator, avoiding duplicated boilerplate. + #[expect(deprecated)] pub fn make_partial( batch: &ArrayRef, is_sorted: bool, @@ -401,6 +403,7 @@ impl AggregateFnVTable for IsSorted { !partial.is_sorted } + #[expect(deprecated)] fn accumulate( &self, partial: &mut Self::Partial, diff --git a/vortex-array/src/aggregate_fn/fns/last/mod.rs b/vortex-array/src/aggregate_fn/fns/last/mod.rs index 63ee54a6efa..73a1ca6d8e4 100644 --- a/vortex-array/src/aggregate_fn/fns/last/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/last/mod.rs @@ -93,6 +93,7 @@ impl AggregateFnVTable for Last { false } + #[expect(deprecated)] fn try_accumulate( &self, partial: &mut Self::Partial, diff --git a/vortex-array/src/aggregate_fn/fns/mean/mod.rs b/vortex-array/src/aggregate_fn/fns/mean/mod.rs index a3a0f77cb45..49a9b9d8d28 100644 --- a/vortex-array/src/aggregate_fn/fns/mean/mod.rs +++ b/vortex-array/src/aggregate_fn/fns/mean/mod.rs @@ -435,6 +435,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn mean_grouped_finalize() -> VortexResult<()> { let cases = mean_nan_null(); let elements = PrimitiveArray::from_option_iter( diff --git a/vortex-array/src/aggregate_fn/fns/sum/grouped.rs b/vortex-array/src/aggregate_fn/fns/sum/grouped.rs index c44feb44823..fade8cd0510 100644 --- a/vortex-array/src/aggregate_fn/fns/sum/grouped.rs +++ b/vortex-array/src/aggregate_fn/fns/sum/grouped.rs @@ -323,6 +323,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn listview_float_nan_and_inf() -> VortexResult<()> { let elements = PrimitiveArray::new( buffer![1.0f64, f64::NAN, 2.0, f64::INFINITY, f64::NEG_INFINITY, 4.0], @@ -363,6 +364,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn listview_float_nan_not_skipping() -> VortexResult<()> { let elements = PrimitiveArray::new( buffer![1.0f64, f64::NAN, 2.0, 3.0, 4.0], diff --git a/vortex-array/src/array/erased.rs b/vortex-array/src/array/erased.rs index 76c0b33cd18..aac37835cc3 100644 --- a/vortex-array/src/array/erased.rs +++ b/vortex-array/src/array/erased.rs @@ -21,11 +21,13 @@ use crate::AnyCanonical; use crate::Array; use crate::ArrayEq; use crate::ArrayHash; +use crate::ArrayProbe; use crate::ArrayView; use crate::Canonical; use crate::ExecutionCtx; use crate::ExecutionResult; use crate::IntoArray; +use crate::ProbeUsage; use crate::VTable; use crate::VortexSessionExecute; use crate::aggregate_fn::fns::sum::sum; @@ -264,40 +266,56 @@ impl ArrayRef { /// Fetch the scalar at the given index. #[deprecated( - note = "Use `execute_scalar` instead, which allows passing an execution context for more \ - efficient execution when fetching multiple scalars from the same array." + note = "Use `ArrayRef::probe` instead, which takes an execution context and retains \ + encoding state across lookups: `array.probe(ProbeUsage::Once).execute_scalar(index, ctx)`." )] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn scalar_at(&self, index: usize) -> VortexResult { self.execute_scalar(index, &mut legacy_session().create_execution_ctx()) } /// Execute the array to extract a scalar at the given index. + #[deprecated( + note = "Use `ArrayRef::probe` instead, which retains encoding state across lookups: \ + `array.probe(ProbeUsage::Once).execute_scalar(index, ctx)`, or `ProbeUsage::Repeated` \ + when reading more than one index from the same array." + )] pub fn execute_scalar(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { - vortex_ensure!(index < self.len(), OutOfBounds: index, 0, self.len()); - if self.dtype().is_nullable() && self.is_invalid(index, ctx)? { - return Ok(Scalar::null(self.dtype().clone())); - } - let scalar = self.0.data.execute_scalar(self, index, ctx)?; - debug_assert_eq!(self.dtype(), scalar.dtype(), "Scalar dtype mismatch"); - Ok(scalar) + self.probe(ProbeUsage::Once).execute_scalar(index, ctx) + } + + /// Create an accessor with the requested policy for retaining state between scalar lookups. + /// + /// ``` + /// use vortex_array::{IntoArray, ProbeUsage, VortexSessionExecute}; + /// use vortex_array::arrays::PrimitiveArray; + /// + /// let array = PrimitiveArray::from_iter([10i32, 20, 30]).into_array(); + /// let mut ctx = vortex_array::array_session().create_execution_ctx(); + /// let mut probe = array.probe(ProbeUsage::Repeated); + /// assert_eq!(probe.execute_scalar(2, &mut ctx)?, 30i32.into()); + /// assert_eq!(probe.execute_scalar(0, &mut ctx)?, 10i32.into()); + /// # Ok::<(), vortex_error::VortexError>(()) + /// ``` + pub fn probe(&self, usage: ProbeUsage) -> ArrayProbe { + ArrayProbe::new(self.clone(), usage) } /// Returns whether the item at `index` is valid. + #[deprecated( + note = "Use `ArrayRef::probe` instead, which retains validity state across lookups: \ + `array.probe(ProbeUsage::Once).execute_is_valid(index, ctx)`, or `ProbeUsage::Repeated` \ + when reading more than one index from the same array." + )] pub fn is_valid(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { - vortex_ensure!(index < self.len(), OutOfBounds: index, 0, self.len()); - match self.validity()? { - Validity::NonNullable | Validity::AllValid => Ok(true), - Validity::AllInvalid => Ok(false), - Validity::Array(a) => a - .execute_scalar(index, ctx)? - .as_bool() - .value() - .ok_or_else(|| vortex_err!("validity value at index {} is null", index)), - } + self.probe(ProbeUsage::Once).execute_is_valid(index, ctx) } /// Returns whether the item at `index` is invalid. + #[deprecated(note = "Use `ArrayRef::probe` instead: \ + `!array.probe(ProbeUsage::Once).execute_is_valid(index, ctx)?`.")] + #[expect(deprecated)] pub fn is_invalid(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { Ok(!self.is_valid(index, ctx)?) } diff --git a/vortex-array/src/array/mod.rs b/vortex-array/src/array/mod.rs index 8b9b2812bfa..aa36aebc620 100644 --- a/vortex-array/src/array/mod.rs +++ b/vortex-array/src/array/mod.rs @@ -31,6 +31,17 @@ pub use erased::*; mod plugin; pub use plugin::*; +mod probe; +pub use probe::ArrayProbe; +pub use probe::ProbeAccess; +pub use probe::ProbeChildren; +pub use probe::ProbeCtx; +pub use probe::ProbeSlot; +pub use probe::ProbeState; +use probe::ProbeStorage; +pub use probe::ProbeUsage; +pub use probe::ValidityProbe; + mod foreign; pub(crate) use foreign::*; @@ -220,13 +231,19 @@ pub(crate) trait DynArrayData: 'static + private::Sealed + Send + Sync + Debug { ctx: &mut ExecutionCtx, ) -> VortexResult; - /// Execute the scalar at the given index. - /// - /// This method panics if the index is out of bounds for the array. - fn execute_scalar( + fn probe_is_valid( + &self, + this: &ArrayRef, + index: usize, + state: Option<&mut ProbeStorage>, + ctx: &mut ExecutionCtx, + ) -> VortexResult; + + fn probe_scalar( &self, this: &ArrayRef, index: usize, + state: Option<&mut ProbeStorage>, ctx: &mut ExecutionCtx, ) -> VortexResult; } @@ -490,14 +507,43 @@ impl DynArrayData for ArrayData { V::execute(typed, ctx) } - fn execute_scalar( + fn probe_is_valid( &self, this: &ArrayRef, index: usize, + state: Option<&mut ProbeStorage>, + ctx: &mut ExecutionCtx, + ) -> VortexResult { + let mut validity = match state { + Some(storage) => storage + .validity::<>::ProbeState>(this)?, + None => ValidityProbe::once(this)?, + }; + validity + .execute_scalar(index, ctx)? + .as_bool() + .value() + .ok_or_else(|| vortex_err!("validity value at index {index} is null")) + } + + fn probe_scalar( + &self, + this: &ArrayRef, + index: usize, + state: Option<&mut ProbeStorage>, ctx: &mut ExecutionCtx, ) -> VortexResult { + // SAFETY: this adapter belongs to the ArrayData stored in `this`. let view = unsafe { ArrayView::new_unchecked(this, &self.data) }; - >::scalar_at(view, index, ctx) + match state { + Some(storage) => storage.scalar_at(view, index, ctx), + None => >::probe_scalar( + view, + index, + ProbeAccess::Once(this), + ctx, + ), + } } } diff --git a/vortex-array/src/array/probe.rs b/vortex-array/src/array/probe.rs new file mode 100644 index 00000000000..c8efd158216 --- /dev/null +++ b/vortex-array/src/array/probe.rs @@ -0,0 +1,390 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +//! Random scalar access with optional, encoding-specific retained state. + +use std::any::Any; + +use vortex_error::VortexResult; +use vortex_error::vortex_ensure; +use vortex_error::vortex_err; + +use crate::ArrayRef; +use crate::ArrayView; +use crate::ExecutionCtx; +use crate::array::VTable; +use crate::scalar::Scalar; +use crate::validity::Validity; +use crate::vtable::OperationsVTable; + +/// Whether scalar access should retain preparation for subsequent lookups. +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +pub enum ProbeUsage { + /// Use temporary resources only, without initializing retained probe state. + Once, + /// Allow the encoding to retain preparation and decoded data between lookups. + Repeated, +} + +/// A scalar accessor that owns its source and retains preparation between lookups. +/// +/// Array handles share their buffers. Repeated access initializes encoding state and +/// child probes lazily; following the same slots reuses the same preparation. +/// `Once` retains no preparation. The probe can outlive the original array handle. +/// Probes are local to a thread. +pub struct ArrayProbe { + array: ArrayRef, + state: Option, +} + +/// Scalar access to a source array, with optional retained preparation. +pub enum ProbeAccess<'p, S> { + /// Read slots with fresh probes that retain no state. + Once(&'p ArrayRef), + /// Reuse the source's local state and child probes. + Repeated(ProbeCtx<'p, S>), +} + +/// Access to retained preparation, independent of source ownership. +pub struct ProbeCtx<'p, S> { + state: &'p mut S, + children: &'p mut ProbeChildren, + validity: &'p mut Option, +} + +impl ProbeAccess<'_, S> { + /// Access retained local state, if repeated access was requested. + pub fn state_mut(&mut self) -> Option<&mut S> { + match self { + Self::Once(_) => None, + Self::Repeated(probe) => Some(probe.state), + } + } + + /// Access validity using this context's retention policy. + /// + /// Array-backed validity is read lazily through an owned probe; repeated access retains it. + pub fn validity(&mut self) -> VortexResult> { + match self { + Self::Once(array) => ValidityProbe::once(array), + Self::Repeated(probe) => validity_access(&probe.children.array, probe.validity), + } + } + + /// Access a child slot using this context's retention policy. + /// + /// Returns `None` for an absent slot and an error for an out-of-bounds slot. + pub fn slot(&mut self, slot: usize) -> VortexResult>> { + match self { + Self::Once(array) => { + let child = array + .slots() + .get(slot) + .ok_or_else(|| vortex_err!("Probe slot {slot} is out of bounds"))?; + Ok(child.as_ref().map(ProbeSlot::Once)) + } + Self::Repeated(probe) => Ok(probe.children.slot(slot)?.map(ProbeSlot::Repeated)), + } + } +} + +/// A child accessor that either starts a fresh probe or borrows a retained probe. +pub enum ProbeSlot<'p> { + /// A source read without retained preparation. + Once(&'p ArrayRef), + /// An existing repeated-access probe. + Repeated(&'p mut ArrayProbe), +} + +impl ProbeSlot<'_> { + /// The source array for this slot. + pub fn array(&self) -> &ArrayRef { + match self { + Self::Once(array) => array, + Self::Repeated(probe) => probe.array(), + } + } + + /// Read a scalar using fresh or retained preparation as appropriate. + pub fn execute_scalar(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + match self { + Self::Once(array) => array.probe(ProbeUsage::Once).execute_scalar(index, ctx), + Self::Repeated(probe) => probe.execute_scalar(index, ctx), + } + } +} + +/// Local encoding state and lazy child probes retained for one source array. +/// +/// The framework initializes this context once for repeated access and passes it to +/// [`OperationsVTable::probe_scalar`]. +/// One-off access uses [`ProbeAccess::Once`] instead. `S` is the encoding's associated state type; +/// it owns its prepared resources, including shared buffer or array handles. +pub struct ProbeState { + state: S, + children: ProbeChildren, + validity: Option, +} + +impl ProbeState { + pub(crate) fn new(array: &ArrayRef) -> Self { + Self { + state: S::default(), + children: ProbeChildren { + array: array.clone(), + slots: Vec::new(), + }, + validity: None, + } + } +} + +impl ProbeState { + /// Borrow retained preparation and children for scalar execution. + pub fn access(&mut self) -> ProbeAccess<'_, S> { + ProbeAccess::Repeated(ProbeCtx { + state: &mut self.state, + children: &mut self.children, + validity: &mut self.validity, + }) + } + + /// Access the encoding's retained local state. + pub fn state_mut(&mut self) -> &mut S { + &mut self.state + } + + /// Borrow local state and child access together, allowing disjoint mutable access. + pub fn parts(&mut self) -> (&mut S, &mut ProbeChildren) { + (&mut self.state, &mut self.children) + } +} + +/// Lazy child probes bound to the slots of one source array. +/// +/// Obtain this through [`ProbeState::parts`] when retaining a mutable borrow of local state +/// while accessing children. Each slot has independent state, even if two slots reference +/// the same array. The slot table allocates on its first valid request; unrequested slots +/// remain empty. Dropping the parent context drops every created child probe. +pub struct ProbeChildren { + array: ArrayRef, + slots: Vec>, +} + +impl ProbeChildren { + /// Get or create a repeated-access probe for the given source slot. + /// + /// Returns `None` for an absent slot and an error for an out-of-bounds slot. + /// Neither case allocates a slot table. + pub fn slot(&mut self, slot: usize) -> VortexResult> { + let child = self + .array + .slots() + .get(slot) + .ok_or_else(|| vortex_err!("Probe slot {slot} is out of bounds"))?; + let Some(child) = child else { + return Ok(None); + }; + if self.slots.is_empty() { + self.slots.resize_with(self.array.slots().len(), || None); + } + Ok(Some( + self.slots[slot].get_or_insert_with(|| child.probe(ProbeUsage::Repeated)), + )) + } +} + +impl ArrayProbe { + /// Own an array and choose whether to retain preparation. + pub fn new(array: ArrayRef, usage: ProbeUsage) -> Self { + Self { + array, + state: match usage { + ProbeUsage::Once => None, + ProbeUsage::Repeated => Some(ProbeStorage::new()), + }, + } + } + + /// The array this probe reads from. + pub fn array(&self) -> &ArrayRef { + &self.array + } + + /// Read a scalar, including its nullness, preparing and reusing state as appropriate. + pub fn execute_scalar(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + vortex_ensure!(index < self.array.len(), OutOfBounds: index, 0, self.array.len()); + if self.array.dtype().is_nullable() && !self.execute_is_valid(index, ctx)? { + return Ok(Scalar::null(self.array.dtype().clone())); + } + let scalar = + self.array + .dyn_array() + .probe_scalar(&self.array, index, self.state.as_mut(), ctx)?; + debug_assert_eq!(scalar.dtype(), self.array.dtype(), "Scalar dtype mismatch"); + Ok(scalar) + } + + /// Check bounds and read validity using this probe's retention policy. + pub fn execute_is_valid(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + vortex_ensure!(index < self.array.len(), OutOfBounds: index, 0, self.array.len()); + if !self.array.dtype().is_nullable() { + return Ok(true); + } + self.array + .dyn_array() + .probe_is_valid(&self.array, index, self.state.as_mut(), ctx) + } +} + +/// A validity accessor with the parent probe's retention policy. +/// +/// A probe borrowed from a parent knows the source array's length and checks bounds against it. +/// One built from a bare [`Validity`] has no length of its own: constant states answer every +/// index, and array-backed validity is bounds-checked by its own probe. +pub struct ValidityProbe<'p> { + len: Option, + inner: ValidityAccess<'p>, +} + +enum ValidityAccess<'p> { + Once(Validity), + Repeated(&'p mut ProbeValidity), + Owned(ProbeValidity), +} + +impl ValidityProbe<'_> { + pub(super) fn once(array: &ArrayRef) -> VortexResult { + Ok(Self { + len: Some(array.len()), + inner: ValidityAccess::Once(array.validity()?), + }) + } + + /// Own a [`Validity`] and choose whether to retain preparation between lookups. + pub(crate) fn owned(validity: Validity, usage: ProbeUsage) -> Self { + Self { + len: None, + inner: ValidityAccess::Owned(ProbeValidity::new(validity, usage)), + } + } + + /// Read a non-null boolean scalar indicating whether the requested row is valid. + #[expect(deprecated)] + pub fn execute_scalar(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + if let Some(len) = self.len { + vortex_ensure!(index < len, OutOfBounds: index, 0, len); + } + match &mut self.inner { + ValidityAccess::Once(validity) => match validity { + Validity::NonNullable | Validity::AllValid => Ok(true.into()), + Validity::AllInvalid => Ok(false.into()), + Validity::Array(array) => array.execute_scalar(index, ctx), + }, + ValidityAccess::Repeated(validity) => validity.execute_scalar(index, ctx), + ValidityAccess::Owned(validity) => validity.execute_scalar(index, ctx), + } + } + + /// Returns whether the item at `index` is valid. + pub fn execute_is_valid(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + self.execute_scalar(index, ctx)? + .as_bool() + .value() + .ok_or_else(|| vortex_err!("validity value at index {index} is null")) + } + + /// Returns whether the item at `index` is invalid. + pub fn execute_is_invalid( + &mut self, + index: usize, + ctx: &mut ExecutionCtx, + ) -> VortexResult { + Ok(!self.execute_is_valid(index, ctx)?) + } +} + +fn validity_access<'p>( + array: &ArrayRef, + slot: &'p mut Option, +) -> VortexResult> { + let validity = match slot { + Some(validity) => validity, + slot @ None => slot.insert(ProbeValidity::new(array.validity()?, ProbeUsage::Repeated)), + }; + Ok(ValidityProbe { + len: Some(array.len()), + inner: ValidityAccess::Repeated(validity), + }) +} + +enum ProbeValidity { + Constant(bool), + Array(ArrayProbe), +} + +impl ProbeValidity { + fn new(validity: Validity, usage: ProbeUsage) -> Self { + match validity { + Validity::NonNullable | Validity::AllValid => Self::Constant(true), + Validity::AllInvalid => Self::Constant(false), + Validity::Array(array) => Self::Array(ArrayProbe::new(array, usage)), + } + } + + fn execute_scalar(&mut self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { + match self { + Self::Constant(valid) => Ok((*valid).into()), + Self::Array(probe) => probe.execute_scalar(index, ctx), + } + } +} + +pub(crate) struct ProbeStorage { + // FIXME: Consider inline storage if benchmarks justify avoiding this allocation. + probe: Option>, +} + +impl ProbeStorage { + fn new() -> Self { + Self { probe: None } + } + + fn get_or_init( + &mut self, + array: &ArrayRef, + ) -> VortexResult<&mut ProbeState> { + self.probe + .get_or_insert_with(|| Box::new(ProbeState::::new(array))) + .downcast_mut::>() + .ok_or_else(|| vortex_err!("Probe state type mismatch")) + } + + pub(crate) fn validity( + &mut self, + array: &ArrayRef, + ) -> VortexResult> { + let state = self.get_or_init::(array)?; + validity_access(array, &mut state.validity) + } + + pub(crate) fn scalar_at( + &mut self, + array: ArrayView<'_, V>, + index: usize, + ctx: &mut ExecutionCtx, + ) -> VortexResult { + let state = self.get_or_init::<>::ProbeState>( + array.array(), + )?; + >::probe_scalar( + array, + index, + state.access(), + ctx, + ) + } +} + +#[cfg(test)] +mod tests; diff --git a/vortex-array/src/array/probe/tests.rs b/vortex-array/src/array/probe/tests.rs new file mode 100644 index 00000000000..fa2cb3232d8 --- /dev/null +++ b/vortex-array/src/array/probe/tests.rs @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: Copyright the Vortex contributors + +#![expect(deprecated)] + +use std::cell::Cell; +use std::rc::Rc; + +use rstest::rstest; +use vortex_error::VortexResult; +use vortex_error::vortex_err; + +use super::ProbeAccess; +use super::ProbeState; +use super::ProbeStorage; +use super::ProbeUsage; +use crate::ArrayRef; +use crate::IntoArray; +use crate::VortexSessionExecute; +use crate::arrays::PrimitiveArray; +use crate::arrays::StructArray; +use crate::scalar::Scalar; + +#[derive(Default)] +struct TrackedState { + reads: usize, + drops: Rc>, +} + +impl Drop for TrackedState { + fn drop(&mut self) { + self.drops.set(self.drops.get() + 1); + } +} + +#[test] +fn state_is_initialized_once_and_survives_moves() -> VortexResult<()> { + let array = PrimitiveArray::from_iter([42i32]).into_array(); + let mut storage = ProbeStorage::new(); + assert!(storage.probe.is_none()); + let state = storage.get_or_init::(&array)?; + state.state.reads += 1; + let drops = Rc::clone(&state.state.drops); + let mut moved = (storage, ()); + let state = moved.0.get_or_init::(&array)?; + assert_eq!(state.state.reads, 1); + assert!(Rc::ptr_eq(&state.state.drops, &drops)); + assert_eq!(drops.get(), 0); + drop(moved); + assert_eq!(drops.get(), 1); + Ok(()) +} + +#[test] +fn children_are_lazy_reused_and_bound_to_their_source_slots() -> VortexResult<()> { + let leaf = PrimitiveArray::from_iter([10i32, 20]).into_array(); + let array = StructArray::from_fields(&[("left", leaf.clone()), ("right", leaf)])?.into_array(); + let mut ctx = crate::array_session().create_execution_ctx(); + let mut probe = ProbeState::::new(&array); + assert_eq!(probe.children.slots.capacity(), 0); + // Slot zero is the absent struct validity; invalid requests must not allocate. + assert!(probe.children.slot(0)?.is_none()); + assert!(probe.children.slot(99).is_err()); + assert_eq!(probe.children.slots.capacity(), 0); + + let first = std::ptr::from_mut( + probe + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))?, + ); + assert!(probe.children.slots[2].is_none()); + let (state, children) = probe.parts(); + let child = children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))?; + assert!(child.execute_scalar(2, &mut ctx).is_err()); + assert_eq!(child.execute_scalar(0, &mut ctx)?, 10i32.into()); + *state += 1; + assert_eq!(*probe.state_mut(), 1); + assert_eq!( + std::ptr::from_mut( + probe + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + ), + first + ); + assert!( + probe + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .state + .as_ref() + .is_some_and(|state| state.probe.is_some()) + ); + + // Identical sources in different slots still get independent probe state. + assert_ne!( + std::ptr::from_mut( + probe + .children + .slot(2)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + ), + first + ); + let source = array.slots()[1] + .as_ref() + .ok_or_else(|| vortex_error::vortex_err!("missing fixture slot"))?; + assert!(ArrayRef::ptr_eq( + probe + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .array(), + source + )); + assert!( + probe + .children + .slot(2)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .state + .as_ref() + .is_some_and(|state| state.probe.is_none()) + ); + let mut other = ProbeState::::new(&array); + assert!( + other + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .state + .as_ref() + .is_some_and(|state| state.probe.is_none()) + ); + + let mut moved = (probe, ()); + assert_eq!( + std::ptr::from_mut( + moved + .0 + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + ), + first + ); + assert_eq!( + moved + .0 + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .execute_scalar(1, &mut ctx)?, + 20i32.into() + ); + Ok(()) +} + +#[rstest] +#[case(ProbeUsage::Once)] +#[case(ProbeUsage::Repeated)] +fn access_checks_bounds_and_nulls(#[case] usage: ProbeUsage) -> VortexResult<()> { + let array = PrimitiveArray::from_option_iter([Some(10i32), None, Some(30)]).into_array(); + let mut ctx = crate::array_session().create_execution_ctx(); + let mut probe = array.probe(usage); + assert!( + probe + .state + .as_ref() + .is_none_or(|state| state.probe.is_none()) + ); + assert!(probe.execute_scalar(3, &mut ctx).is_err()); + assert!( + probe + .state + .as_ref() + .is_none_or(|state| state.probe.is_none()) + ); + assert!(probe.execute_scalar(1, &mut ctx)?.is_null()); + assert_eq!( + probe + .state + .as_ref() + .is_some_and(|state| state.probe.is_some()), + usage == ProbeUsage::Repeated + ); + assert_eq!( + array.execute_scalar(0, &mut ctx)?, + Scalar::primitive(10i32, array.dtype().nullability()) + ); + assert!(array.execute_scalar(1, &mut ctx)?.is_null()); + assert!(array.execute_scalar(3, &mut ctx).is_err()); + for index in [2, 1, 0, 2] { + assert_eq!( + probe.execute_scalar(index, &mut ctx)?, + array.execute_scalar(index, &mut ctx)? + ); + } + if usage == ProbeUsage::Once { + assert!(probe.state.is_none()); + } + Ok(()) +} + +#[rstest] +fn slot_access_uses_context_policy( + #[values(ProbeUsage::Once, ProbeUsage::Repeated)] usage: ProbeUsage, +) -> VortexResult<()> { + let leaf = PrimitiveArray::from_option_iter([Some(10i32), None]).into_array(); + let array = StructArray::from_fields(&[("values", leaf)])?.into_array(); + let mut ctx = crate::array_session().create_execution_ctx(); + let mut retained = ProbeState::<()>::new(&array); + { + let mut probe = match usage { + ProbeUsage::Once => ProbeAccess::Once(&array), + ProbeUsage::Repeated => retained.access(), + }; + assert!(probe.slot(0)?.is_none()); + assert!(probe.slot(99).is_err()); + for index in [1, 0, 1, 0] { + let mut slot = probe + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))?; + assert_eq!( + slot.execute_scalar(index, &mut ctx)?, + slot.array().execute_scalar(index, &mut ctx)? + ); + } + assert!( + probe + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .execute_scalar(2, &mut ctx) + .is_err() + ); + } + match usage { + ProbeUsage::Once => assert_eq!(retained.children.slots.capacity(), 0), + ProbeUsage::Repeated => assert!( + retained + .children + .slot(1)? + .ok_or_else(|| vortex_err!("missing fixture slot"))? + .state + .as_ref() + .is_some_and(|state| state.probe.is_some()) + ), + } + Ok(()) +} + +#[test] +fn validity_is_owned_by_probe_state() -> VortexResult<()> { + let array = PrimitiveArray::from_option_iter([Some(10i32), None]).into_array(); + let mut ctx = crate::array_session().create_execution_ctx(); + let mut state = ProbeState::<()>::new(&array); + assert!(state.validity.is_none()); + assert_eq!( + state.access().validity()?.execute_scalar(1, &mut ctx)?, + false.into() + ); + assert_eq!(state.children.slots.capacity(), 0); + let mut validity = state + .validity + .take() + .ok_or_else(|| vortex_err!("missing validity probe"))?; + drop(state); + drop(array); + assert_eq!(validity.execute_scalar(0, &mut ctx)?, true.into()); + assert_eq!(validity.execute_scalar(1, &mut ctx)?, false.into()); + Ok(()) +} + +#[rstest] +fn validity_accessor_obeys_retention_policy( + #[values(ProbeUsage::Once, ProbeUsage::Repeated)] usage: ProbeUsage, +) -> VortexResult<()> { + let array = PrimitiveArray::from_option_iter([Some(10i32), None]).into_array(); + let mut ctx = crate::array_session().create_execution_ctx(); + let mut retained = ProbeState::<()>::new(&array); + for index in [0, 1, 0] { + let mut access = match usage { + ProbeUsage::Once => ProbeAccess::Once(&array), + ProbeUsage::Repeated => retained.access(), + }; + assert_eq!( + access.validity()?.execute_scalar(index, &mut ctx)?, + (index == 0).into() + ); + assert!(access.validity()?.execute_scalar(2, &mut ctx).is_err()); + } + assert_eq!(retained.validity.is_some(), usage == ProbeUsage::Repeated); + assert_eq!(retained.children.slots.capacity(), 0); + Ok(()) +} diff --git a/vortex-array/src/array/typed.rs b/vortex-array/src/array/typed.rs index a9def0318bf..95fad0612cb 100644 --- a/vortex-array/src/array/typed.rs +++ b/vortex-array/src/array/typed.rs @@ -19,10 +19,12 @@ use std::sync::Arc; use vortex_error::VortexResult; +use crate::ArrayProbe; use crate::ArrayRef; use crate::ArraySlots; use crate::ExecutionCtx; use crate::IntoArray; +use crate::ProbeUsage; use crate::VortexSessionExecute; use crate::array::ArrayId; use crate::array::ArrayView; @@ -381,16 +383,23 @@ impl Array { } #[deprecated( - note = "Use `execute_scalar` instead, which allows passing an execution context for more \ - efficient execution when fetching multiple scalars from the same array." + note = "Use `Array::::probe` instead, which takes an execution context and retains \ + encoding state across lookups: `array.probe(ProbeUsage::Once).execute_scalar(index, ctx)`." )] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn scalar_at(&self, index: usize) -> VortexResult { self.inner .execute_scalar(index, &mut legacy_session().create_execution_ctx()) } /// Execute the array to extract a scalar at the given index. + #[deprecated( + note = "Use `Array::::probe` instead, which retains encoding state across lookups: \ + `array.probe(ProbeUsage::Once).execute_scalar(index, ctx)`, or `ProbeUsage::Repeated` \ + when reading more than one index from the same array." + )] + #[expect(deprecated)] pub fn execute_scalar( &self, index: usize, @@ -399,6 +408,11 @@ impl Array { self.inner.execute_scalar(index, ctx) } + /// Create an accessor with the requested policy for retaining state between scalar lookups. + pub fn probe(&self, usage: ProbeUsage) -> ArrayProbe { + self.inner.probe(usage) + } + /// Filter the array with a selection mask. pub fn filter(&self, mask: vortex_mask::Mask) -> VortexResult { self.inner.filter(mask) @@ -415,11 +429,20 @@ impl Array { } /// Returns whether `index` is valid using the provided execution context. + #[deprecated( + note = "Use `Array::::probe` instead, which retains validity state across lookups: \ + `array.probe(ProbeUsage::Once).execute_is_valid(index, ctx)`, or `ProbeUsage::Repeated` \ + when reading more than one index from the same array." + )] + #[expect(deprecated)] pub fn is_valid(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { self.inner.is_valid(index, ctx) } /// Returns whether `index` is null using the provided execution context. + #[deprecated(note = "Use `Array::::probe` instead: \ + `!array.probe(ProbeUsage::Once).execute_is_valid(index, ctx)?`.")] + #[expect(deprecated)] pub fn is_invalid(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { self.inner.is_invalid(index, ctx) } diff --git a/vortex-array/src/array/vtable/operations.rs b/vortex-array/src/array/vtable/operations.rs index 7f49e683640..3f0f9cb5d10 100644 --- a/vortex-array/src/array/vtable/operations.rs +++ b/vortex-array/src/array/vtable/operations.rs @@ -5,6 +5,7 @@ use vortex_error::VortexResult; use vortex_error::vortex_bail; use crate::ExecutionCtx; +use crate::ProbeAccess; use crate::array::ArrayView; use crate::array::VTable; use crate::scalar::Scalar; @@ -17,6 +18,32 @@ use crate::vtable::NotSupported; /// [`ArrayRef`](crate::ArrayRef) /// methods perform common checks before dispatching here. pub trait OperationsVTable { + /// Encoding-specific state retained by repeated scalar access. + /// + /// Default construction should be cheap and avoid allocation or execution. Preparation + /// belongs in [`Self::probe_scalar`]. State owns its preparation and may retain shared + /// buffer or array handles. Request retained child probes through [`ProbeAccess`]. + /// Use `()` when no local state is needed. + type ProbeState: Default + 'static; + + /// Read a non-null scalar, optionally retaining state for subsequent reads. + /// + /// Bounds and validity have been checked; the row is non-null. `ProbeAccess::Once` requests one-off access and + /// never initializes a context; `ProbeAccess::Repeated` reuses local state and child probes for this source. + /// The scalar must retain the source's logical dtype, including nullability. + /// + /// The default preserves the existing scalar path without adding caching. + #[expect(deprecated)] + fn probe_scalar( + array: ArrayView<'_, V>, + index: usize, + _probe: ProbeAccess<'_, Self::ProbeState>, + ctx: &mut ExecutionCtx, + ) -> VortexResult { + // FIXME: Remove this default once all encodings have migrated to probe_scalar. + Self::scalar_at(array, index, ctx) + } + /// Fetch the scalar at the given index. /// /// ## Preconditions @@ -27,6 +54,11 @@ pub trait OperationsVTable { /// ## Postconditions /// /// The returned [`Scalar`] must have the same logical dtype as the array's element dtype. + // FIXME: Remove this hook once all encodings have migrated to probe_scalar. + #[deprecated( + note = "Implement `OperationsVTable::probe_scalar` instead, which is handed a \ + `ProbeAccess` so the encoding can retain preparation across lookups." + )] fn scalar_at( array: ArrayView<'_, V>, index: usize, @@ -35,6 +67,8 @@ pub trait OperationsVTable { } impl OperationsVTable for NotSupported { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, V>, _index: usize, diff --git a/vortex-array/src/arrays/assertions.rs b/vortex-array/src/arrays/assertions.rs index aff8d4e32cb..9a3a6f0939d 100644 --- a/vortex-array/src/arrays/assertions.rs +++ b/vortex-array/src/arrays/assertions.rs @@ -27,6 +27,7 @@ fn execute_to_canonical(array: ArrayRef, ctx: &mut ExecutionCtx) -> ArrayRef { /// Finds indices where two arrays differ based on `scalar_at` comparison. #[expect(clippy::unwrap_used)] +#[expect(deprecated)] fn find_mismatched_indices( left: &ArrayRef, right: &ArrayRef, @@ -54,7 +55,9 @@ macro_rules! assert_nth_scalar { use $crate::IntoArray as _; let arr_ref: $crate::ArrayRef = $crate::IntoArray::into_array($arr.clone()); let expected = $expected.try_into().unwrap(); - assert_eq!(arr_ref.execute_scalar($n, $ctx).unwrap(), expected); + #[expect(deprecated)] + let actual = arr_ref.execute_scalar($n, $ctx).unwrap(); + assert_eq!(actual, expected); }}; } @@ -70,6 +73,7 @@ macro_rules! assert_nth_scalar { macro_rules! assert_nth_scalar_is_null { ($arr:expr, $n:expr, $ctx:expr) => {{ let arr_ref: $crate::ArrayRef = $crate::IntoArray::into_array($arr.clone()); + #[expect(deprecated)] let scalar = arr_ref.execute_scalar($n, $ctx).unwrap(); assert!( scalar.is_null(), diff --git a/vortex-array/src/arrays/bool/array.rs b/vortex-array/src/arrays/bool/array.rs index 5b1083e7f88..610c00e9abf 100644 --- a/vortex-array/src/arrays/bool/array.rs +++ b/vortex-array/src/arrays/bool/array.rs @@ -388,6 +388,7 @@ mod tests { use crate::validity::Validity; #[test] + #[expect(deprecated)] fn bool_array() { let mut ctx = array_session().create_execution_ctx(); @@ -397,6 +398,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_all_some_iter() { let mut ctx = array_session().create_execution_ctx(); @@ -411,6 +413,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_bool_from_iter() { let mut ctx = array_session().create_execution_ctx(); let arr = BoolArray::from_iter([Some(true), Some(true), None, Some(false), None]); diff --git a/vortex-array/src/arrays/bool/vtable/operations.rs b/vortex-array/src/arrays/bool/vtable/operations.rs index c29ab20331b..e1ec02ecbc8 100644 --- a/vortex-array/src/arrays/bool/vtable/operations.rs +++ b/vortex-array/src/arrays/bool/vtable/operations.rs @@ -11,6 +11,8 @@ use crate::arrays::bool::BoolArrayExt; use crate::scalar::Scalar; impl OperationsVTable for Bool { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Bool>, index: usize, diff --git a/vortex-array/src/arrays/chunked/tests.rs b/vortex-array/src/arrays/chunked/tests.rs index e0755108e9c..d903dbc2ae0 100644 --- a/vortex-array/src/arrays/chunked/tests.rs +++ b/vortex-array/src/arrays/chunked/tests.rs @@ -397,6 +397,7 @@ pub fn pack_nested_structs() -> VortexResult<()> { } #[test] +#[expect(deprecated)] pub fn pack_nested_lists() { let mut ctx = SESSION.create_execution_ctx(); let l1 = ListArray::try_new( diff --git a/vortex-array/src/arrays/chunked/vtable/canonical.rs b/vortex-array/src/arrays/chunked/vtable/canonical.rs index a521fd0e6cc..1adc5b2ddbb 100644 --- a/vortex-array/src/arrays/chunked/vtable/canonical.rs +++ b/vortex-array/src/arrays/chunked/vtable/canonical.rs @@ -371,6 +371,7 @@ mod tests { } } + #[expect(deprecated)] fn assert_variant_values(array: &VariantArray, expected: &[i32]) -> VortexResult<()> { assert_eq!(array.len(), expected.len()); let mut ctx = SESSION.create_execution_ctx(); @@ -575,6 +576,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn pack_nested_lists() { let mut ctx = SESSION.create_execution_ctx(); let l1 = ListArray::try_new( @@ -614,6 +616,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn pack_fixed_size_lists() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let f1 = FixedSizeListArray::try_new( diff --git a/vortex-array/src/arrays/chunked/vtable/operations.rs b/vortex-array/src/arrays/chunked/vtable/operations.rs index 8f9e0867a88..b8bfcdf3f1b 100644 --- a/vortex-array/src/arrays/chunked/vtable/operations.rs +++ b/vortex-array/src/arrays/chunked/vtable/operations.rs @@ -11,6 +11,9 @@ use crate::arrays::chunked::ChunkedArrayExt; use crate::scalar::Scalar; impl OperationsVTable for Chunked { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Chunked>, index: usize, diff --git a/vortex-array/src/arrays/constant/compute/cast.rs b/vortex-array/src/arrays/constant/compute/cast.rs index 439bf8367b8..e3a093553cc 100644 --- a/vortex-array/src/arrays/constant/compute/cast.rs +++ b/vortex-array/src/arrays/constant/compute/cast.rs @@ -49,6 +49,7 @@ mod tests { #[test] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn test_cast_constant_i64_to_decimal() { let target_dtype = DType::Decimal(DecimalDType::new(21, 2), Nullability::NonNullable); let casted = ConstantArray::new(Scalar::from(42i64), 5) diff --git a/vortex-array/src/arrays/constant/vtable/canonical.rs b/vortex-array/src/arrays/constant/vtable/canonical.rs index e6a656afa51..ec1e64a7532 100644 --- a/vortex-array/src/arrays/constant/vtable/canonical.rs +++ b/vortex-array/src/arrays/constant/vtable/canonical.rs @@ -394,6 +394,7 @@ mod tests { static SESSION: LazyLock = LazyLock::new(crate::array_session); #[test] + #[expect(deprecated)] fn test_canonicalize_null() { let mut ctx = SESSION.create_execution_ctx(); let const_null = ConstantArray::new(Scalar::null(DType::Null), 42); @@ -445,6 +446,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_canonicalize_scalar_values() { let mut ctx = SESSION.create_execution_ctx(); let f16_value = f16::from_f32(5.722046e-6); @@ -718,6 +720,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_canonicalize_fixed_size_list_nested() { let mut ctx = SESSION.create_execution_ctx(); // Test with nested data types (list of strings). @@ -782,6 +785,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_canonicalize_fixed_size_list_with_null_elements() { let mut ctx = SESSION.create_execution_ctx(); // Test FSL with nullable element type where some elements are null. @@ -836,6 +840,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_canonicalize_fixed_size_list_large() { let mut ctx = SESSION.create_execution_ctx(); // Test with a large constant array. diff --git a/vortex-array/src/arrays/constant/vtable/operations.rs b/vortex-array/src/arrays/constant/vtable/operations.rs index e3568a9c39f..c95be262f0f 100644 --- a/vortex-array/src/arrays/constant/vtable/operations.rs +++ b/vortex-array/src/arrays/constant/vtable/operations.rs @@ -10,6 +10,8 @@ use crate::arrays::Constant; use crate::scalar::Scalar; impl OperationsVTable for Constant { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Constant>, _index: usize, @@ -33,6 +35,7 @@ mod tests { use crate::scalar::Scalar; #[test] + #[expect(deprecated)] fn scalar_at_preserves_union_scalar() -> VortexResult<()> { let variants = UnionVariants::try_new( ["int", "string"].into(), diff --git a/vortex-array/src/arrays/decimal/compute/cast.rs b/vortex-array/src/arrays/decimal/compute/cast.rs index 8770a9bc8f4..251e6378c5d 100644 --- a/vortex-array/src/arrays/decimal/compute/cast.rs +++ b/vortex-array/src/arrays/decimal/compute/cast.rs @@ -876,6 +876,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn cast_decimal_f64_null() { let values = [Some(100i32), None, Some(-200)]; let array = DecimalArray::from_option_iter(values, DecimalDType::new(6, 2)); @@ -904,6 +905,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn cast_decimal_f64_all_null() { let dtype = DecimalDType::new(6, 2); let buf = buffer![i32::MAX, i32::MIN, 12345]; diff --git a/vortex-array/src/arrays/decimal/vtable/operations.rs b/vortex-array/src/arrays/decimal/vtable/operations.rs index 257f26127ae..af628b3d8e1 100644 --- a/vortex-array/src/arrays/decimal/vtable/operations.rs +++ b/vortex-array/src/arrays/decimal/vtable/operations.rs @@ -12,6 +12,8 @@ use crate::scalar::DecimalValue; use crate::scalar::Scalar; impl OperationsVTable for Decimal { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Decimal>, index: usize, @@ -72,6 +74,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_scalar_at() { let array = DecimalArray::new( buffer![100i128], diff --git a/vortex-array/src/arrays/dict/vtable/operations.rs b/vortex-array/src/arrays/dict/vtable/operations.rs index 1982a1e0870..d1380cc888b 100644 --- a/vortex-array/src/arrays/dict/vtable/operations.rs +++ b/vortex-array/src/arrays/dict/vtable/operations.rs @@ -12,6 +12,9 @@ use crate::arrays::dict::DictArraySlotsExt; use crate::scalar::Scalar; impl OperationsVTable for Dict { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Dict>, index: usize, diff --git a/vortex-array/src/arrays/extension/vtable/operations.rs b/vortex-array/src/arrays/extension/vtable/operations.rs index 66de94b596a..11fd8d48d22 100644 --- a/vortex-array/src/arrays/extension/vtable/operations.rs +++ b/vortex-array/src/arrays/extension/vtable/operations.rs @@ -11,6 +11,9 @@ use crate::arrays::extension::ExtensionArrayExt; use crate::scalar::Scalar; impl OperationsVTable for Extension { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Extension>, index: usize, diff --git a/vortex-array/src/arrays/filter/execute/listview.rs b/vortex-array/src/arrays/filter/execute/listview.rs index ba15ee51998..7a5f25376e6 100644 --- a/vortex-array/src/arrays/filter/execute/listview.rs +++ b/vortex-array/src/arrays/filter/execute/listview.rs @@ -294,6 +294,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_filter_extreme_offsets() { // ListView-specific: Test with very large offsets. let elements = PrimitiveArray::from_iter(0i32..10000).into_array(); diff --git a/vortex-array/src/arrays/filter/vtable.rs b/vortex-array/src/arrays/filter/vtable.rs index 56fc112aa16..6d15d0afce7 100644 --- a/vortex-array/src/arrays/filter/vtable.rs +++ b/vortex-array/src/arrays/filter/vtable.rs @@ -200,6 +200,9 @@ impl VTable for Filter { } } impl OperationsVTable for Filter { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Filter>, index: usize, diff --git a/vortex-array/src/arrays/fixed_size_list/tests/basic.rs b/vortex-array/src/arrays/fixed_size_list/tests/basic.rs index b471ebb07a0..4fbd5503503 100644 --- a/vortex-array/src/arrays/fixed_size_list/tests/basic.rs +++ b/vortex-array/src/arrays/fixed_size_list/tests/basic.rs @@ -18,6 +18,7 @@ use crate::scalar::Scalar; use crate::validity::Validity; #[test] +#[expect(deprecated)] fn test_basic_fixed_size_list() { let len = 4; let list_size = 3; @@ -120,6 +121,7 @@ fn test_basic_fixed_size_list() { } #[test] +#[expect(deprecated)] fn test_scalar_at() { let len = 2; let list_size = 3; @@ -197,6 +199,7 @@ fn test_scalar_at() { } #[test] +#[expect(deprecated)] fn test_fixed_size_list_at() { let len = 3; let list_size = 2; diff --git a/vortex-array/src/arrays/fixed_size_list/tests/degenerate.rs b/vortex-array/src/arrays/fixed_size_list/tests/degenerate.rs index 73085b8c8a8..14486157514 100644 --- a/vortex-array/src/arrays/fixed_size_list/tests/degenerate.rs +++ b/vortex-array/src/arrays/fixed_size_list/tests/degenerate.rs @@ -44,6 +44,7 @@ fn test_fsl_size_0_length_0_non_nullable() { } #[test] +#[expect(deprecated)] fn test_fsl_size_0_length_1_non_nullable() { let len = 1; let list_size = 0; @@ -72,6 +73,7 @@ fn test_fsl_size_0_length_1_non_nullable() { } #[test] +#[expect(deprecated)] fn test_fsl_size_0_huge_length_non_nullable() { let len = 1_000_000_000_000; let list_size = 0; @@ -149,6 +151,7 @@ fn test_fsl_size_0_length_0_nullable() { } #[test] +#[expect(deprecated)] fn test_fsl_size_0_length_1_nullable_valid() { let len = 1; let list_size = 0; @@ -174,6 +177,7 @@ fn test_fsl_size_0_length_1_nullable_valid() { } #[test] +#[expect(deprecated)] fn test_fsl_size_0_length_1_nullable_null() { let len = 1; let list_size = 0; @@ -195,6 +199,7 @@ fn test_fsl_size_0_length_1_nullable_null() { } #[test] +#[expect(deprecated)] fn test_fsl_size_0_length_10_nullable_mixed() { let len = 10; let list_size = 0; @@ -235,6 +240,7 @@ fn test_fsl_size_0_length_10_nullable_mixed() { //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_fsl_size_0_nullable_elements() { let len = 5; let list_size = 0; diff --git a/vortex-array/src/arrays/fixed_size_list/tests/nested.rs b/vortex-array/src/arrays/fixed_size_list/tests/nested.rs index b754229ff90..747def8614f 100644 --- a/vortex-array/src/arrays/fixed_size_list/tests/nested.rs +++ b/vortex-array/src/arrays/fixed_size_list/tests/nested.rs @@ -27,6 +27,7 @@ use crate::validity::Validity; //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_fsl_of_fsl_basic() { let outer_len = 2; let outer_list_size = 3; @@ -205,6 +206,7 @@ fn test_fsl_of_fsl_basic() { } #[test] +#[expect(deprecated)] fn test_fsl_of_fsl_with_nulls() { let outer_len = 3; let outer_list_size = 2; @@ -271,6 +273,7 @@ fn test_fsl_of_fsl_with_nulls() { } #[test] +#[expect(deprecated)] fn test_deeply_nested_fsl() { let list_size = 2; diff --git a/vortex-array/src/arrays/fixed_size_list/tests/nullability.rs b/vortex-array/src/arrays/fixed_size_list/tests/nullability.rs index f5e5339e756..2c9964e810c 100644 --- a/vortex-array/src/arrays/fixed_size_list/tests/nullability.rs +++ b/vortex-array/src/arrays/fixed_size_list/tests/nullability.rs @@ -19,6 +19,7 @@ use crate::scalar::Scalar; use crate::validity::Validity; #[test] +#[expect(deprecated)] fn test_nullable_fsl_with_nulls() { let len = 4; let list_size = 2; @@ -103,6 +104,7 @@ fn test_nullable_fsl_with_nulls() { } #[test] +#[expect(deprecated)] fn test_nullable_elements_non_nullable_lists() { let len = 2; let list_size = 3; @@ -151,6 +153,7 @@ fn test_nullable_elements_non_nullable_lists() { } #[test] +#[expect(deprecated)] fn test_nullable_elements_and_nullable_lists() { let len = 3; let list_size = 2; @@ -229,6 +232,7 @@ fn test_nullable_elements_and_nullable_lists() { } #[test] +#[expect(deprecated)] fn test_alternating_nulls() { let len = 6; let list_size = 1; @@ -263,6 +267,7 @@ fn test_alternating_nulls() { } #[test] +#[expect(deprecated)] fn test_validity_types() { let len = 4; let list_size = 2; @@ -316,6 +321,7 @@ fn test_validity_types() { } #[test] +#[expect(deprecated)] fn test_mixed_nullability_patterns() { let len = 5; let list_size = 2; diff --git a/vortex-array/src/arrays/fixed_size_list/tests/take.rs b/vortex-array/src/arrays/fixed_size_list/tests/take.rs index 3904527abfd..c5e600c0773 100644 --- a/vortex-array/src/arrays/fixed_size_list/tests/take.rs +++ b/vortex-array/src/arrays/fixed_size_list/tests/take.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors +#![expect(deprecated)] + use rstest::rstest; use vortex_buffer::Buffer; use vortex_buffer::buffer; diff --git a/vortex-array/src/arrays/fixed_size_list/vtable/operations.rs b/vortex-array/src/arrays/fixed_size_list/vtable/operations.rs index 9f4cf02fbf8..39c049fea4a 100644 --- a/vortex-array/src/arrays/fixed_size_list/vtable/operations.rs +++ b/vortex-array/src/arrays/fixed_size_list/vtable/operations.rs @@ -11,6 +11,9 @@ use crate::arrays::fixed_size_list::FixedSizeListArrayExt; use crate::scalar::Scalar; impl OperationsVTable for FixedSizeList { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, FixedSizeList>, index: usize, diff --git a/vortex-array/src/arrays/interleave/mod.rs b/vortex-array/src/arrays/interleave/mod.rs index d29981249d4..e8bf09e293d 100644 --- a/vortex-array/src/arrays/interleave/mod.rs +++ b/vortex-array/src/arrays/interleave/mod.rs @@ -389,6 +389,9 @@ impl VTable for Interleave { } impl OperationsVTable for Interleave { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Interleave>, index: usize, @@ -471,6 +474,7 @@ mod tests { /// /// This is deliberately *not* wired into the array execution path — it exists purely as a /// trustworthy comparison point in tests. + #[expect(deprecated)] fn interleave_reference( values: &[ArrayRef], array_indices: &ArrayRef, diff --git a/vortex-array/src/arrays/list/array.rs b/vortex-array/src/arrays/list/array.rs index 419617c073c..4465b4d0622 100644 --- a/vortex-array/src/arrays/list/array.rs +++ b/vortex-array/src/arrays/list/array.rs @@ -292,6 +292,7 @@ pub trait ListArrayExt: ListArraySlotsExt { } #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn offset_at(&self, index: usize) -> VortexResult { vortex_ensure!( index <= self.as_ref().len(), @@ -328,6 +329,7 @@ pub trait ListArrayExt: ListArraySlotsExt { self.elements().dtype() } + #[expect(deprecated)] fn reset_offsets(&self, recurse: bool, ctx: &mut ExecutionCtx) -> VortexResult> { let mut elements = self.sliced_elements()?; if recurse && elements.is_canonical() { diff --git a/vortex-array/src/arrays/list/compute/take.rs b/vortex-array/src/arrays/list/compute/take.rs index c010b0d2732..48a6630e17b 100644 --- a/vortex-array/src/arrays/list/compute/take.rs +++ b/vortex-array/src/arrays/list/compute/take.rs @@ -869,6 +869,7 @@ mod test { use crate::validity::Validity; #[test] + #[expect(deprecated)] fn nullable_take() { let mut ctx = array_session().create_execution_ctx(); let list = ListArray::try_new( @@ -1020,6 +1021,7 @@ mod test { } #[test] + #[expect(deprecated)] fn non_nullable_take() { let mut ctx = array_session().create_execution_ctx(); let list = ListArray::try_new( @@ -1094,6 +1096,7 @@ mod test { } #[test] + #[expect(deprecated)] fn piecewise_sequence_take() { let mut ctx = array_session().create_execution_ctx(); let list = ListArray::try_new( @@ -1142,6 +1145,7 @@ mod test { } #[test] + #[expect(deprecated)] fn piecewise_sequence_take_nullable_list_constant_lengths() -> VortexResult<()> { let mut ctx = array_session().create_execution_ctx(); let list = ListArray::try_new( @@ -1194,6 +1198,7 @@ mod test { } #[test] + #[expect(deprecated)] fn piecewise_sequence_take_nullable_list_array_lengths() -> VortexResult<()> { let mut ctx = array_session().create_execution_ctx(); let list = ListArray::try_new( @@ -1308,6 +1313,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_u64_offset_accumulation_non_nullable() { let mut ctx = array_session().create_execution_ctx(); let elements = buffer![0i32; 200].into_array(); @@ -1337,6 +1343,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_u64_offset_accumulation_nullable() { let mut ctx = array_session().create_execution_ctx(); let elements = buffer![0i32; 150].into_array(); diff --git a/vortex-array/src/arrays/list/tests.rs b/vortex-array/src/arrays/list/tests.rs index 93daf3dc4a4..ad2e2365c58 100644 --- a/vortex-array/src/arrays/list/tests.rs +++ b/vortex-array/src/arrays/list/tests.rs @@ -43,6 +43,7 @@ fn test_empty_list_array() { } #[test] +#[expect(deprecated)] fn test_simple_list_array() { let mut ctx = SESSION.create_execution_ctx(); let elements = buffer![1i32, 2, 3, 4, 5].into_array(); @@ -74,6 +75,7 @@ fn test_simple_list_array() { } #[test] +#[expect(deprecated)] fn test_simple_list_array_from_iter() { let mut ctx = SESSION.create_execution_ctx(); let elements = buffer![1i32, 2, 3].into_array(); @@ -208,6 +210,7 @@ fn test_list_filter_empty_lists() { } #[test] +#[expect(deprecated)] fn test_list_filter_with_nulls() { let mut ctx = SESSION.create_execution_ctx(); // Test filtering lists with null validity. @@ -586,6 +589,7 @@ fn create_list_of_lists_nullable(data: OptVec>>) -> ListArray #[test] #[expect(clippy::cognitive_complexity)] +#[expect(deprecated)] fn test_list_of_lists() { let mut ctx = SESSION.create_execution_ctx(); let data = vec![ @@ -670,6 +674,7 @@ fn test_list_of_lists() { } #[test] +#[expect(deprecated)] fn test_list_of_lists_nullable_outer() { let mut ctx = SESSION.create_execution_ctx(); // Create list of lists with nullable outer, non-nullable inner. @@ -715,6 +720,7 @@ fn test_list_of_lists_nullable_outer() { } #[test] +#[expect(deprecated)] fn test_list_of_lists_nullable_inner() { // Create list of lists with non-nullable outer, nullable inner. // Structure: [[[1, 2], null, [3]], [[4, 5, 6]], [], [[null, 7]]] @@ -759,6 +765,7 @@ fn test_list_of_lists_nullable_inner() { } #[test] +#[expect(deprecated)] fn test_list_of_lists_both_nullable() { let mut ctx = SESSION.create_execution_ctx(); // Create list of lists with both nullable. @@ -904,6 +911,7 @@ fn test_offsets_constant() { } #[test] +#[expect(deprecated)] fn test_recursive_compact_list_of_lists() { let mut ctx = SESSION.create_execution_ctx(); // Create a nested list structure: [[[1,2,3], [4,5]], [[6,7,8,9]], [[10], [11,12]]] diff --git a/vortex-array/src/arrays/list/vtable/operations.rs b/vortex-array/src/arrays/list/vtable/operations.rs index 02c686cd1f1..c8f7137304c 100644 --- a/vortex-array/src/arrays/list/vtable/operations.rs +++ b/vortex-array/src/arrays/list/vtable/operations.rs @@ -13,6 +13,9 @@ use crate::arrays::list::ListArrayExt; use crate::scalar::Scalar; impl OperationsVTable for List { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, List>, index: usize, diff --git a/vortex-array/src/arrays/listview/array.rs b/vortex-array/src/arrays/listview/array.rs index 43f51971b8f..dd68e11beca 100644 --- a/vortex-array/src/arrays/listview/array.rs +++ b/vortex-array/src/arrays/listview/array.rs @@ -369,6 +369,7 @@ pub trait ListViewArrayExt: ListViewArraySlotsExt { } #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn offset_at(&self, index: usize) -> usize { assert!( index < self.as_ref().len(), @@ -389,6 +390,7 @@ pub trait ListViewArrayExt: ListViewArraySlotsExt { } #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn size_at(&self, index: usize) -> usize { assert!( index < self.as_ref().len(), diff --git a/vortex-array/src/arrays/listview/rebuild.rs b/vortex-array/src/arrays/listview/rebuild.rs index dfcfc4283c7..fbaf7014630 100644 --- a/vortex-array/src/arrays/listview/rebuild.rs +++ b/vortex-array/src/arrays/listview/rebuild.rs @@ -505,6 +505,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_rebuild_flatten_with_nullable() -> VortexResult<()> { use crate::arrays::BoolArray; @@ -547,6 +548,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_rebuild_flatten_null_row_uses_valid_empty_range() -> VortexResult<()> { let elements = PrimitiveArray::from_iter(vec![1i32, 2, 3, 4]).into_array(); let offsets = PrimitiveArray::from_iter(vec![0u32, 1, 2]).into_array(); @@ -583,6 +585,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_rebuild_trim_elements_basic() -> VortexResult<()> { // Test trimming both leading and trailing unused elements while preserving gaps in the // middle. @@ -662,6 +665,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_rebuild_with_trailing_nulls_regression() -> VortexResult<()> { // Regression test for issue #5412 // Tests that zero-copy-to-list arrays with trailing NULLs correctly calculate diff --git a/vortex-array/src/arrays/listview/tests/basic.rs b/vortex-array/src/arrays/listview/tests/basic.rs index f3082757ca0..429c1df2414 100644 --- a/vortex-array/src/arrays/listview/tests/basic.rs +++ b/vortex-array/src/arrays/listview/tests/basic.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors +#![expect(deprecated)] + use std::sync::Arc; use rstest::rstest; diff --git a/vortex-array/src/arrays/listview/tests/filter.rs b/vortex-array/src/arrays/listview/tests/filter.rs index d8a6cb4f4db..2e91f857b16 100644 --- a/vortex-array/src/arrays/listview/tests/filter.rs +++ b/vortex-array/src/arrays/listview/tests/filter.rs @@ -170,6 +170,7 @@ fn test_filter_constant_arrays() { } #[test] +#[expect(deprecated)] fn test_filter_extreme_offsets() { // ListView-specific: Test with very large offsets. let elements = PrimitiveArray::from_iter(0i32..10000).into_array(); diff --git a/vortex-array/src/arrays/listview/tests/nested.rs b/vortex-array/src/arrays/listview/tests/nested.rs index 4b2676f4491..814a78a8def 100644 --- a/vortex-array/src/arrays/listview/tests/nested.rs +++ b/vortex-array/src/arrays/listview/tests/nested.rs @@ -23,6 +23,7 @@ use crate::validity::Validity; //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_listview_of_listview_with_overlapping() { // Create elements that will be shared between inner lists. // Elements: [1, 2, 3, 4, 5, 6, 7, 8] @@ -239,6 +240,7 @@ fn test_mixed_offset_size_types() { //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_listview_zero_and_overlapping() { // Mix of empty lists, overlapping lists, and normal lists. let elements = buffer![1i32, 2, 3, 4, 5].into_array(); @@ -324,6 +326,7 @@ fn test_listview_zero_and_overlapping() { //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_listview_of_struct_with_nulls() { // Create structs with fields that could be null. let struct_fields = StructFields::new( diff --git a/vortex-array/src/arrays/listview/tests/nullability.rs b/vortex-array/src/arrays/listview/tests/nullability.rs index b32e2052435..af42edb576a 100644 --- a/vortex-array/src/arrays/listview/tests/nullability.rs +++ b/vortex-array/src/arrays/listview/tests/nullability.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors +#![expect(deprecated)] + use std::sync::Arc; use rstest::rstest; diff --git a/vortex-array/src/arrays/listview/tests/operations.rs b/vortex-array/src/arrays/listview/tests/operations.rs index 38ac286b2d1..e3e375442dd 100644 --- a/vortex-array/src/arrays/listview/tests/operations.rs +++ b/vortex-array/src/arrays/listview/tests/operations.rs @@ -36,6 +36,7 @@ use crate::validity::Validity; //////////////////////////////////////////////////////////////////////////////////////////////////// #[test] +#[expect(deprecated)] fn test_slice_comprehensive() { // Comprehensive test for basic slicing, full array, and single element cases. // Logical lists: [[1,2,3], [4,5], [6,7,8], [9,10]] @@ -139,6 +140,7 @@ fn test_slice_out_of_order() { } #[test] +#[expect(deprecated)] fn test_slice_with_nulls() { // Test slicing with nullable ListView. // Logical lists: [[1,2], null, [5,6], null] @@ -274,6 +276,7 @@ fn test_cast_numeric_types(#[case] from_ptype: PType, #[case] to_ptype: PType) { } #[test] +#[expect(deprecated)] fn test_cast_with_nulls() { // Logical lists: [[10,20], null] let elements = buffer![10i32, 20, 30, 40].into_array(); @@ -632,6 +635,7 @@ fn test_mask_listview_conformance(#[case] listview: ListViewArray) { } #[test] +#[expect(deprecated)] fn test_mask_preserves_structure() { // ListView-specific: Verify mask preserves offsets and sizes. // Logical lists: [[1,2], [3,4], [5,6], [7,8]] @@ -688,6 +692,7 @@ fn test_mask_preserves_structure() { } #[test] +#[expect(deprecated)] fn test_mask_with_existing_nulls() { // ListView-specific: Test interaction between existing nulls and mask. // Logical lists: [[10,20], null, [50,60]] @@ -728,6 +733,7 @@ fn test_mask_with_existing_nulls() { } #[test] +#[expect(deprecated)] fn test_mask_with_gaps() { // ListView-specific: Mask with gaps in elements. // Logical lists: [[1,2], [5,6], [9,10]] (999 values are gaps) @@ -766,6 +772,7 @@ fn test_mask_with_gaps() { } #[test] +#[expect(deprecated)] fn test_mask_constant_arrays() { // ListView-specific: Test mask with ConstantArray offsets/sizes. // Logical lists: [[200,300], [200,300], [200,300]] diff --git a/vortex-array/src/arrays/listview/tests/take.rs b/vortex-array/src/arrays/listview/tests/take.rs index 6f74081a8c5..51227cf4ad3 100644 --- a/vortex-array/src/arrays/listview/tests/take.rs +++ b/vortex-array/src/arrays/listview/tests/take.rs @@ -159,6 +159,7 @@ fn test_take_constant_arrays() { } #[test] +#[expect(deprecated)] fn test_take_extreme_offsets() { // ListView-specific: Test with very large offsets to demonstrate // that we keep unreferenced elements. diff --git a/vortex-array/src/arrays/listview/vtable/operations.rs b/vortex-array/src/arrays/listview/vtable/operations.rs index f0cb9539cc3..c2eefc3e32a 100644 --- a/vortex-array/src/arrays/listview/vtable/operations.rs +++ b/vortex-array/src/arrays/listview/vtable/operations.rs @@ -13,6 +13,9 @@ use crate::arrays::listview::ListViewArrayExt; use crate::scalar::Scalar; impl OperationsVTable for ListView { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ListView>, index: usize, diff --git a/vortex-array/src/arrays/map/tests.rs b/vortex-array/src/arrays/map/tests.rs index e1df51ce6d3..43f7d407d82 100644 --- a/vortex-array/src/arrays/map/tests.rs +++ b/vortex-array/src/arrays/map/tests.rs @@ -142,6 +142,7 @@ fn constructs_map_with_listview_entries() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn accepts_duplicate_and_unsorted_keys() -> VortexResult<()> { let array = sample_array()?; let mut ctx = array_session().create_execution_ctx(); @@ -205,6 +206,7 @@ fn rejects_malformed_entry_storage() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn scalar_access_preserves_null_and_empty_maps() -> VortexResult<()> { let array = sample_array()?; let mut ctx = array_session().create_execution_ctx(); @@ -220,6 +222,7 @@ fn scalar_access_preserves_null_and_empty_maps() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn scalar_access_preserves_variable_entry_counts_and_utf8_pairs() -> VortexResult<()> { let map_dtype = MapDType::try_new( DType::Utf8(Nullability::NonNullable), @@ -652,6 +655,7 @@ fn filter_preserves_duplicate_map_keys() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn builder_appends_existing_map_arrays() -> VortexResult<()> { let source = sample_array()?; let mut builder = MapBuilder::::with_capacity_in( @@ -702,6 +706,7 @@ fn canonicalizes_empty_constant_and_chunked_maps() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn serde_roundtrip_uses_registered_map_vtable() -> VortexResult<()> { let session = array_session(); assert!(session.arrays().registry().contains_key(&Map.id())); diff --git a/vortex-array/src/arrays/map/vtable/operations.rs b/vortex-array/src/arrays/map/vtable/operations.rs index d6e8fe87f12..c58d1de0ab9 100644 --- a/vortex-array/src/arrays/map/vtable/operations.rs +++ b/vortex-array/src/arrays/map/vtable/operations.rs @@ -13,6 +13,9 @@ use crate::arrays::struct_::StructArrayExt; use crate::scalar::Scalar; impl OperationsVTable for Map { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Map>, index: usize, diff --git a/vortex-array/src/arrays/masked/tests.rs b/vortex-array/src/arrays/masked/tests.rs index b326380bbf4..b380b5af362 100644 --- a/vortex-array/src/arrays/masked/tests.rs +++ b/vortex-array/src/arrays/masked/tests.rs @@ -77,6 +77,7 @@ fn test_canonical_dtype_matches_array_dtype() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn test_masked_child_with_validity() { // When validity has nulls, masked_child should apply inverted mask. let child = PrimitiveArray::from_iter([1i32, 2, 3, 4, 5]).into_array(); diff --git a/vortex-array/src/arrays/masked/vtable/canonical.rs b/vortex-array/src/arrays/masked/vtable/canonical.rs index 32a5e334afa..00c6524cd5f 100644 --- a/vortex-array/src/arrays/masked/vtable/canonical.rs +++ b/vortex-array/src/arrays/masked/vtable/canonical.rs @@ -48,6 +48,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_canonical_with_nulls() -> VortexResult<()> { let array = MaskedArray::try_new( PrimitiveArray::from_iter([1i32, 2, 3, 4, 5]).into_array(), diff --git a/vortex-array/src/arrays/masked/vtable/operations.rs b/vortex-array/src/arrays/masked/vtable/operations.rs index c82d0bf03ed..44537d272d3 100644 --- a/vortex-array/src/arrays/masked/vtable/operations.rs +++ b/vortex-array/src/arrays/masked/vtable/operations.rs @@ -11,6 +11,9 @@ use crate::arrays::masked::MaskedArraySlotsExt; use crate::scalar::Scalar; impl OperationsVTable for Masked { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Masked>, index: usize, diff --git a/vortex-array/src/arrays/null/compute/cast.rs b/vortex-array/src/arrays/null/compute/cast.rs index c1058156127..da0c7c714d3 100644 --- a/vortex-array/src/arrays/null/compute/cast.rs +++ b/vortex-array/src/arrays/null/compute/cast.rs @@ -50,6 +50,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_cast_null_to_nullable_succeeds() { let null_array = NullArray::new(5); let result = null_array diff --git a/vortex-array/src/arrays/null/compute/mod.rs b/vortex-array/src/arrays/null/compute/mod.rs index 73a23fe7a8d..cd88d074cc8 100644 --- a/vortex-array/src/arrays/null/compute/mod.rs +++ b/vortex-array/src/arrays/null/compute/mod.rs @@ -70,6 +70,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_scalar_at_nulls() { let nulls = NullArray::new(10); diff --git a/vortex-array/src/arrays/null/mod.rs b/vortex-array/src/arrays/null/mod.rs index 8479b7137cc..b4d4536c9cf 100644 --- a/vortex-array/src/arrays/null/mod.rs +++ b/vortex-array/src/arrays/null/mod.rs @@ -175,6 +175,8 @@ impl Array { } impl OperationsVTable for Null { + type ProbeState = (); + fn scalar_at( _array: ArrayView<'_, Null>, _index: usize, diff --git a/vortex-array/src/arrays/patched/array.rs b/vortex-array/src/arrays/patched/array.rs index 4522c8223b8..9f1ee91ed73 100644 --- a/vortex-array/src/arrays/patched/array.rs +++ b/vortex-array/src/arrays/patched/array.rs @@ -115,6 +115,7 @@ pub trait PatchedArrayExt: PatchedArraySlotsExt { #[inline] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn lane_range(&self, chunk: usize, lane: usize) -> VortexResult> { assert!(chunk * 1024 <= self.as_ref().len() + self.offset()); assert!(lane < self.n_lanes()); diff --git a/vortex-array/src/arrays/patched/vtable/operations.rs b/vortex-array/src/arrays/patched/vtable/operations.rs index 51dd1fc9e3c..9c72817c5ff 100644 --- a/vortex-array/src/arrays/patched/vtable/operations.rs +++ b/vortex-array/src/arrays/patched/vtable/operations.rs @@ -14,6 +14,9 @@ use crate::optimizer::ArrayOptimizer; use crate::scalar::Scalar; impl OperationsVTable for Patched { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Patched>, index: usize, @@ -70,6 +73,7 @@ mod tests { use crate::scalar::Scalar; #[test] + #[expect(deprecated)] fn test_simple() { let values = buffer![0u16; 1024].into_array(); let patches = Patches::new( @@ -115,6 +119,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_multi_chunk() { let values = buffer![0u16; 4096].into_array(); let patches = Patches::new( @@ -147,6 +152,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_multi_chunk_sliced() { let values = buffer![0u16; 4096].into_array(); let patches = Patches::new( diff --git a/vortex-array/src/arrays/piecewise_sequence/tests.rs b/vortex-array/src/arrays/piecewise_sequence/tests.rs index a087404fee2..d0999391a5b 100644 --- a/vortex-array/src/arrays/piecewise_sequence/tests.rs +++ b/vortex-array/src/arrays/piecewise_sequence/tests.rs @@ -103,6 +103,7 @@ fn supports_constant_lengths() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn scalar_at_maps_into_piece() -> VortexResult<()> { let starts = buffer![3u64, 15, 21].into_array(); let lengths = buffer![3u64, 3, 3].into_array(); diff --git a/vortex-array/src/arrays/piecewise_sequence/vtable.rs b/vortex-array/src/arrays/piecewise_sequence/vtable.rs index d68a00815f3..d39bd6eccac 100644 --- a/vortex-array/src/arrays/piecewise_sequence/vtable.rs +++ b/vortex-array/src/arrays/piecewise_sequence/vtable.rs @@ -145,6 +145,8 @@ impl VTable for PiecewiseSequence { } impl OperationsVTable for PiecewiseSequence { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, PiecewiseSequence>, index: usize, diff --git a/vortex-array/src/arrays/primitive/vtable/operations.rs b/vortex-array/src/arrays/primitive/vtable/operations.rs index ddeaa386485..9501513fb1c 100644 --- a/vortex-array/src/arrays/primitive/vtable/operations.rs +++ b/vortex-array/src/arrays/primitive/vtable/operations.rs @@ -11,6 +11,8 @@ use crate::match_each_native_ptype; use crate::scalar::Scalar; impl OperationsVTable for Primitive { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, Primitive>, index: usize, diff --git a/vortex-array/src/arrays/scalar_fn/vtable/operations.rs b/vortex-array/src/arrays/scalar_fn/vtable/operations.rs index 40d75906356..9f24d4ba153 100644 --- a/vortex-array/src/arrays/scalar_fn/vtable/operations.rs +++ b/vortex-array/src/arrays/scalar_fn/vtable/operations.rs @@ -15,6 +15,9 @@ use crate::scalar::Scalar; use crate::scalar_fn::VecExecutionArgs; impl OperationsVTable for ScalarFn { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, ScalarFn>, index: usize, diff --git a/vortex-array/src/arrays/shared/vtable.rs b/vortex-array/src/arrays/shared/vtable.rs index 758d091b557..ca4e3c62d65 100644 --- a/vortex-array/src/arrays/shared/vtable.rs +++ b/vortex-array/src/arrays/shared/vtable.rs @@ -125,6 +125,9 @@ impl VTable for Shared { } } impl OperationsVTable for Shared { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Shared>, index: usize, diff --git a/vortex-array/src/arrays/slice/vtable.rs b/vortex-array/src/arrays/slice/vtable.rs index c88c28a9a4d..fa9a889703f 100644 --- a/vortex-array/src/arrays/slice/vtable.rs +++ b/vortex-array/src/arrays/slice/vtable.rs @@ -169,6 +169,9 @@ impl VTable for Slice { } } impl OperationsVTable for Slice { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Slice>, index: usize, diff --git a/vortex-array/src/arrays/struct_/vtable/operations.rs b/vortex-array/src/arrays/struct_/vtable/operations.rs index b491e231520..860353d7670 100644 --- a/vortex-array/src/arrays/struct_/vtable/operations.rs +++ b/vortex-array/src/arrays/struct_/vtable/operations.rs @@ -12,6 +12,9 @@ use crate::scalar::Scalar; use crate::scalar::ScalarValue; impl OperationsVTable for Struct { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Struct>, index: usize, diff --git a/vortex-array/src/arrays/union/tests/mod.rs b/vortex-array/src/arrays/union/tests/mod.rs index fc0abec37b8..354c203d769 100644 --- a/vortex-array/src/arrays/union/tests/mod.rs +++ b/vortex-array/src/arrays/union/tests/mod.rs @@ -78,6 +78,7 @@ fn nullable_union_array() -> VortexResult { } #[test] +#[expect(deprecated)] fn scalar_at_uses_type_id_indirection() -> VortexResult<()> { let array = union_array()?; let mut ctx = array_session().create_execution_ctx(); @@ -140,6 +141,7 @@ fn validates_sparse_components() -> VortexResult<()> { #[test] #[should_panic(expected = "Unknown UnionArray type ID 7")] +#[expect(deprecated)] fn invalid_type_id_panics_when_accessed() { let array = UnionArray::try_new( PrimitiveArray::from_iter([5u8, 7, 5]).into_array(), @@ -158,6 +160,7 @@ fn invalid_type_id_panics_when_accessed() { } #[test] +#[expect(deprecated)] fn outer_nulls_are_independent_from_inner_nulls() -> VortexResult<()> { let variants = nullable_variants()?; let array = nullable_union_array()?; @@ -193,6 +196,7 @@ fn outer_nulls_are_independent_from_inner_nulls() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn masking_adds_outer_nulls_only() -> VortexResult<()> { let masked = union_array()? .into_array() @@ -221,6 +225,7 @@ fn masking_adds_outer_nulls_only() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn slice_and_filter_preserve_sparse_alignment() -> VortexResult<()> { let array = union_array()?.into_array(); let mut ctx = array_session().create_execution_ctx(); @@ -243,6 +248,7 @@ fn slice_and_filter_preserve_sparse_alignment() -> VortexResult<()> { /// A constant union canonicalizes into a sparse union whose selected child repeats the scalar's /// value and whose unselected children hold placeholders. #[test] +#[expect(deprecated)] fn constant_union_canonicalizes_to_sparse_union() -> VortexResult<()> { let mut ctx = array_session().create_execution_ctx(); let i32_variant = DType::Primitive(PType::I32, Nullability::NonNullable); @@ -303,6 +309,7 @@ fn constant_union_reports_uncompressed_size() -> VortexResult<()> { } #[test] +#[expect(deprecated)] fn serde_roundtrip() -> VortexResult<()> { let session = array_session(); let mut execution_ctx = session.create_execution_ctx(); diff --git a/vortex-array/src/arrays/union/tests/take.rs b/vortex-array/src/arrays/union/tests/take.rs index 0088ace43b2..25108cd76b5 100644 --- a/vortex-array/src/arrays/union/tests/take.rs +++ b/vortex-array/src/arrays/union/tests/take.rs @@ -38,6 +38,7 @@ fn take(array: &UnionArray, indices: ArrayRef) -> VortexResult { /// Assert that `array` holds exactly `expected`, row for row. #[track_caller] +#[expect(deprecated)] fn assert_rows(array: &UnionArray, expected: Vec) -> VortexResult<()> { let mut ctx = array_session().create_execution_ctx(); diff --git a/vortex-array/src/arrays/union/vtable/operations.rs b/vortex-array/src/arrays/union/vtable/operations.rs index 39ba95ed4ee..8325402d63a 100644 --- a/vortex-array/src/arrays/union/vtable/operations.rs +++ b/vortex-array/src/arrays/union/vtable/operations.rs @@ -14,6 +14,9 @@ use crate::arrays::union::UnionArraySlotsExt; use crate::scalar::Scalar; impl OperationsVTable for Union { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Union>, index: usize, diff --git a/vortex-array/src/arrays/varbin/array.rs b/vortex-array/src/arrays/varbin/array.rs index a763fb4f1de..228af74f7c4 100644 --- a/vortex-array/src/arrays/varbin/array.rs +++ b/vortex-array/src/arrays/varbin/array.rs @@ -335,6 +335,7 @@ pub trait VarBinArrayExt: VarBinArraySlotsExt { } #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn offset_at(&self, index: usize) -> usize { assert!( index <= self.as_ref().len(), diff --git a/vortex-array/src/arrays/varbin/builder.rs b/vortex-array/src/arrays/varbin/builder.rs index d915efdf2fd..110c402b00c 100644 --- a/vortex-array/src/arrays/varbin/builder.rs +++ b/vortex-array/src/arrays/varbin/builder.rs @@ -753,6 +753,7 @@ mod tests { use crate::scalar::Scalar; #[test] + #[expect(deprecated)] fn test_builder() { let mut builder = VarBinBuilder::::with_capacity_in( DType::Utf8(Nullable), diff --git a/vortex-array/src/arrays/varbin/vtable/canonical.rs b/vortex-array/src/arrays/varbin/vtable/canonical.rs index 825d920f1c7..9480c403aa0 100644 --- a/vortex-array/src/arrays/varbin/vtable/canonical.rs +++ b/vortex-array/src/arrays/varbin/vtable/canonical.rs @@ -43,6 +43,7 @@ pub(crate) fn varbin_to_canonical( #[cfg(test)] mod tests { + #![expect(deprecated)] use rstest::rstest; use vortex_error::VortexResult; diff --git a/vortex-array/src/arrays/varbin/vtable/operations.rs b/vortex-array/src/arrays/varbin/vtable/operations.rs index e11043e605a..cc5090d8912 100644 --- a/vortex-array/src/arrays/varbin/vtable/operations.rs +++ b/vortex-array/src/arrays/varbin/vtable/operations.rs @@ -12,6 +12,8 @@ use crate::arrays::varbin::varbin_scalar; use crate::scalar::Scalar; impl OperationsVTable for VarBin { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, VarBin>, index: usize, diff --git a/vortex-array/src/arrays/varbinview/vtable/operations.rs b/vortex-array/src/arrays/varbinview/vtable/operations.rs index 1a1f20a0dbe..53866d29fb5 100644 --- a/vortex-array/src/arrays/varbinview/vtable/operations.rs +++ b/vortex-array/src/arrays/varbinview/vtable/operations.rs @@ -11,6 +11,8 @@ use crate::arrays::varbin::varbin_scalar; use crate::scalar::Scalar; impl OperationsVTable for VarBinView { + type ProbeState = (); + fn scalar_at( array: ArrayView<'_, VarBinView>, index: usize, diff --git a/vortex-array/src/arrays/variant/mod.rs b/vortex-array/src/arrays/variant/mod.rs index b5610320719..15dd9fec072 100644 --- a/vortex-array/src/arrays/variant/mod.rs +++ b/vortex-array/src/arrays/variant/mod.rs @@ -168,6 +168,7 @@ mod tests { Ok(()) } + #[expect(deprecated)] fn assert_variant_core_rows( array: &VariantArray, expected_core: &[Option], @@ -247,6 +248,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn scalar_at_merges_shredded_with_core_storage() -> VortexResult<()> { let dtype = DType::Variant(Nullability::Nullable); let core_chunks = [Some(1i32), None, Some(3)] diff --git a/vortex-array/src/arrays/variant/vtable/kernel.rs b/vortex-array/src/arrays/variant/vtable/kernel.rs index 22d52ecd6a7..a1cd61f51aa 100644 --- a/vortex-array/src/arrays/variant/vtable/kernel.rs +++ b/vortex-array/src/arrays/variant/vtable/kernel.rs @@ -169,6 +169,7 @@ fn typed_shredded_path( Ok(Some(current)) } +#[expect(deprecated)] fn merge_typed_as_variant( typed: ArrayRef, fallback: Option, diff --git a/vortex-array/src/arrays/variant/vtable/operations.rs b/vortex-array/src/arrays/variant/vtable/operations.rs index c7f7d36fd97..d22f8acaf8d 100644 --- a/vortex-array/src/arrays/variant/vtable/operations.rs +++ b/vortex-array/src/arrays/variant/vtable/operations.rs @@ -12,6 +12,9 @@ use crate::arrays::variant::VariantArraySlotsExt; use crate::scalar::Scalar; impl OperationsVTable for Variant { + type ProbeState = (); + + #[expect(deprecated)] fn scalar_at( array: ArrayView<'_, Variant>, index: usize, diff --git a/vortex-array/src/builders/decimal.rs b/vortex-array/src/builders/decimal.rs index d65dc41ad4a..e3990dc3613 100644 --- a/vortex-array/src/builders/decimal.rs +++ b/vortex-array/src/builders/decimal.rs @@ -341,6 +341,7 @@ mod tests { use crate::dtype::DecimalDType; #[test] + #[expect(deprecated)] fn test_mixed_extend() { let values = 42i8; @@ -375,6 +376,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_scalar() { let mut ctx = array_session().create_execution_ctx(); use crate::scalar::Scalar; diff --git a/vortex-array/src/builders/fixed_size_list.rs b/vortex-array/src/builders/fixed_size_list.rs index e9a66b62d83..471f42fb886 100644 --- a/vortex-array/src/builders/fixed_size_list.rs +++ b/vortex-array/src/builders/fixed_size_list.rs @@ -553,6 +553,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_nullable_lists_non_nullable_elements() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(DType::Primitive(I32, NonNullable)); @@ -691,6 +692,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_nulls() { let mut ctx = array_session().create_execution_ctx(); // Elements must be nullable if we're going to append null lists @@ -726,6 +728,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_scalar_nulls() { let mut ctx = array_session().create_execution_ctx(); // Elements must be nullable if we're going to append null lists @@ -815,6 +818,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_extend_from_array() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); @@ -895,6 +899,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_extend_degenerate_arrays() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); @@ -1020,6 +1025,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_mixed_operations() { let mut ctx = array_session().create_execution_ctx(); // Use nullable elements since we'll be appending nulls @@ -1114,6 +1120,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_scalar() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); diff --git a/vortex-array/src/builders/list.rs b/vortex-array/src/builders/list.rs index 5e97f122cba..6ee6c638d1d 100644 --- a/vortex-array/src/builders/list.rs +++ b/vortex-array/src/builders/list.rs @@ -842,6 +842,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_array_with_gap() { let one_trailing_unused_element = ListArray::try_new( buffer![1, 2, 3, 4].into_array(), @@ -892,6 +893,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_scalar() { let dtype: Arc = Arc::new(I32.into()); let mut builder = ListBuilder::::with_capacity_in( diff --git a/vortex-array/src/builders/listview.rs b/vortex-array/src/builders/listview.rs index a0c326b7f37..b03d41beece 100644 --- a/vortex-array/src/builders/listview.rs +++ b/vortex-array/src/builders/listview.rs @@ -709,6 +709,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_basic_append_and_nulls() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); @@ -861,6 +862,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_builder_trait_methods() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); @@ -919,6 +921,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_extend_from_array() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); @@ -1120,6 +1123,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_extend_from_array_overlapping_listview() { let mut ctx = array_session().create_execution_ctx(); let dtype: Arc = Arc::new(I32.into()); diff --git a/vortex-array/src/builders/primitive.rs b/vortex-array/src/builders/primitive.rs index 647854176c5..c24d7d64bde 100644 --- a/vortex-array/src/builders/primitive.rs +++ b/vortex-array/src/builders/primitive.rs @@ -437,6 +437,7 @@ mod tests { /// The old API had `append_mask` on the builder, which was confusing when used with ranges. /// This test ensures the new API works correctly. #[test] + #[expect(deprecated)] fn test_append_mask_on_uninit_range() { let mut builder = PrimitiveBuilder::::with_capacity_in( Nullability::Nullable, @@ -545,6 +546,7 @@ mod tests { /// use `append_mask` to set up the buffer, then demonstrate that `set_bit` can /// modify individual bits with relative indexing. #[test] + #[expect(deprecated)] fn test_set_bit_relative_indexing() { let mut builder = PrimitiveBuilder::::with_capacity_in( Nullability::Nullable, @@ -694,6 +696,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_append_scalar() { use crate::dtype::DType; use crate::scalar::Scalar; diff --git a/vortex-array/src/builders/tests.rs b/vortex-array/src/builders/tests.rs index 5b7977a0ef0..fcfc7f594ba 100644 --- a/vortex-array/src/builders/tests.rs +++ b/vortex-array/src/builders/tests.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors +#![expect(deprecated)] + use std::alloc::Layout; use std::ptr::NonNull; use std::sync::Arc; diff --git a/vortex-array/src/builders/varbinview.rs b/vortex-array/src/builders/varbinview.rs index e27336fe998..b561e1bf264 100644 --- a/vortex-array/src/builders/varbinview.rs +++ b/vortex-array/src/builders/varbinview.rs @@ -2044,6 +2044,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_large_value_allocation() { use super::BufferGrowthStrategy; use super::VarBinViewBuilder; diff --git a/vortex-array/src/compute/conformance/binary_numeric.rs b/vortex-array/src/compute/conformance/binary_numeric.rs index 1750ffc8e5d..41ef01de6cf 100644 --- a/vortex-array/src/compute/conformance/binary_numeric.rs +++ b/vortex-array/src/compute/conformance/binary_numeric.rs @@ -55,6 +55,7 @@ use crate::scalar::PrimitiveScalar; use crate::scalar::Scalar; use crate::scalar_fn::fns::binary::numeric_op_result_decimal_dtype; +#[expect(deprecated)] fn to_vec_of_scalar(array: &ArrayRef, ctx: &mut ExecutionCtx) -> Vec { // Not fast, but obviously correct (0..array.len()) diff --git a/vortex-array/src/compute/conformance/cast.rs b/vortex-array/src/compute/conformance/cast.rs index 6f9bd4aefd0..0c7dfa2746a 100644 --- a/vortex-array/src/compute/conformance/cast.rs +++ b/vortex-array/src/compute/conformance/cast.rs @@ -67,6 +67,7 @@ pub fn test_cast_conformance(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_cast_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { // Casting to the same type should be a no-op let result = cast_and_execute(&array.clone(), array.dtype().clone(), ctx) @@ -87,6 +88,7 @@ fn test_cast_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_cast_from_null(array: &ArrayRef, ctx: &mut ExecutionCtx) { // Null can be cast to itself let result = cast_and_execute(&array.clone(), DType::Null, ctx) @@ -131,6 +133,7 @@ fn test_cast_from_null(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_cast_to_non_nullable(array: &ArrayRef, ctx: &mut ExecutionCtx) { // DType::Null has no non-nullable form if &DType::Null == array.dtype() { @@ -190,6 +193,7 @@ fn test_cast_to_non_nullable(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_cast_to_nullable(array: &ArrayRef, ctx: &mut ExecutionCtx) { let nullable = cast_and_execute(&array.clone(), array.dtype().as_nullable(), ctx) .vortex_expect("arrays without nulls can cast to nullable"); @@ -260,6 +264,7 @@ fn fits(value: &Scalar, ptype: PType) -> bool { value.cast(&dtype).is_ok() } +#[expect(deprecated)] fn test_cast_to_primitive( array: &ArrayRef, target_ptype: PType, diff --git a/vortex-array/src/compute/conformance/consistency.rs b/vortex-array/src/compute/conformance/consistency.rs index cc1d826bdcf..7f02fb6765f 100644 --- a/vortex-array/src/compute/conformance/consistency.rs +++ b/vortex-array/src/compute/conformance/consistency.rs @@ -50,6 +50,7 @@ use crate::scalar_fn::fns::operators::Operator; /// - Creates indices array containing positions where mask is true /// - Applies take with these indices /// - Verifies both results are identical +#[expect(deprecated)] fn test_filter_take_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -118,6 +119,7 @@ fn test_filter_take_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// # Why This Matters /// This test ensures that mask operations compose correctly, which is critical for /// complex query operations that may apply multiple filters. +#[expect(deprecated)] fn test_double_mask_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -191,6 +193,7 @@ fn test_double_mask_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// # Why This Matters /// This is an identity operation that should be optimized in implementations /// to avoid unnecessary copying. +#[expect(deprecated)] fn test_filter_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -240,6 +243,7 @@ fn test_filter_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// # Why This Matters /// Masking always produces a nullable array, even when no values are actually masked. /// This test ensures the type system handles this correctly. +#[expect(deprecated)] fn test_mask_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -298,6 +302,7 @@ fn test_mask_identity(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// # Why This Matters /// When a filter mask represents a contiguous range, it should be equivalent to /// a slice operation. Some implementations may optimize this case. +#[expect(deprecated)] fn test_slice_filter_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 4 { @@ -355,6 +360,7 @@ fn test_slice_filter_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// /// # Why This Matters /// Sequential takes are a common pattern that can be optimized to slice operations. +#[expect(deprecated)] fn test_take_slice_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 3 { @@ -398,6 +404,7 @@ fn test_take_slice_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests that filter preserves relative ordering +#[expect(deprecated)] fn test_filter_preserves_order(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 4 { @@ -443,6 +450,7 @@ fn test_filter_preserves_order(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests that take with repeated indices works correctly +#[expect(deprecated)] fn test_take_repeated_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -469,6 +477,7 @@ fn test_take_repeated_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests mask and filter interaction with nulls +#[expect(deprecated)] fn test_mask_filter_null_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 3 { @@ -538,6 +547,7 @@ fn test_empty_operations_consistency(array: &ArrayRef) { } /// Tests that take preserves array properties +#[expect(deprecated)] fn test_take_preserves_properties(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -582,6 +592,7 @@ fn test_take_preserves_properties(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// # Why This Matters /// Nullable indices are a powerful feature that allows introducing nulls during /// a take operation, which is useful for outer joins and similar operations. +#[expect(deprecated)] fn test_nullable_indices_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 3 { @@ -648,6 +659,7 @@ fn test_nullable_indices_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests large array consistency +#[expect(deprecated)] fn test_large_array_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 1000 { @@ -698,6 +710,7 @@ fn test_large_array_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { /// Comparison operations must maintain logical consistency across encodings. /// This test catches bugs where an encoding might implement one comparison /// correctly but fail on its logical inverse. +#[expect(deprecated)] fn test_comparison_inverse_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -818,6 +831,7 @@ fn test_comparison_inverse_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) /// # Why This Matters /// Ensures that comparison operations maintain mathematical ordering properties /// regardless of operand order. +#[expect(deprecated)] fn test_comparison_symmetry_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -909,6 +923,7 @@ fn test_comparison_symmetry_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx /// Boolean operations must maintain logical consistency across encodings. /// This test catches bugs where encodings might optimize boolean operations /// incorrectly, breaking fundamental logical properties. +#[expect(deprecated)] fn test_boolean_demorgan_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { if !matches!(array.dtype(), DType::Bool(_)) { return; @@ -1127,6 +1142,7 @@ fn widened_primitive_dtype(dtype: &DType) -> Option { /// This test specifically catches bugs where encodings (like RunEndArray) fail to preserve /// offset information during cast operations. Such bugs can lead to incorrect data being /// returned after casting a sliced array. +#[expect(deprecated)] fn test_cast_slice_consistency(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 5 { diff --git a/vortex-array/src/compute/conformance/filter.rs b/vortex-array/src/compute/conformance/filter.rs index 5c78e0d70ad..f60ae1fe949 100644 --- a/vortex-array/src/compute/conformance/filter.rs +++ b/vortex-array/src/compute/conformance/filter.rs @@ -81,6 +81,7 @@ fn test_none_filter(array: &ArrayRef) { assert_eq!(filtered.dtype(), array.dtype()); } +#[expect(deprecated)] fn test_selective_filter(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 2 { @@ -137,6 +138,7 @@ fn test_selective_filter(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_single_element_filter(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len == 0 { @@ -218,6 +220,7 @@ fn test_mismatched_lengths(array: &ArrayRef) { } /// Tests filtering with alternating true/false pattern +#[expect(deprecated)] fn test_alternating_pattern_filter(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let pattern = create_alternating_pattern(len); diff --git a/vortex-array/src/compute/conformance/mask.rs b/vortex-array/src/compute/conformance/mask.rs index 50930ba2876..e9c70ff20cc 100644 --- a/vortex-array/src/compute/conformance/mask.rs +++ b/vortex-array/src/compute/conformance/mask.rs @@ -36,6 +36,7 @@ pub fn test_mask_conformance(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests masking with a heterogeneous pattern +#[expect(deprecated)] fn test_heterogenous_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -72,6 +73,7 @@ fn test_heterogenous_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests that an empty mask (all false) preserves all elements +#[expect(deprecated)] fn test_empty_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let all_unmasked = vec![false; len]; @@ -98,6 +100,7 @@ fn test_empty_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests that a full mask (all true) makes all elements null +#[expect(deprecated)] fn test_full_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let all_masked = vec![true; len]; @@ -120,6 +123,7 @@ fn test_full_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests alternating mask pattern +#[expect(deprecated)] fn test_alternating_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let pattern: Vec = (0..len).map(|i| i % 2 == 0).collect(); @@ -153,6 +157,7 @@ fn test_alternating_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests sparse mask (only a few elements masked) +#[expect(deprecated)] fn test_sparse_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 10 { @@ -194,6 +199,7 @@ fn test_sparse_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests masking a single element +#[expect(deprecated)] fn test_single_element_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -226,6 +232,7 @@ fn test_single_element_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests double masking operations +#[expect(deprecated)] fn test_double_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -267,6 +274,7 @@ fn test_double_mask(array: &ArrayRef, ctx: &mut ExecutionCtx) { } /// Tests masking with nullable mask (nulls treated as false) +#[expect(deprecated)] fn test_nullable_mask_input(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); if len < 3 { diff --git a/vortex-array/src/compute/conformance/take.rs b/vortex-array/src/compute/conformance/take.rs index 47bc8f1bd82..3c079db3704 100644 --- a/vortex-array/src/compute/conformance/take.rs +++ b/vortex-array/src/compute/conformance/take.rs @@ -52,6 +52,7 @@ pub fn test_take_conformance(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_take_all(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let indices = PrimitiveArray::from_iter(0..len as u64); @@ -105,6 +106,7 @@ fn test_take_none(array: &ArrayRef) { } #[expect(clippy::cast_possible_truncation)] +#[expect(deprecated)] fn test_take_selective(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -131,6 +133,7 @@ fn test_take_selective(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_take_first_and_last(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let indices = PrimitiveArray::from_iter([0u64, (len - 1) as u64]); @@ -158,6 +161,7 @@ fn test_take_first_and_last(array: &ArrayRef, ctx: &mut ExecutionCtx) { } #[expect(clippy::cast_possible_truncation)] +#[expect(deprecated)] fn test_take_with_nullable_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -205,6 +209,7 @@ fn test_take_with_nullable_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_take_repeated_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { if array.is_empty() { return; @@ -240,6 +245,7 @@ fn test_empty_indices(array: &ArrayRef) { assert_eq!(result.dtype(), array.dtype()); } +#[expect(deprecated)] fn test_take_reverse(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); // Take elements in reverse order @@ -263,6 +269,7 @@ fn test_take_reverse(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_take_single_middle(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let middle_idx = len / 2; @@ -284,6 +291,7 @@ fn test_take_single_middle(array: &ArrayRef, ctx: &mut ExecutionCtx) { } #[expect(clippy::cast_possible_truncation)] +#[expect(deprecated)] fn test_take_random_unsorted(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -315,6 +323,7 @@ fn test_take_random_unsorted(array: &ArrayRef, ctx: &mut ExecutionCtx) { } } +#[expect(deprecated)] fn test_take_contiguous_range(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); let start = len / 4; @@ -342,6 +351,7 @@ fn test_take_contiguous_range(array: &ArrayRef, ctx: &mut ExecutionCtx) { } #[expect(clippy::cast_possible_truncation)] +#[expect(deprecated)] fn test_take_mixed_repeated(array: &ArrayRef, ctx: &mut ExecutionCtx) { let len = array.len(); @@ -378,6 +388,7 @@ fn test_take_mixed_repeated(array: &ArrayRef, ctx: &mut ExecutionCtx) { } #[expect(clippy::cast_possible_truncation)] +#[expect(deprecated)] fn test_take_large_indices(array: &ArrayRef, ctx: &mut ExecutionCtx) { // Test with a large number of indices to stress test performance let len = array.len(); diff --git a/vortex-array/src/display/mod.rs b/vortex-array/src/display/mod.rs index 780140af2ac..06fd27049a8 100644 --- a/vortex-array/src/display/mod.rs +++ b/vortex-array/src/display/mod.rs @@ -523,6 +523,7 @@ impl ArrayRef { } #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn fmt_as(&self, f: &mut std::fmt::Formatter, options: &DisplayOptions) -> std::fmt::Result { match options { DisplayOptions::MetadataOnly => EncodingSummaryExtractor::write(self, f), diff --git a/vortex-array/src/patches.rs b/vortex-array/src/patches.rs index 641efd61404..d379e2cb1ca 100644 --- a/vortex-array/src/patches.rs +++ b/vortex-array/src/patches.rs @@ -238,6 +238,7 @@ pub struct Patches { impl Patches { #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn new( array_len: usize, offset: usize, @@ -381,6 +382,7 @@ impl Patches { #[inline] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn chunk_offset_at(&self, idx: usize) -> VortexResult { let Some(chunk_offsets) = &self.chunk_offsets else { vortex_bail!("chunk_offsets must be set to retrieve offset at index") @@ -442,6 +444,7 @@ impl Patches { /// Get the patched value at a given index if it exists. #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn get_patched(&self, index: usize) -> VortexResult> { self.search_index(index)? .to_found() @@ -602,6 +605,7 @@ impl Patches { /// Returns the minimum patch index #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn min_index(&self) -> VortexResult { let first = self .indices @@ -614,6 +618,7 @@ impl Patches { /// Returns the maximum patch index #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn max_index(&self) -> VortexResult { let last = self .indices @@ -722,6 +727,7 @@ impl Patches { /// Slice the patches by a range of the patched array. #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn slice(&self, range: Range) -> VortexResult> { let slice_start_idx = self.search_index(range.start)?.to_index(); let slice_end_idx = self.search_index(range.end)?.to_index(); @@ -1530,6 +1536,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_mask_all_false() { let mut ctx = array_session().create_execution_ctx(); let patches = Patches::new( @@ -1630,6 +1637,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_mask_nullable_values() { let mut ctx = array_session().create_execution_ctx(); let patches = Patches::new( @@ -1843,6 +1851,7 @@ mod test { } #[test] + #[expect(deprecated)] fn test_patch_values() { let mut ctx = array_session().create_execution_ctx(); let patches = Patches::new( diff --git a/vortex-array/src/scalar_fn/fns/binary/boolean.rs b/vortex-array/src/scalar_fn/fns/binary/boolean.rs index 78f683eddf2..9bc3e518037 100644 --- a/vortex-array/src/scalar_fn/fns/binary/boolean.rs +++ b/vortex-array/src/scalar_fn/fns/binary/boolean.rs @@ -715,6 +715,7 @@ fn is_boolean_operator(operator: Operator) -> bool { #[cfg(test)] mod tests { + #![expect(deprecated)] use rstest::rstest; use vortex_error::VortexResult; diff --git a/vortex-array/src/scalar_fn/fns/binary/compare/tests.rs b/vortex-array/src/scalar_fn/fns/binary/compare/tests.rs index 40c969bf809..5e98e5e36a4 100644 --- a/vortex-array/src/scalar_fn/fns/binary/compare/tests.rs +++ b/vortex-array/src/scalar_fn/fns/binary/compare/tests.rs @@ -114,6 +114,7 @@ fn test_bool_basic_comparisons() { } #[test] +#[expect(deprecated)] fn constant_compare() { let left = ConstantArray::new(Scalar::from(2u32), 10); let right = ConstantArray::new(Scalar::from(10u32), 10); @@ -336,6 +337,7 @@ fn scalar_cmp_incompatible_extension_types_errors() { } #[test] +#[expect(deprecated)] fn test_empty_list() { let ctx = &mut array_session().create_execution_ctx(); let list = ListViewArray::new( diff --git a/vortex-array/src/scalar_fn/fns/binary/mod.rs b/vortex-array/src/scalar_fn/fns/binary/mod.rs index ed31cdf8d46..ee4b4ba07ff 100644 --- a/vortex-array/src/scalar_fn/fns/binary/mod.rs +++ b/vortex-array/src/scalar_fn/fns/binary/mod.rs @@ -466,6 +466,7 @@ mod tests { /// Regression test for GitHub issue #5947: struct comparison in filter expressions should work /// using `make_comparator` instead of Arrow's `cmp` functions which don't support nested types. #[test] + #[expect(deprecated)] fn test_struct_comparison() { use crate::IntoArray; use crate::arrays::StructArray; diff --git a/vortex-array/src/scalar_fn/fns/byte_length.rs b/vortex-array/src/scalar_fn/fns/byte_length.rs index cc709628bad..67944956b4d 100644 --- a/vortex-array/src/scalar_fn/fns/byte_length.rs +++ b/vortex-array/src/scalar_fn/fns/byte_length.rs @@ -220,6 +220,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_nullable_string_byte_length() -> VortexResult<()> { let array = VarBinArray::from_nullable_strs(vec![Some("hello"), None, Some("Пуховички")]) .into_array(); @@ -241,6 +242,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_null_scalar_byte_length() -> VortexResult<()> { let null_scalar = Scalar::null(DType::Utf8(Nullability::Nullable)); let array = ConstantArray::new(null_scalar, 2).into_array(); diff --git a/vortex-array/src/scalar_fn/fns/case_when.rs b/vortex-array/src/scalar_fn/fns/case_when.rs index b9d3450562a..fbc1d3ca8ad 100644 --- a/vortex-array/src/scalar_fn/fns/case_when.rs +++ b/vortex-array/src/scalar_fn/fns/case_when.rs @@ -380,6 +380,7 @@ fn merge_case_branches( /// Iterates spans directly, emitting one `scalar_at` per row. /// Zero per-run allocations; preferred for fragmented masks (avg run < [`SLICE_CROSSOVER_RUN_LEN`]). +#[expect(deprecated)] fn merge_row_by_row( branch_arrays: &[&ArrayRef], else_value: &ArrayRef, @@ -1219,6 +1220,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_evaluate_nary_string_output() -> VortexResult<()> { // Exercises merge_case_branches with a non-primitive (Utf8) builder. let test_array = diff --git a/vortex-array/src/scalar_fn/fns/is_not_null.rs b/vortex-array/src/scalar_fn/fns/is_not_null.rs index b6a2dcd372f..bcb0c74e31d 100644 --- a/vortex-array/src/scalar_fn/fns/is_not_null.rs +++ b/vortex-array/src/scalar_fn/fns/is_not_null.rs @@ -162,6 +162,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_mask() { let test_array = PrimitiveArray::from_option_iter(vec![Some(1), None, Some(2), None, Some(3)]) @@ -184,6 +185,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_all_true() { let test_array = buffer![1, 2, 3, 4, 5].into_array(); @@ -201,6 +203,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_all_false() { let test_array = PrimitiveArray::from_option_iter(vec![None::, None, None, None, None]) @@ -220,6 +223,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_struct() { let test_array = StructArray::from_fields(&[( "a", diff --git a/vortex-array/src/scalar_fn/fns/is_null.rs b/vortex-array/src/scalar_fn/fns/is_null.rs index 6242ad48394..8790935d910 100644 --- a/vortex-array/src/scalar_fn/fns/is_null.rs +++ b/vortex-array/src/scalar_fn/fns/is_null.rs @@ -150,6 +150,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_mask() { let test_array = PrimitiveArray::from_option_iter(vec![Some(1), None, Some(2), None, Some(3)]) @@ -172,6 +173,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_all_false() { let test_array = buffer![1, 2, 3, 4, 5].into_array(); @@ -190,6 +192,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_all_true() { let test_array = PrimitiveArray::from_option_iter(vec![None::, None, None, None, None]) @@ -210,6 +213,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn evaluate_struct() { let test_array = StructArray::from_fields(&[( "a", diff --git a/vortex-array/src/scalar_fn/fns/list_contains/mod.rs b/vortex-array/src/scalar_fn/fns/list_contains/mod.rs index d2508014089..ae5e2c85e31 100644 --- a/vortex-array/src/scalar_fn/fns/list_contains/mod.rs +++ b/vortex-array/src/scalar_fn/fns/list_contains/mod.rs @@ -225,6 +225,7 @@ fn constant_list_scalar_contains( } /// Returns a [`BoolArray`] where each bit represents if a list contains the scalar. +#[expect(deprecated)] fn list_contains_scalar( array: &ArrayRef, value: &Scalar, @@ -459,6 +460,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_one() { let arr = test_array(); @@ -478,6 +480,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_all() { let arr = test_array(); @@ -497,6 +500,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_none() { let arr = test_array(); @@ -516,6 +520,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_empty() { let arr = ListArray::try_new( PrimitiveArray::from_iter(vec![1, 1, 2, 2, 2]).into_array(), @@ -541,6 +546,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_nullable() { let arr = ListArray::try_new( PrimitiveArray::from_iter(vec![1, 1, 2, 2, 2]).into_array(), @@ -640,6 +646,7 @@ mod tests { } #[test] + #[expect(deprecated)] pub fn test_constant_scalars() { let arr = test_array(); diff --git a/vortex-array/src/scalar_fn/fns/list_length.rs b/vortex-array/src/scalar_fn/fns/list_length.rs index 058cefd1c16..8a3369901a8 100644 --- a/vortex-array/src/scalar_fn/fns/list_length.rs +++ b/vortex-array/src/scalar_fn/fns/list_length.rs @@ -267,6 +267,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_null_scalar_list_length() -> VortexResult<()> { let null_scalar = Scalar::null(DType::List( Arc::new(DType::Primitive(PType::I32, Nullability::NonNullable)), diff --git a/vortex-array/src/scalar_fn/fns/list_sum.rs b/vortex-array/src/scalar_fn/fns/list_sum.rs index f73551250c3..6e09f38d6d8 100644 --- a/vortex-array/src/scalar_fn/fns/list_sum.rs +++ b/vortex-array/src/scalar_fn/fns/list_sum.rs @@ -79,6 +79,7 @@ impl ScalarFnVTable for ListSum { .ok_or_else(|| vortex_err!("list_sum() cannot sum elements of type {elem_dtype}")) } + #[expect(deprecated)] fn execute( &self, options: &Self::Options, @@ -322,6 +323,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_nan_poisons_with_include_nans() -> VortexResult<()> { let elements = PrimitiveArray::from_iter([1.0f64, f64::NAN, 2.0]); let list = ListArray::try_new( @@ -448,6 +450,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_constant_list_sum() -> VortexResult<()> { let elements = create_list_elements(); let list = ListArray::try_new( @@ -467,6 +470,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_null_scalar_list_sum() -> VortexResult<()> { let null_scalar = Scalar::null(DType::List( Arc::new(DType::Primitive(PType::I32, Nullability::NonNullable)), diff --git a/vortex-array/src/scalar_fn/fns/variant_get/mod.rs b/vortex-array/src/scalar_fn/fns/variant_get/mod.rs index 2634aff1d82..95c3ebef48b 100644 --- a/vortex-array/src/scalar_fn/fns/variant_get/mod.rs +++ b/vortex-array/src/scalar_fn/fns/variant_get/mod.rs @@ -131,6 +131,7 @@ impl ScalarFnVTable for VariantGet { .map_or(DType::Variant(Nullability::Nullable), DType::as_nullable)) } + #[expect(deprecated)] fn execute( &self, options: &Self::Options, @@ -772,6 +773,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn variant_get_generic_fallback_preserves_variant_null() -> VortexResult<()> { let array = variant_rows([ Scalar::variant(variant_object([( @@ -810,6 +812,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn variant_get_fallback_variant_output_canonicalizes() -> VortexResult<()> { let array = variant_rows([ Scalar::variant(variant_object([( diff --git a/vortex-array/src/scalar_fn/unstable/row/batch/execute/constant.rs b/vortex-array/src/scalar_fn/unstable/row/batch/execute/constant.rs index 0cd60e821b6..d3e5dd5f168 100644 --- a/vortex-array/src/scalar_fn/unstable/row/batch/execute/constant.rs +++ b/vortex-array/src/scalar_fn/unstable/row/batch/execute/constant.rs @@ -13,6 +13,7 @@ use crate::arrays::ConstantArray; impl RowFnExecutionArgs { /// Execute all-constant inputs by evaluating one row and broadcasting the validated result. + #[expect(deprecated)] pub(super) fn execute_all_constant( &self, kernel: impl Fn(BorrowedRowFnArgs<'_>, &mut ExecutionCtx) -> VortexResult, diff --git a/vortex-array/src/search_sorted/mod.rs b/vortex-array/src/search_sorted/mod.rs index cda27cfc511..e479e023998 100644 --- a/vortex-array/src/search_sorted/mod.rs +++ b/vortex-array/src/search_sorted/mod.rs @@ -274,6 +274,7 @@ fn search_sorted_side_idx VortexResult>( impl IndexOrd for ArrayRef { #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] fn index_cmp(&self, idx: usize, elem: &Scalar) -> VortexResult> { let scalar_a = self.execute_scalar(idx, &mut legacy_session().create_execution_ctx())?; Ok(scalar_a.partial_cmp(elem)) diff --git a/vortex-array/src/search_sorted/primitive.rs b/vortex-array/src/search_sorted/primitive.rs index 3da28c7be2b..918703ad924 100644 --- a/vortex-array/src/search_sorted/primitive.rs +++ b/vortex-array/src/search_sorted/primitive.rs @@ -37,6 +37,7 @@ impl<'a, T: NativePType> SearchSortedPrimitiveArray<'a, T> { } /// Returns the value at `idx`, with nulls mapped to `T::zero()`. + #[expect(deprecated)] fn value(&self, idx: usize) -> VortexResult { Ok(self .0 @@ -59,6 +60,7 @@ impl IndexOrd for SearchSortedPrimitiveArray<'_, T> { } impl IndexOrd> for SearchSortedPrimitiveArray<'_, T> { + #[expect(deprecated)] fn index_cmp(&self, idx: usize, elem: &Option) -> VortexResult> { // The borrow must end before `self.value` re-borrows the ctx. let valid = self.0.is_valid(idx, &mut self.1.borrow_mut())?; diff --git a/vortex-array/src/validity.rs b/vortex-array/src/validity.rs index a2c10e30ca7..d3c984cb82d 100644 --- a/vortex-array/src/validity.rs +++ b/vortex-array/src/validity.rs @@ -24,6 +24,8 @@ use crate::ArrayRef; use crate::Canonical; use crate::ExecutionCtx; use crate::IntoArray; +use crate::ProbeUsage; +use crate::ValidityProbe; use crate::VortexSessionExecute; use crate::arrays::BoolArray; use crate::arrays::ChunkedArray; @@ -162,8 +164,39 @@ impl Validity { } } + /// Create an accessor with the requested policy for retaining state between validity lookups. + /// + /// Mirrors [`ArrayRef::probe`]. Constant states answer from the variant alone; + /// [`Validity::Array`] reads through an owned [`ArrayProbe`](crate::ArrayProbe), so + /// [`ProbeUsage::Repeated`] keeps its preparation across lookups instead of rebuilding it + /// for every row. + /// + /// ``` + /// use vortex_array::IntoArray; + /// use vortex_array::ProbeUsage; + /// use vortex_array::VortexSessionExecute; + /// use vortex_array::arrays::PrimitiveArray; + /// + /// let array = PrimitiveArray::from_option_iter([Some(10i32), None, Some(30)]).into_array(); + /// let mut ctx = vortex_array::array_session().create_execution_ctx(); + /// let mut probe = array.validity()?.probe(ProbeUsage::Repeated); + /// assert!(probe.execute_is_valid(0, &mut ctx)?); + /// assert!(probe.execute_is_invalid(1, &mut ctx)?); + /// assert!(probe.execute_is_valid(2, &mut ctx)?); + /// # Ok::<(), vortex_error::VortexError>(()) + /// ``` + pub fn probe(&self, usage: ProbeUsage) -> ValidityProbe<'static> { + ValidityProbe::owned(self.clone(), usage) + } + /// Returns whether the `index` item is valid, using `ctx` to execute the validity array. + #[deprecated( + note = "Use `Validity::probe` instead, which retains preparation across lookups: \ + `validity.probe(ProbeUsage::Once).execute_is_valid(index, ctx)`, or `ProbeUsage::Repeated` \ + when reading more than one index from the same validity." + )] #[inline] + #[expect(deprecated)] pub fn execute_is_valid(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { Ok(match self { Self::NonNullable | Self::AllValid => true, @@ -177,23 +210,37 @@ impl Validity { } /// Returns whether the `index` item is null, using `ctx` to execute the validity array. + #[deprecated( + note = "Use `Validity::probe` instead, which retains preparation across lookups: \ + `validity.probe(ProbeUsage::Once).execute_is_invalid(index, ctx)`, or \ + `ProbeUsage::Repeated` when reading more than one index from the same validity." + )] #[inline] + #[expect(deprecated)] pub fn execute_is_null(&self, index: usize, ctx: &mut ExecutionCtx) -> VortexResult { Ok(!self.execute_is_valid(index, ctx)?) } /// Returns whether the `index` item is valid. - #[deprecated(note = "use `execute_is_valid` with an explicit `ExecutionCtx`")] + #[deprecated( + note = "Use `Validity::probe` with an explicit `ExecutionCtx` instead: \ + `validity.probe(ProbeUsage::Once).execute_is_valid(index, ctx)`." + )] #[inline] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn is_valid(&self, index: usize) -> VortexResult { self.execute_is_valid(index, &mut legacy_session().create_execution_ctx()) } /// Returns whether the `index` item is null. - #[deprecated(note = "use `execute_is_null` with an explicit `ExecutionCtx`")] + #[deprecated( + note = "Use `Validity::probe` with an explicit `ExecutionCtx` instead: \ + `validity.probe(ProbeUsage::Once).execute_is_invalid(index, ctx)`." + )] #[inline] #[allow(clippy::disallowed_methods)] + #[expect(deprecated)] pub fn is_null(&self, index: usize) -> VortexResult { self.execute_is_null(index, &mut legacy_session().create_execution_ctx()) } diff --git a/vortex-arrow/src/datum.rs b/vortex-arrow/src/datum.rs index 953a9d8d714..cb2e826230f 100644 --- a/vortex-arrow/src/datum.rs +++ b/vortex-arrow/src/datum.rs @@ -150,6 +150,7 @@ where /// # Error /// /// The provided array must have length `len` or `1`. +#[expect(deprecated)] pub fn from_arrow_columnar( array: ArrowArrayRef, len: usize, diff --git a/vortex-btrblocks/src/schemes/patches.rs b/vortex-btrblocks/src/schemes/patches.rs index 69ca8450f12..dbf829b725a 100644 --- a/vortex-btrblocks/src/schemes/patches.rs +++ b/vortex-btrblocks/src/schemes/patches.rs @@ -12,6 +12,7 @@ use vortex_error::VortexError; use vortex_error::VortexResult; /// Compresses the given patches by downscaling integers and checking for constant values. +#[expect(deprecated)] pub fn compress_patches(patches: Patches, ctx: &mut ExecutionCtx) -> VortexResult { // Downscale the patch indices. let indices = patches diff --git a/vortex-compressor/src/compressor/constant.rs b/vortex-compressor/src/compressor/constant.rs index 7e8edc73f2f..0848a17540c 100644 --- a/vortex-compressor/src/compressor/constant.rs +++ b/vortex-compressor/src/compressor/constant.rs @@ -97,6 +97,7 @@ pub(crate) fn is_constant_for_compression( /// # Errors /// /// Returns an error if computing validity or extracting the constant scalar fails. +#[expect(deprecated)] pub(crate) fn compress_constant( source: &ArrayRef, ctx: &mut ExecutionCtx, diff --git a/vortex-datafusion/src/convert/scalars.rs b/vortex-datafusion/src/convert/scalars.rs index c2b1dfc79b2..91f5df3c2aa 100644 --- a/vortex-datafusion/src/convert/scalars.rs +++ b/vortex-datafusion/src/convert/scalars.rs @@ -365,6 +365,7 @@ fn struct_to_df(scalar: &Scalar) -> VortexResult { /// same fields. Going through `ScalarValue` instead would drop each field's `ARROW:extension:name` /// (and its declared nullability), yielding storage-typed children that /// [`Scalar::struct_`] rejects against an extension-typed struct dtype. +#[expect(deprecated)] fn struct_from_df(array: &StructArray, session: &VortexSession) -> Scalar { let arrow = session.arrow(); let dtype = arrow diff --git a/vortex-duckdb/src/duckdb/vector.rs b/vortex-duckdb/src/duckdb/vector.rs index 47cad049516..cf167e8ed90 100644 --- a/vortex-duckdb/src/duckdb/vector.rs +++ b/vortex-duckdb/src/duckdb/vector.rs @@ -422,6 +422,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_create_validity_single_element() { let len = 1; let logical_type = LogicalType::new(DUCKDB_TYPE::DUCKDB_TYPE_INTEGER); @@ -440,6 +441,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_create_validity_single_element_valid() { let len = 1; let logical_type = LogicalType::new(DUCKDB_TYPE::DUCKDB_TYPE_INTEGER); diff --git a/vortex-duckdb/src/exporter/run_end.rs b/vortex-duckdb/src/exporter/run_end.rs index f252866ef3c..a70288cb729 100644 --- a/vortex-duckdb/src/exporter/run_end.rs +++ b/vortex-duckdb/src/exporter/run_end.rs @@ -94,6 +94,7 @@ impl ColumnExporter for RunEndExporter { if start_run_idx == end_run_idx { // NOTE(ngates): would be great if we could just export and set type == CONSTANT // self.values_exporter.export(start_run_idx, 1, vector, cache); + #[expect(deprecated)] let constant = self.values.execute_scalar(start_run_idx, ctx)?; let value = constant.try_to_duckdb_scalar()?; vector.reference_value(&value); diff --git a/vortex-ffi/src/array.rs b/vortex-ffi/src/array.rs index 3d4b9758567..6b482b117a5 100644 --- a/vortex-ffi/src/array.rs +++ b/vortex-ffi/src/array.rs @@ -263,6 +263,7 @@ pub unsafe extern "C-unwind" fn vx_array_slice( /// array is corrupted. #[unsafe(no_mangle)] #[allow(clippy::disallowed_methods)] +#[expect(deprecated)] pub unsafe extern "C-unwind" fn vx_array_element_is_invalid( session: *const vx_session, array: *const vx_array, @@ -516,6 +517,7 @@ pub unsafe extern "C-unwind" fn vx_array_get_bool(array: *const vx_array, index: /// /// Errors if "index" is out of bounds. #[unsafe(no_mangle)] +#[expect(deprecated)] pub unsafe extern "C-unwind" fn vx_array_get_scalar( session: *const vx_session, array: *const vx_array, diff --git a/vortex-ffi/src/expression.rs b/vortex-ffi/src/expression.rs index 1c3eaad3b72..9e56f6d690e 100644 --- a/vortex-ffi/src/expression.rs +++ b/vortex-ffi/src/expression.rs @@ -419,6 +419,7 @@ mod tests { #[test] #[cfg_attr(miri, ignore)] + #[expect(deprecated)] fn test_literal() { let mut ctx = array_session().create_execution_ctx(); let array = diff --git a/vortex-file/src/pruning.rs b/vortex-file/src/pruning.rs index df327638d00..1e9aeb0b4b5 100644 --- a/vortex-file/src/pruning.rs +++ b/vortex-file/src/pruning.rs @@ -25,6 +25,7 @@ use vortex_session::VortexSession; use crate::FileStatistics; +#[expect(deprecated)] pub(crate) fn can_prune_file_stats( expr: &BoundExpression, row_count: u64, diff --git a/vortex-layout/src/layouts/list/reader.rs b/vortex-layout/src/layouts/list/reader.rs index 53227635de6..b58a4de6957 100644 --- a/vortex-layout/src/layouts/list/reader.rs +++ b/vortex-layout/src/layouts/list/reader.rs @@ -543,6 +543,7 @@ fn fetch_validity( } /// Read `offsets[0]` and `offsets[-1]` and return the elements range they bound. +#[expect(deprecated)] fn elements_range_from_offsets( offsets: &ArrayRef, session: &VortexSession, diff --git a/vortex-layout/src/layouts/struct_/reader.rs b/vortex-layout/src/layouts/struct_/reader.rs index 005a4e47fed..9bf26ff254a 100644 --- a/vortex-layout/src/layouts/struct_/reader.rs +++ b/vortex-layout/src/layouts/struct_/reader.rs @@ -877,6 +877,7 @@ mod tests { } #[rstest] + #[expect(deprecated)] fn test_struct_layout_nulls( #[from(null_struct_layout)] (segments, layout): (Arc, LayoutRef), ) { @@ -909,6 +910,7 @@ mod tests { } #[rstest] + #[expect(deprecated)] fn test_struct_layout_nested( #[from(nested_struct_layout)] (segments, layout): (Arc, LayoutRef), ) { diff --git a/vortex-python/src/arrays/mod.rs b/vortex-python/src/arrays/mod.rs index 834b42ef718..6731f1dfe2e 100644 --- a/vortex-python/src/arrays/mod.rs +++ b/vortex-python/src/arrays/mod.rs @@ -799,6 +799,7 @@ impl PyArray { /// OverflowError: can't convert negative int to unsigned /// ``` // TODO(ngates): return a vortex.Scalar + #[expect(deprecated)] fn scalar_at(slf: Bound, index: usize) -> PyVortexResult> { // PyArray/PyArrayRef do not currently carry a VortexSession; threading one // through would change the FromPyObject contract. Use the crate session diff --git a/vortex-python/src/arrays/py/vtable.rs b/vortex-python/src/arrays/py/vtable.rs index 5ec749d3a5f..5697d5a7574 100644 --- a/vortex-python/src/arrays/py/vtable.rs +++ b/vortex-python/src/arrays/py/vtable.rs @@ -122,6 +122,8 @@ impl VTable for PythonVTable { } impl OperationsVTable for PythonVTable { + type ProbeState = (); + fn scalar_at( _array: ArrayView<'_, PythonVTable>, _index: usize, diff --git a/vortex-python/src/scan.rs b/vortex-python/src/scan.rs index 913443cc298..24f9c261063 100644 --- a/vortex-python/src/scan.rs +++ b/vortex-python/src/scan.rs @@ -59,6 +59,7 @@ impl PyRepeatedScan { }) } + #[expect(deprecated)] fn scalar_at(slf: Bound, index: u64) -> PyVortexResult> { let row_count = slf.get().row_count; if index >= row_count { diff --git a/vortex-spatial/benches/binary_predicates.rs b/vortex-spatial/benches/binary_predicates.rs index 8cc25888e59..77e032dddf2 100644 --- a/vortex-spatial/benches/binary_predicates.rs +++ b/vortex-spatial/benches/binary_predicates.rs @@ -83,6 +83,7 @@ fn query_ring(cx: f64, cy: f64) -> Vec<(f64, f64)> { /// The query polygon as a batch-constant operand: a top-level `ConstantArray` over the geometry /// extension scalar, the shape that reaches the row loop's stride-0 path. +#[expect(deprecated)] fn query_constant(ctx: &mut ExecutionCtx, rows: usize) -> ArrayRef { let scalar = polygon_column(vec![vec![query_ring(0.0, 0.0)]]) .unwrap() @@ -92,6 +93,7 @@ fn query_constant(ctx: &mut ExecutionCtx, rows: usize) -> ArrayRef { } /// A batch-constant point operand with the requested row count. +#[expect(deprecated)] fn point_constant(ctx: &mut ExecutionCtx, rows: usize) -> ArrayRef { let scalar = point_column(vec![0.0], vec![0.0]) .unwrap() diff --git a/vortex-spatial/benches/distance.rs b/vortex-spatial/benches/distance.rs index 50714841e1e..32a3b53cbf6 100644 --- a/vortex-spatial/benches/distance.rs +++ b/vortex-spatial/benches/distance.rs @@ -77,6 +77,7 @@ fn polygons(rows: usize) -> ArrayRef { polygon_column(rows).unwrap() } +#[expect(deprecated)] fn point_constant(x: f64, y: f64, rows: usize, ctx: &mut ExecutionCtx) -> ArrayRef { let scalar = point_column(vec![x], vec![y]) .unwrap() @@ -85,6 +86,7 @@ fn point_constant(x: f64, y: f64, rows: usize, ctx: &mut ExecutionCtx) -> ArrayR ConstantArray::new(scalar, rows).into_array() } +#[expect(deprecated)] fn polygon_constant(rows: usize, ctx: &mut ExecutionCtx) -> ArrayRef { let scalar = polygon_column(vec![square(0.0, 0.0)]) .unwrap() diff --git a/vortex-spatial/benches/make_line.rs b/vortex-spatial/benches/make_line.rs index 04cb2c47505..476b5c3ca10 100644 --- a/vortex-spatial/benches/make_line.rs +++ b/vortex-spatial/benches/make_line.rs @@ -74,6 +74,7 @@ fn nullable_points(offset: usize, null_every: usize) -> ArrayRef { .unwrap() } +#[expect(deprecated)] fn point_constant(ctx: &mut ExecutionCtx) -> ArrayRef { let scalar = point_column(vec![0.0], vec![0.0]) .unwrap() diff --git a/vortex-spatial/src/extension/point.rs b/vortex-spatial/src/extension/point.rs index e6a00fe8fea..f8cae058e3a 100644 --- a/vortex-spatial/src/extension/point.rs +++ b/vortex-spatial/src/extension/point.rs @@ -348,6 +348,7 @@ mod tests { /// A `Point` column round-trips through scalar execution back to the original coordinates. #[test] + #[expect(deprecated)] fn point_unpacks_coordinates() -> VortexResult<()> { let session = vortex_array::array_session(); let mut ctx = session.create_execution_ctx(); diff --git a/vortex-spatial/src/prune/distance.rs b/vortex-spatial/src/prune/distance.rs index 9231b33875e..e3cdd630b10 100644 --- a/vortex-spatial/src/prune/distance.rs +++ b/vortex-spatial/src/prune/distance.rs @@ -154,6 +154,7 @@ mod tests { /// Run the rule against `SpatialDistance(root, origin) radius`, operands swapped when /// `geom_first` is false. The radius is any literal scalar, matching the uncoerced filter /// expressions the rule sees in production. + #[expect(deprecated)] fn falsify_distance( operator: Operator, geom_first: bool, @@ -253,6 +254,7 @@ mod tests { /// An extension-typed radius passes `Binary`'s typecheck (extension operands are exempt) but /// has no numeric value - the rule declines rather than erroring, and the chunk is scanned. #[test] + #[expect(deprecated)] fn extension_radius_never_prunes() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -264,6 +266,7 @@ mod tests { /// A non-geometry scope is rejected while binding, before stats rewriting. #[test] + #[expect(deprecated)] fn unsupported_scope_is_not_pruned() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -290,6 +293,7 @@ mod tests { /// End-to-end over a hand-built zone map: the far chunk is skipped, the near one kept. #[test] + #[expect(deprecated)] fn prunes_far_chunk_keeps_near() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -318,6 +322,7 @@ mod tests { /// The true-distance prune skips a chunk that is *diagonally* farther than `r`, even though /// neither axis alone exceeds `r`, the case a per-axis box-overlap test would wrongly keep. #[test] + #[expect(deprecated)] fn prunes_diagonally_distant_chunk() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -348,6 +353,7 @@ mod tests { /// A `>= r` filter prunes a chunk lying wholly *within* `r` (every row nearer than `r`, so none /// satisfy `>= r`) via the box max-distance, while a chunk beyond `r` is kept. #[test] + #[expect(deprecated)] fn prunes_within_chunk_for_far_filter() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -376,6 +382,7 @@ mod tests { /// Backward compat: a zone map written without the `GeometryAabb` stat (an older file) keeps /// every zone, the missing stat binds to null and `null_as_false` retains the zone. #[test] + #[expect(deprecated)] fn missing_aabb_stat_keeps_all_zones() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); diff --git a/vortex-spatial/src/prune/intersects.rs b/vortex-spatial/src/prune/intersects.rs index 74103003b2f..c916c178783 100644 --- a/vortex-spatial/src/prune/intersects.rs +++ b/vortex-spatial/src/prune/intersects.rs @@ -75,6 +75,7 @@ mod tests { /// Run the intersects rule against `SpatialIntersects(root, point(1.0, 0.5))`, operands swapped /// when `geom_first` is false. + #[expect(deprecated)] fn falsify_intersects(geom_first: bool) -> VortexResult> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -103,6 +104,7 @@ mod tests { /// A non-geometry scope is rejected while binding, before stats rewriting. #[test] + #[expect(deprecated)] fn unsupported_scope_is_not_pruned() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -134,6 +136,7 @@ mod tests { /// End-to-end: a zone strictly separated from the query is skipped; zones containing or merely /// touching the query must scan, touching geometries intersect under OGC semantics. #[test] + #[expect(deprecated)] fn prunes_disjoint_keeps_touching_and_containing() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); @@ -164,6 +167,7 @@ mod tests { /// Backward compat: a zone map written without the `GeometryAabb` stat keeps every zone. #[test] + #[expect(deprecated)] fn missing_aabb_stat_keeps_all_zones() -> VortexResult<()> { let session = spatial_session(); let mut ctx = session.create_execution_ctx(); diff --git a/vortex-spatial/src/scalar_fn/collect.rs b/vortex-spatial/src/scalar_fn/collect.rs index a7708f8e8d3..faef46fdd9b 100644 --- a/vortex-spatial/src/scalar_fn/collect.rs +++ b/vortex-spatial/src/scalar_fn/collect.rs @@ -210,6 +210,7 @@ fn collect_list_rows( } /// Apply [`collect_list_rows`] to a constant or column, after shared unary null dispatch. +#[expect(deprecated)] fn execute_collect( execution: Execution<1, Validity>, output_dtype: &ExtDTypeRef, @@ -504,6 +505,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn constant_list_remains_constant() -> VortexResult<()> { let input = list( nullable_point_column(vec![Some((0.0, 2.0)), None, Some((1.0, 3.0))])?, diff --git a/vortex-spatial/src/scalar_fn/convex_hull.rs b/vortex-spatial/src/scalar_fn/convex_hull.rs index f7bc47f891c..e371949c2fe 100644 --- a/vortex-spatial/src/scalar_fn/convex_hull.rs +++ b/vortex-spatial/src/scalar_fn/convex_hull.rs @@ -199,6 +199,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn constant_remains_constant() -> VortexResult<()> { let mut ctx = vortex_array::array_session().create_execution_ctx(); let scalar = multipoint_column(vec![vec![(0.0, 0.0), (1.0, 0.0), (0.0, 1.0)]])? diff --git a/vortex-spatial/src/scalar_fn/distance.rs b/vortex-spatial/src/scalar_fn/distance.rs index c78c8f89262..749bf7aee7f 100644 --- a/vortex-spatial/src/scalar_fn/distance.rs +++ b/vortex-spatial/src/scalar_fn/distance.rs @@ -95,6 +95,7 @@ mod tests { use crate::test_harness::polygon_column; /// A constant `Point` column of length `len`, every row at `(x, y)`. + #[expect(deprecated)] fn point_constant( x: f64, y: f64, @@ -146,6 +147,7 @@ mod tests { /// Distance passes no bounding-rect rejection: a point far outside a constant polygon's /// bounding rect still gets its true distance, alongside an inside point at distance zero. #[test] + #[expect(deprecated)] fn distance_to_constant_polygon_is_exact() -> VortexResult<()> { let session = vortex_array::array_session(); let mut ctx = session.create_execution_ctx(); diff --git a/vortex-spatial/src/scalar_fn/envelope.rs b/vortex-spatial/src/scalar_fn/envelope.rs index 553fb415017..c76a505084f 100644 --- a/vortex-spatial/src/scalar_fn/envelope.rs +++ b/vortex-spatial/src/scalar_fn/envelope.rs @@ -188,6 +188,7 @@ fn envelope_array( } /// Execute `envelope` after shared constant/column and null dispatch. +#[expect(deprecated)] fn execute_envelope( execution: Execution<1, Validity>, output_dtype: &ExtDType, @@ -548,6 +549,7 @@ mod tests { /// A non-null constant is boxed once and retained as a constant output. #[test] + #[expect(deprecated)] fn constant_point_remains_constant() -> VortexResult<()> { let session = crate::test_harness::spatial_session(); let mut ctx = session.create_execution_ctx(); diff --git a/vortex-spatial/src/scalar_fn/length.rs b/vortex-spatial/src/scalar_fn/length.rs index f2c12b72692..3d5d24242cc 100644 --- a/vortex-spatial/src/scalar_fn/length.rs +++ b/vortex-spatial/src/scalar_fn/length.rs @@ -130,6 +130,7 @@ fn length_array( } /// Execute length after shared constant/column and null dispatch. +#[expect(deprecated)] fn execute_length( execution: Execution<1, Validity>, ctx: &mut ExecutionCtx, @@ -248,6 +249,7 @@ mod tests { use crate::test_harness::multilinestring_column; use crate::test_harness::point_column; + #[expect(deprecated)] fn line_constant( line: Vec<(f64, f64)>, len: usize, diff --git a/vortex-spatial/src/scalar_fn/make_line.rs b/vortex-spatial/src/scalar_fn/make_line.rs index fdd69676acd..278c976c338 100644 --- a/vortex-spatial/src/scalar_fn/make_line.rs +++ b/vortex-spatial/src/scalar_fn/make_line.rs @@ -136,6 +136,7 @@ fn build_make_lines( } /// Execute `ST_MakeLine` after shared constant/column and null dispatch. +#[expect(deprecated)] fn execute_make_line( execution: Execution<2>, output_dtype: &ExtDType, @@ -299,6 +300,7 @@ mod tests { Ok(ExtensionArray::try_new(dtype.erased(), storage)?.into_array()) } + #[expect(deprecated)] fn point_constant( x: f64, y: f64, diff --git a/vortex-spatial/src/tests/point.rs b/vortex-spatial/src/tests/point.rs index aec2e91bcbf..338d56615bc 100644 --- a/vortex-spatial/src/tests/point.rs +++ b/vortex-spatial/src/tests/point.rs @@ -135,6 +135,7 @@ fn import_interleaved_field_fails() { /// Import wraps the Arrow struct's coordinate buffers into a Point column. #[test] +#[expect(deprecated)] fn imports_from_struct() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let arrow: ArrowArrayRef = @@ -163,6 +164,7 @@ fn imports_from_struct() -> VortexResult<()> { /// A point column exported to Arrow and imported back is unchanged, including the CRS. #[test] +#[expect(deprecated)] fn roundtrips_through_arrow() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let original = point_column(vec![0.0, 3.0], vec![4.0, 0.0])?; diff --git a/vortex-spatial/src/tests/rect.rs b/vortex-spatial/src/tests/rect.rs index 9baf724af6e..4860f781e83 100644 --- a/vortex-spatial/src/tests/rect.rs +++ b/vortex-spatial/src/tests/rect.rs @@ -73,6 +73,7 @@ fn import_field_recovers_extension() -> VortexResult<()> { /// A `Rect` column exported to Arrow and imported back is unchanged, including the CRS and the /// box corners. #[test] +#[expect(deprecated)] fn roundtrips_through_arrow() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let original = rect_column(vec![(0.0, 1.0, 2.0, 3.0), (-5.0, -5.0, 5.0, 5.0)])?; diff --git a/vortex-spatial/src/tests/wkb.rs b/vortex-spatial/src/tests/wkb.rs index 5ed4273cb0b..d4b197f3c4f 100644 --- a/vortex-spatial/src/tests/wkb.rs +++ b/vortex-spatial/src/tests/wkb.rs @@ -103,6 +103,7 @@ fn assert_imported_wkb_dtype(dtype: &DType, expected_crs: Option<&str>, nullable /// WKB scalars unpack back to the geometry they encode. #[test] +#[expect(deprecated)] fn scalar_unpacks_to_geometry() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let (_, array) = wkb_extension_array()?; @@ -182,6 +183,7 @@ fn import_field_without_crs() -> VortexResult<()> { /// Import wraps the binary-family Arrow array's WKB values unchanged. #[test] +#[expect(deprecated)] fn imports_from_binary() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let (wkb_bytes, _) = wkb_extension_array()?; @@ -238,6 +240,7 @@ fn imports_from_binary_view() -> VortexResult<()> { /// A WKB column exported to Arrow and imported back is unchanged, byte for byte. #[test] +#[expect(deprecated)] fn roundtrips_through_arrow() -> VortexResult<()> { let mut ctx = SESSION.create_execution_ctx(); let (wkb_bytes, original) = wkb_extension_array()?; diff --git a/vortex-tensor/src/scalar_fns/cosine_similarity.rs b/vortex-tensor/src/scalar_fns/cosine_similarity.rs index 5ffc466bfa8..ca4f2b3437e 100644 --- a/vortex-tensor/src/scalar_fns/cosine_similarity.rs +++ b/vortex-tensor/src/scalar_fns/cosine_similarity.rs @@ -365,6 +365,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn null_input_row() -> VortexResult<()> { // 2 rows of dim-2 vectors. Row 1 of rhs is masked as null. let lhs = tensor_array(&[2], &[3.0, 4.0, 1.0, 0.0])?; diff --git a/vortex-tensor/src/scalar_fns/inner_product.rs b/vortex-tensor/src/scalar_fns/inner_product.rs index 974b59e7e91..bf9739b69d2 100644 --- a/vortex-tensor/src/scalar_fns/inner_product.rs +++ b/vortex-tensor/src/scalar_fns/inner_product.rs @@ -290,6 +290,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn null_input_row() -> VortexResult<()> { // 3 rows of dim-2 vectors. Row 1 of lhs is masked as null. let lhs = tensor_array(&[2], &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])?; diff --git a/vortex-tensor/src/scalar_fns/l2_norm.rs b/vortex-tensor/src/scalar_fns/l2_norm.rs index ea7b47a721e..086da54d2d5 100644 --- a/vortex-tensor/src/scalar_fns/l2_norm.rs +++ b/vortex-tensor/src/scalar_fns/l2_norm.rs @@ -306,6 +306,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn null_input_row() -> VortexResult<()> { // 2 rows of dim-2 vectors. Row 1 is masked as null. let arr = tensor_array(&[2], &[3.0, 4.0, 0.0, 0.0])?; diff --git a/vortex-tensor/src/scalar_fns/l2_normalize.rs b/vortex-tensor/src/scalar_fns/l2_normalize.rs index 74139a506a2..7dabb8cbf19 100644 --- a/vortex-tensor/src/scalar_fns/l2_normalize.rs +++ b/vortex-tensor/src/scalar_fns/l2_normalize.rs @@ -373,6 +373,7 @@ mod tests { } #[test] + #[expect(deprecated)] fn test_input_nulls_produce_null_struct_rows() -> VortexResult<()> { let input = vector_array( 2, diff --git a/vortex-test/compat-gen/src/fixtures/arrays/synthetic/encodings/constant.rs b/vortex-test/compat-gen/src/fixtures/arrays/synthetic/encodings/constant.rs index c77c10fe311..409718046d9 100644 --- a/vortex-test/compat-gen/src/fixtures/arrays/synthetic/encodings/constant.rs +++ b/vortex-test/compat-gen/src/fixtures/arrays/synthetic/encodings/constant.rs @@ -39,6 +39,7 @@ impl FlatLayoutFixture for ConstantFixture { vec![Constant.id()] } + #[expect(deprecated)] fn build(&self, ctx: &mut ExecutionCtx) -> VortexResult { let const_i32 = ConstantArray::new(42i32, N); let const_f64 = ConstantArray::new(99.99f64, N); diff --git a/vortex-tui/src/browse/ui/layouts.rs b/vortex-tui/src/browse/ui/layouts.rs index bace4ef2c0e..1aba5737aa0 100644 --- a/vortex-tui/src/browse/ui/layouts.rs +++ b/vortex-tui/src/browse/ui/layouts.rs @@ -125,6 +125,7 @@ fn render_layout_header(app: &AppState, area: Rect, buf: &mut Buffer) { } /// Render the inner Array for a FlatLayout. +#[expect(deprecated)] fn render_array(app: &AppState, area: Rect, buf: &mut Buffer, is_stats_table: bool) { // Array data is loaded eagerly when navigating to a FlatLayout (synchronously on // native, asynchronously on WASM) and cached in AppState. The render loop never