From 17e0e5284148a393cf67f42e990f706bd5a79bf6 Mon Sep 17 00:00:00 2001 From: amorynan Date: Sat, 27 Dec 2025 15:57:02 +0800 Subject: [PATCH 1/8] add a method to push struct validity into children Signed-off-by: amorynan --- vortex-array/src/arrays/struct_/array.rs | 112 ++++++++++++++ vortex-array/src/arrays/struct_/tests.rs | 177 +++++++++++++++++++++++ 2 files changed, 289 insertions(+) diff --git a/vortex-array/src/arrays/struct_/array.rs b/vortex-array/src/arrays/struct_/array.rs index a0b2418b903..e74bf7b2f35 100644 --- a/vortex-array/src/arrays/struct_/array.rs +++ b/vortex-array/src/arrays/struct_/array.rs @@ -13,6 +13,7 @@ use vortex_error::VortexExpect; use vortex_error::VortexResult; use vortex_error::vortex_bail; use vortex_error::vortex_err; +use vortex_mask::Mask; use crate::Array; use crate::ArrayRef; @@ -451,4 +452,115 @@ impl StructArray { Self::try_new_with_dtype(children, new_fields, self.len, self.validity.clone()) } + + /// Push the struct-level validity into the children fields. + /// + /// This method takes the top-level validity of the struct array and applies it to each child field + /// using a mask operation. The resulting struct array will have the struct-level nulls propagated + /// down to the individual fields. + /// + /// # Parameters + /// + /// * `preserve_struct_validity` - If `Some(true)`, the new struct array retains the original struct-level + /// validity. If `Some(false)` or `None`, the new struct array has `Validity::AllValid` since all null + /// information is now contained within the individual fields. Defaults to `false` when `None`. + /// + /// # Returns + /// + /// A new `StructArray` where each child field has been masked with the struct's validity. + /// + /// # Examples + /// + /// ``` + /// use vortex_array::arrays::StructArray; + /// use vortex_array::validity::Validity; + /// use vortex_array::IntoArray; + /// use vortex_buffer::buffer; + /// + /// // Create struct with top-level nulls + /// let struct_array = StructArray::try_new( + /// ["a", "b"].into(), + /// vec![ + /// buffer![1i32, 2i32, 3i32].into_array(), + /// buffer![10i32, 20i32, 30i32].into_array(), + /// ], + /// 3, + /// Validity::from_iter([true, false, true]), // row 1 is null + /// ).unwrap(); + /// + /// // Push validity into children, preserving struct validity + /// let pushed = struct_array.push_validity_into_children(true).unwrap(); + /// // pushed.fields()[0] now has nulls at position 1 + /// // pushed.fields()[1] now has nulls at position 1 + /// // pushed.validity still shows row 1 as null + /// + /// // Push validity into children, removing struct validity (default behavior) + /// let pushed_no_struct = struct_array.push_validity_into_children_default().unwrap(); + /// // or explicitly: + /// let pushed_no_struct = struct_array.push_validity_into_children(false).unwrap(); + /// // pushed_no_struct.fields()[0] now has nulls at position 1 + /// // pushed_no_struct.fields()[1] now has nulls at position 1 + /// // pushed_no_struct.validity is AllValid + /// ``` + /// Push validity into children with default behavior (preserve_struct_validity = false). + /// + /// This is equivalent to calling `push_validity_into_children(None)` or + /// `push_validity_into_children(Some(false))`. + pub fn push_validity_into_children_default(&self) -> VortexResult { + self.push_validity_into_children(false) + } + + + pub fn push_validity_into_children(&self, preserve_struct_validity: bool) -> VortexResult { + use crate::compute::mask; + + // Get the struct-level validity mask + let struct_validity_mask = self.validity_mask(); + + // If the struct has no nulls, return a clone + if struct_validity_mask.all_true() { + return if preserve_struct_validity { + Ok(self.clone()) + } else { + // Remove struct validity if requested + Self::try_new( + self.names().clone(), + self.fields().clone(), + self.len(), + Validity::AllValid, + ) + }; + } + + // Apply the struct validity mask to each child field + // We want to set nulls where the struct is null (i.e., where struct_validity_mask is false) + // So we need to invert the mask: where struct is invalid, set child to invalid + let null_mask = struct_validity_mask.iter_bools(|iter| { + Mask::from_iter(iter.map(|valid| !valid)) // invert: valid->invalid, invalid->valid + }); + + let masked_fields: Vec = self + .fields() + .iter() + .map(|field| { + // Use the mask function to apply null positions to each field + mask(field.as_ref(), &null_mask) + }) + .collect::>>()?; + + // Determine the new struct validity (default to false = remove struct validity) + let new_struct_validity = if preserve_struct_validity { + self.validity.clone() + } else { + Validity::AllValid + }; + + // Construct the new struct array + Self::try_new( + self.names().clone(), + masked_fields, + self.len(), + new_struct_validity, + ) + } } diff --git a/vortex-array/src/arrays/struct_/tests.rs b/vortex-array/src/arrays/struct_/tests.rs index d768adff136..a5b41969a4b 100644 --- a/vortex-array/src/arrays/struct_/tests.rs +++ b/vortex-array/src/arrays/struct_/tests.rs @@ -7,6 +7,7 @@ use vortex_dtype::FieldName; use vortex_dtype::FieldNames; use vortex_dtype::Nullability; use vortex_dtype::PType; +use vortex_scalar::Scalar; use crate::Array; use crate::IntoArray; @@ -150,3 +151,179 @@ fn test_uncompressed_size_in_bytes() { assert_eq!(canonical_size, 2); assert_eq!(uncompressed_size, Some(4000)); } + +#[test] +fn test_push_validity_into_children_preserve_struct() { + // Create struct with top-level nulls + // structArray : [a, b] + // fields: [1, 2, 3] (a), [10, 20, 30] (b) + // validity: [true, false, true] + // row 1 is null at struct level + let struct_array = StructArray::try_new( + ["a", "b"].into(), + vec![ + buffer![1i32, 2i32, 3i32].into_array(), + buffer![10i32, 20i32, 30i32].into_array(), + ], + 3, + Validity::from_iter([true, false, true]), // row 1 is null at struct level + ) + .unwrap(); + + // Push validity into children, preserving struct validity + let pushed = struct_array.push_validity_into_children(true).unwrap(); + + // Check that struct validity is preserved + assert_eq!(pushed.validity_mask(), struct_array.validity_mask()); + + // Check that children now have nulls where struct was null + let field_a = pushed.fields()[0].as_ref(); + let field_b = pushed.fields()[1].as_ref(); + + + assert!(field_a.is_valid(0)); + assert!(!field_a.is_valid(1)); // Should be null due to struct null + assert!(field_a.is_valid(2)); + + assert!(field_b.is_valid(0)); + assert!(!field_b.is_valid(1)); // Should be null due to struct null + assert!(field_b.is_valid(2)); + + + // Original values should be preserved where valid + assert_eq!(field_a.scalar_at(0), 1i32.into()); + assert_eq!(field_a.scalar_at(2), 3i32.into()); + assert_eq!(field_b.scalar_at(0), 10i32.into()); + assert_eq!(field_b.scalar_at(2), 30i32.into()); + + + // Verify pushed struct array values (preserve_struct_validity = true) + assert!(pushed.is_valid(0)); // Row 0 should be valid + assert!(!pushed.is_valid(1)); // Row 1 should be null (preserved) + assert!(pushed.is_valid(2)); // Row 2 should be valid + + // Row 0: {a: 1, b: 10} - should be valid struct with valid fields + let row0 = pushed.scalar_at(0); + assert!(row0.is_valid()); + + // Row 1: null - should be null struct (preserved from original) + let row1 = pushed.scalar_at(1); + assert!(!row1.is_valid()); + + // Row 2: {a: 3, b: 30} - should be valid struct with valid fields + let row2 = pushed.scalar_at(2); + assert!(row2.is_valid()); + +} + +#[test] +fn test_push_validity_into_children_remove_struct() { + + // Create struct with top-level nulls + let struct_array = StructArray::try_new( + ["a", "b"].into(), + vec![ + buffer![1i32, 2i32, 3i32].into_array(), + buffer![10i32, 20i32, 30i32].into_array(), + ], + 3, + Validity::from_iter([true, false, true]), // row 1 is null at struct level + ) + .unwrap(); + + + // Push validity into children, removing struct validity when default behavior is used (preserve_struct_validity = false) + let pushed = struct_array.push_validity_into_children_default().unwrap(); + + + // Check that struct validity is now AllValid + assert!(pushed.validity_mask().all_true()); + + // Check that children still have nulls where struct was null + let field_a = pushed.fields()[0].as_ref(); + let field_b = pushed.fields()[1].as_ref(); + + + assert!(field_a.is_valid(0)); + assert!(!field_a.is_valid(1)); // Should be null due to struct null + assert!(field_a.is_valid(2)); + + assert!(field_b.is_valid(0)); + assert!(!field_b.is_valid(1)); // Should be null due to struct null + assert!(field_b.is_valid(2)); + + // Original values should be preserved where valid + assert_eq!(field_a.scalar_at(0), 1i32.into()); + assert_eq!(field_a.scalar_at(2), 3i32.into()); + assert_eq!(field_b.scalar_at(0), 10i32.into()); + assert_eq!(field_b.scalar_at(2), 30i32.into()); + + // Verify null values using proper null scalar comparison + use vortex_dtype::{DType, Nullability, PType}; + let null_i32_scalar = Scalar::null(DType::Primitive(PType::I32, Nullability::Nullable)); + assert_eq!(field_a.scalar_at(1), null_i32_scalar); + assert_eq!(field_b.scalar_at(1), null_i32_scalar); + + // Alternative: check if the scalar is null + assert!(!field_a.scalar_at(1).is_valid()); + assert!(!field_b.scalar_at(1).is_valid()); + + // Verify pushed struct array values (preserve_struct_validity = false) + assert!(pushed.is_valid(0)); // Row 0 should be valid + assert!(pushed.is_valid(1)); // Row 1 should be valid (validity removed) + assert!(pushed.is_valid(2)); // Row 2 should be valid + + // Row 0: {a: 1, b: 10} - should be valid struct with valid fields + let row0 = pushed.scalar_at(0); + assert!(row0.is_valid()); + + // Row 1: {a: null, b: null} - should be valid struct but with null fields + let row1 = pushed.scalar_at(1); + assert!(row1.is_valid()); // Struct is valid, but fields are null + + // Row 2: {a: 3, b: 30} - should be valid struct with valid fields + let row2 = pushed.scalar_at(2); + assert!(row2.is_valid()); + +} + +#[test] +fn test_push_validity_into_children_no_nulls() { + // Create struct without any nulls + let struct_array = StructArray::try_new( + ["a", "b"].into(), + vec![ + buffer![1i32, 2i32, 3i32].into_array(), + buffer![10i32, 20i32, 30i32].into_array(), + ], + 3, + Validity::AllValid, + ) + .unwrap(); + + + // Push validity into children (should be no-op when preserve=true) + let pushed_preserve = struct_array.push_validity_into_children(true).unwrap(); + assert_eq!(pushed_preserve.validity_mask(), struct_array.validity_mask()); + + // Push validity into children (should change validity to AllValid when preserve=false) + let pushed_remove = struct_array.push_validity_into_children(false).unwrap(); + assert!(pushed_remove.validity_mask().all_true()); + + // Fields should remain unchanged + for i in 0..struct_array.fields().len() { + assert_eq!( + pushed_preserve.fields()[i].scalar_at(0), + struct_array.fields()[i].scalar_at(0) + ); + assert_eq!( + pushed_preserve.fields()[i].scalar_at(1), + struct_array.fields()[i].scalar_at(1) + ); + assert_eq!( + pushed_preserve.fields()[i].scalar_at(2), + struct_array.fields()[i].scalar_at(2) + ); + } + +} From d02d28caf89948465294833c6f35c5bdcb6d6e35 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 01:00:47 +0000 Subject: [PATCH 2/8] Update all patch updates (#5809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [cc](https://redirect.github.com/rust-lang/cc-rs) | workspace.dependencies | patch | `1.2.49` -> `1.2.50` | ![age](https://developer.mend.io/api/mc/badges/age/crate/cc/1.2.50?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/cc/1.2.49/1.2.50?slim=true) | | [cxx](https://cxx.rs) ([source](https://redirect.github.com/dtolnay/cxx)) | dependencies | patch | `1.0.191` -> `1.0.192` | ![age](https://developer.mend.io/api/mc/badges/age/crate/cxx/1.0.192?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/cxx/1.0.191/1.0.192?slim=true) | | [cxx-build](https://cxx.rs) ([source](https://redirect.github.com/dtolnay/cxx)) | build-dependencies | patch | `1.0.191` -> `1.0.192` | ![age](https://developer.mend.io/api/mc/badges/age/crate/cxx-build/1.0.192?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/cxx-build/1.0.191/1.0.192?slim=true) | | [moka](https://redirect.github.com/moka-rs/moka) | workspace.dependencies | patch | `0.12.11` -> `0.12.12` | ![age](https://developer.mend.io/api/mc/badges/age/crate/moka/0.12.12?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/moka/0.12.11/0.12.12?slim=true) | | [reqwest](https://redirect.github.com/seanmonstar/reqwest) | workspace.dependencies | patch | `0.12.25` -> `0.12.26` | ![age](https://developer.mend.io/api/mc/badges/age/crate/reqwest/0.12.26?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/reqwest/0.12.25/0.12.26?slim=true) | | [roaring](https://redirect.github.com/RoaringBitmap/roaring-rs) | workspace.dependencies | patch | `0.11.2` -> `0.11.3` | ![age](https://developer.mend.io/api/mc/badges/age/crate/roaring/0.11.3?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/roaring/0.11.2/0.11.3?slim=true) | | [target-lexicon](https://redirect.github.com/bytecodealliance/target-lexicon) | workspace.dependencies | patch | `0.13.3` -> `0.13.4` | ![age](https://developer.mend.io/api/mc/badges/age/crate/target-lexicon/0.13.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/crate/target-lexicon/0.13.3/0.13.4?slim=true) | | com.google.protobuf | plugin | patch | `0.9.5` -> `0.9.6` | ![age](https://developer.mend.io/api/mc/badges/age/maven/com.google.protobuf:com.google.protobuf.gradle.plugin/0.9.6?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/maven/com.google.protobuf:com.google.protobuf.gradle.plugin/0.9.5/0.9.6?slim=true) | --- ### Release Notes
rust-lang/cc-rs (cc) ### [`v1.2.50`](https://redirect.github.com/rust-lang/cc-rs/blob/HEAD/CHANGELOG.md#1250---2025-12-19) [Compare Source](https://redirect.github.com/rust-lang/cc-rs/compare/cc-v1.2.49...cc-v1.2.50) ##### Other - Add tests for `OUT_DIR` escape for '..' file paths ([#​1631](https://redirect.github.com/rust-lang/cc-rs/issues/1631)) - Fix [#​283](https://redirect.github.com/rust-lang/cc-rs/issues/283): Make warnings(false) actually suppress compiler warnings ([#​1633](https://redirect.github.com/rust-lang/cc-rs/pull/1633))
dtolnay/cxx (cxx) ### [`v1.0.192`](https://redirect.github.com/dtolnay/cxx/releases/tag/1.0.192) [Compare Source](https://redirect.github.com/dtolnay/cxx/compare/1.0.191...1.0.192) - Add support for `Vec>` ([#​1681](https://redirect.github.com/dtolnay/cxx/issues/1681), thanks [@​anforowicz](https://redirect.github.com/anforowicz))
moka-rs/moka (moka) ### [`v0.12.12`](https://redirect.github.com/moka-rs/moka/blob/HEAD/CHANGELOG.md#Version-01212) [Compare Source](https://redirect.github.com/moka-rs/moka/compare/v0.12.11...v0.12.12) Bumped the minimum supported Rust version (MSRV) to 1.71.1, released on August 3, 2023 (\[[#​555](https://redirect.github.com/moka-rs/moka/issues/555)]\[gh-pull-0555]). ##### Fixed - Fixed use-after-free panic in the hierarchical timer wheels when `Expiry` returns `None` (\[[#​548](https://redirect.github.com/moka-rs/moka/issues/548)]\[gh-pull-0548], by \[[@​awarus](https://redirect.github.com/awarus)]\[gh-awarus]). - Fixed a subtle undefined behavior (UB) in the internal `deque::move_to_back` method (found by Miri) (\[[#​553](https://redirect.github.com/moka-rs/moka/issues/553)]\[gh-pull-0553]). ##### Added - `impl Expiry` for some types (\[[#​519](https://redirect.github.com/moka-rs/moka/issues/519)]\[gh-pull-0519], by \[[@​koushiro](https://redirect.github.com/koushiro)]\[gh-koushiro]). ##### Removed - Removed several unneeded files from the published package (\[[#​541](https://redirect.github.com/moka-rs/moka/issues/541)]\[gh-pull-0541], by \[[@​weiznich](https://redirect.github.com/weiznich)]\[gh-weiznich]). - Removed the `once_cell` crate from the dependencies (\[[#​520](https://redirect.github.com/moka-rs/moka/issues/520)]\[gh-pull-0520], by \[[@​Expyron](https://redirect.github.com/Expyron)]\[gh-Expyron]). - Removed the `rustc_version` crate from the dev-dependencies (\[[#​554](https://redirect.github.com/moka-rs/moka/issues/554)]\[gh-pull-0554]).
seanmonstar/reqwest (reqwest) ### [`v0.12.26`](https://redirect.github.com/seanmonstar/reqwest/blob/HEAD/CHANGELOG.md#v01226) [Compare Source](https://redirect.github.com/seanmonstar/reqwest/compare/v0.12.25...v0.12.26) - Fix sending `Accept-Encoding` header only with values configured with reqwest, regardless of underlying tower-http config.
RoaringBitmap/roaring-rs (roaring) ### [`v0.11.3`](https://redirect.github.com/RoaringBitmap/roaring-rs/releases/tag/v0.11.3) [Compare Source](https://redirect.github.com/RoaringBitmap/roaring-rs/compare/v0.11.2...v0.11.3) #### What's Changed - fix: bitmap advance\_back\_to could violate invariants by [@​Dr-Emann](https://redirect.github.com/Dr-Emann) in [#​339](https://redirect.github.com/RoaringBitmap/roaring-rs/pull/339) - Introduce Iter::next\_range and next\_range\_back by [@​Dr-Emann](https://redirect.github.com/Dr-Emann) in [#​338](https://redirect.github.com/RoaringBitmap/roaring-rs/pull/338) - Bump version to v0.11.3 and MSRV to 1.82 by [@​Kerollmops](https://redirect.github.com/Kerollmops) in [#​342](https://redirect.github.com/RoaringBitmap/roaring-rs/pull/342) **Full Changelog**:
bytecodealliance/target-lexicon (target-lexicon) ### [`v0.13.4`](https://redirect.github.com/bytecodealliance/target-lexicon/compare/v0.13.3...v0.13.4) [Compare Source](https://redirect.github.com/bytecodealliance/target-lexicon/compare/v0.13.3...v0.13.4)
--- ### Configuration πŸ“… **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ‘» **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/vortex-data/vortex). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: amorynan --- Cargo.lock | 47 +++++++++++++++++++++---------------------- java/build.gradle.kts | 2 +- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 950ef248737..78879a0243d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1015,7 +1015,7 @@ dependencies = [ "bitflags", "cexpr", "clang-sys", - "itertools 0.12.1", + "itertools 0.13.0", "log", "prettyplease", "proc-macro2", @@ -1269,9 +1269,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -1415,7 +1415,7 @@ checksum = "af491d569909a7e4dee0ad7db7f5341fef5c614d5b8ec8cf765732aba3cff681" dependencies = [ "serde", "termcolor", - "unicode-width 0.1.14", + "unicode-width 0.2.0", ] [[package]] @@ -1879,9 +1879,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd46505a9588ea42961c833d8e20a8956741f26f4aa84f5248a60c2137bf0373" +checksum = "bbda285ba6e5866529faf76352bdf73801d9b44a6308d7cd58ca2379f378e994" dependencies = [ "cc", "cxx-build", @@ -1894,9 +1894,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b78549cfae183ba0391f186544fdf1f5d96e9d3cf2683ee1449a3aea066e4e32" +checksum = "af9efde466c5d532d57efd92f861da3bdb7f61e369128ce8b4c3fe0c9de4fa4d" dependencies = [ "cc", "codespan-reporting", @@ -1909,9 +1909,9 @@ dependencies = [ [[package]] name = "cxxbridge-cmd" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5f593aa804e4cd4fda75ca4c56820c15a27ac667f02bffe626c2ed16e2d747d" +checksum = "3efb93799095bccd4f763ca07997dc39a69e5e61ab52d2c407d4988d21ce144d" dependencies = [ "clap", "codespan-reporting", @@ -1923,15 +1923,15 @@ dependencies = [ [[package]] name = "cxxbridge-flags" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5e77806f6ca008fe3cb35ac747db8f5cf30c038b81ae97077a6aecd7ca01a31" +checksum = "3092010228026e143b32a4463ed9fa8f86dca266af4bf5f3b2a26e113dbe4e45" [[package]] name = "cxxbridge-macro" -version = "1.0.191" +version = "1.0.192" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e751ebe2dee4a88a26df4f11c2baf6aa1e7f652af9a3bef5b4db5ae33397577d" +checksum = "31d72ebfcd351ae404fb00ff378dfc9571827a00722c9e735c9181aec320ba0a" dependencies = [ "indexmap", "proc-macro2", @@ -4957,9 +4957,9 @@ checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" [[package]] name = "moka" -version = "0.12.11" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" +checksum = "a3dec6bd31b08944e08b58fd99373893a6c17054d6f3ea5006cc894f4f4eee2a" dependencies = [ "async-lock", "crossbeam-channel", @@ -4970,7 +4970,6 @@ dependencies = [ "futures-util", "parking_lot", "portable-atomic", - "rustc_version", "smallvec", "tagptr", "uuid", @@ -6530,9 +6529,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.25" +version = "0.12.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6eff9328d40131d43bd911d42d79eb6a47312002a4daefc9e37f17e74a7701a" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" dependencies = [ "base64", "bytes", @@ -6601,9 +6600,9 @@ dependencies = [ [[package]] name = "roaring" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f08d6a905edb32d74a5d5737a0c9d7e950c312f3c46cb0ca0a2ca09ea11878a0" +checksum = "8ba9ce64a8f45d7fc86358410bb1a82e8c987504c0d4900e9141d69a9f26c885" dependencies = [ "bytemuck", "byteorder", @@ -7609,9 +7608,9 @@ checksum = "c1bbb9f3c5c463a01705937a24fdabc5047929ac764b2d5b9cf681c1f5041ed5" [[package]] name = "target-lexicon" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df7f62577c25e07834649fc3b39fafdc597c0a3527dc1c60129201ccfcbaa50c" +checksum = "b1dd07eb858a2067e2f3c7155d54e929265c264e6f37efe3ee7a8d1b5a1dd0ba" [[package]] name = "tempfile" @@ -9048,7 +9047,7 @@ dependencies = [ "futures", "itertools 0.14.0", "parking_lot", - "roaring 0.11.2", + "roaring 0.11.3", "sketches-ddsketch", "tracing", "vortex-array", diff --git a/java/build.gradle.kts b/java/build.gradle.kts index 8c202d122a4..fdfe1f2d8ac 100644 --- a/java/build.gradle.kts +++ b/java/build.gradle.kts @@ -8,7 +8,7 @@ plugins { id("com.palantir.consistent-versions") version "3.7.0" id("com.palantir.git-version") version "4.2.0" id("net.ltgt.errorprone") version "4.3.0" apply false - id("com.google.protobuf") version "0.9.5" apply false + id("com.google.protobuf") version "0.9.6" apply false id("com.vanniktech.maven.publish") version "0.35.0" apply false } From 8fd7b5d964ee08e2618a987b4954195165bbb6aa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 23 Dec 2025 12:12:57 +0000 Subject: [PATCH 3/8] Update CodSpeedHQ/action digest to 972e343 (#5808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | CodSpeedHQ/action | action | digest | `346a2d8` -> `972e343` | --- ### Configuration πŸ“… **Schedule**: Branch creation - Between 12:00 AM and 03:59 AM, only on Monday ( * 0-3 * * 1 ) (UTC), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. β™» **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. πŸ”• **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/vortex-data/vortex). Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Signed-off-by: amorynan --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3b45cf2f317..fbbf0dcb19e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -595,7 +595,7 @@ jobs: RUSTFLAGS: "-C target-feature=+avx2 -C debug-assertions=yes" run: cargo codspeed build ${{ matrix.features }} $(printf -- '-p %s ' ${{ matrix.packages }}) --profile bench - name: Run benchmarks - uses: CodSpeedHQ/action@346a2d8a8d9d38909abd0bc3d23f773110f076ad + uses: CodSpeedHQ/action@972e3437949c89e1357ebd1a2dbc852fcbc57245 with: run: cargo codspeed run token: ${{ secrets.CODSPEED_TOKEN }} From d53e6e8cd2341a1862a91f86a77c9d35c2ba97f2 Mon Sep 17 00:00:00 2001 From: Adam Gutglick Date: Tue, 23 Dec 2025 12:54:07 +0000 Subject: [PATCH 4/8] Cleanup unused dependencies and dead file (#5787) Signed-off-by: Adam Gutglick Signed-off-by: amorynan --- Cargo.lock | 11 - encodings/bytebool/Cargo.toml | 1 - encodings/decimal-byte-parts/Cargo.toml | 1 - encodings/fastlanes/Cargo.toml | 1 - encodings/fsst/Cargo.toml | 1 - encodings/sequence/Cargo.toml | 3 - vortex-btrblocks/Cargo.toml | 2 - vortex-buffer/Cargo.toml | 2 +- vortex-compute/Cargo.toml | 1 - vortex-flatbuffers/src/generated/scalar.rs | 300 --------------------- vortex-io/Cargo.toml | 1 - vortex/Cargo.toml | 4 +- 12 files changed, 3 insertions(+), 325 deletions(-) delete mode 100644 vortex-flatbuffers/src/generated/scalar.rs diff --git a/Cargo.lock b/Cargo.lock index 78879a0243d..88578879a6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8430,12 +8430,10 @@ name = "vortex-btrblocks" version = "0.1.0" dependencies = [ "codspeed-divan-compat", - "env_logger", "getrandom 0.3.4", "itertools 0.14.0", "num-traits", "rand 0.9.2", - "rstest", "rustc-hash", "tracing", "vortex-alp", @@ -8479,7 +8477,6 @@ dependencies = [ name = "vortex-bytebool" version = "0.1.0" dependencies = [ - "itertools 0.14.0", "num-traits", "rstest", "vortex-array", @@ -8500,7 +8497,6 @@ dependencies = [ "codspeed-divan-compat", "half", "itertools 0.14.0", - "log", "multiversion", "num-traits", "paste", @@ -8584,7 +8580,6 @@ dependencies = [ name = "vortex-decimal-byte-parts" version = "0.1.0" dependencies = [ - "itertools 0.14.0", "num-traits", "prost 0.14.1", "rstest", @@ -8683,7 +8678,6 @@ dependencies = [ "fastlanes", "itertools 0.14.0", "lending-iterator", - "mimalloc", "num-traits", "prost 0.14.1", "rand 0.9.2", @@ -8776,7 +8770,6 @@ version = "0.1.0" dependencies = [ "codspeed-divan-compat", "fsst-rs", - "itertools 0.14.0", "num-traits", "prost 0.14.1", "rand 0.9.2", @@ -8837,7 +8830,6 @@ dependencies = [ "tempfile", "tokio", "tracing", - "tracing-subscriber", "vortex-buffer", "vortex-error", "vortex-metrics", @@ -9069,13 +9061,10 @@ dependencies = [ "num-traits", "prost 0.14.1", "rstest", - "tokio", "vortex-array", "vortex-buffer", "vortex-dtype", "vortex-error", - "vortex-file", - "vortex-layout", "vortex-mask", "vortex-proto", "vortex-scalar", diff --git a/encodings/bytebool/Cargo.toml b/encodings/bytebool/Cargo.toml index 7e7117b687a..682b40235c7 100644 --- a/encodings/bytebool/Cargo.toml +++ b/encodings/bytebool/Cargo.toml @@ -26,6 +26,5 @@ vortex-mask = { workspace = true } vortex-scalar = { workspace = true } [dev-dependencies] -itertools = { workspace = true } rstest = { workspace = true } vortex-array = { workspace = true, features = ["test-harness"] } diff --git a/encodings/decimal-byte-parts/Cargo.toml b/encodings/decimal-byte-parts/Cargo.toml index 79d6f87711b..cb79a92ede9 100644 --- a/encodings/decimal-byte-parts/Cargo.toml +++ b/encodings/decimal-byte-parts/Cargo.toml @@ -27,6 +27,5 @@ vortex-mask = { workspace = true } vortex-scalar = { workspace = true } [dev-dependencies] -itertools = { workspace = true } rstest = { workspace = true } vortex-array = { path = "../../vortex-array", features = ["test-harness"] } diff --git a/encodings/fastlanes/Cargo.toml b/encodings/fastlanes/Cargo.toml index 81a2e00b8e8..7b0024db94b 100644 --- a/encodings/fastlanes/Cargo.toml +++ b/encodings/fastlanes/Cargo.toml @@ -37,7 +37,6 @@ vortex-vector = { workspace = true } [dev-dependencies] divan = { workspace = true } itertools = { workspace = true } -mimalloc = { workspace = true } rand = { workspace = true } rstest = { workspace = true } vortex-alp = { path = "../alp" } diff --git a/encodings/fsst/Cargo.toml b/encodings/fsst/Cargo.toml index 00b0e9d182b..cff277e89a2 100644 --- a/encodings/fsst/Cargo.toml +++ b/encodings/fsst/Cargo.toml @@ -34,7 +34,6 @@ test-harness = ["dep:rand", "vortex-array/test-harness"] [dev-dependencies] divan = { workspace = true } -itertools = { workspace = true } rand = { workspace = true } rstest = { workspace = true } vortex-array = { workspace = true, features = ["test-harness"] } diff --git a/encodings/sequence/Cargo.toml b/encodings/sequence/Cargo.toml index c3ebfeef598..143f5805ab8 100644 --- a/encodings/sequence/Cargo.toml +++ b/encodings/sequence/Cargo.toml @@ -28,10 +28,7 @@ vortex-vector = { workspace = true } [dev-dependencies] itertools = { workspace = true } rstest = { workspace = true } -tokio = { workspace = true, features = ["full"] } vortex-array = { path = "../../vortex-array", features = ["test-harness"] } -vortex-file = { path = "../../vortex-file", features = ["tokio"] } -vortex-layout = { path = "../../vortex-layout" } [lints] workspace = true diff --git a/vortex-btrblocks/Cargo.toml b/vortex-btrblocks/Cargo.toml index 7ad94f3c551..f1a3feb0af4 100644 --- a/vortex-btrblocks/Cargo.toml +++ b/vortex-btrblocks/Cargo.toml @@ -39,8 +39,6 @@ vortex-zigzag = { workspace = true } [dev-dependencies] divan = { workspace = true } -env_logger = "0.11" -rstest = { workspace = true } vortex-array = { workspace = true, features = ["test-harness"] } [features] diff --git a/vortex-buffer/Cargo.toml b/vortex-buffer/Cargo.toml index e4a65fc6c85..cf13a40c069 100644 --- a/vortex-buffer/Cargo.toml +++ b/vortex-buffer/Cargo.toml @@ -28,7 +28,6 @@ bitvec = { workspace = true } bytes = { workspace = true } itertools = { workspace = true } memmap2 = { workspace = true, optional = true } -num-traits = { workspace = true } serde = { workspace = true, optional = true } simdutf8 = { workspace = true } tracing = { workspace = true, optional = true } @@ -43,6 +42,7 @@ workspace = true [dev-dependencies] arrow-buffer = { workspace = true } divan = { workspace = true } +num-traits = { workspace = true } rstest = { workspace = true } [[bench]] diff --git a/vortex-compute/Cargo.toml b/vortex-compute/Cargo.toml index bad907c6aa9..dc70db6ee45 100644 --- a/vortex-compute/Cargo.toml +++ b/vortex-compute/Cargo.toml @@ -32,7 +32,6 @@ vortex-vector = { workspace = true } half = { workspace = true } itertools = { workspace = true } -log = { workspace = true } multiversion = { workspace = true } num-traits = { workspace = true } paste = { workspace = true } diff --git a/vortex-flatbuffers/src/generated/scalar.rs b/vortex-flatbuffers/src/generated/scalar.rs deleted file mode 100644 index 57658a85f49..00000000000 --- a/vortex-flatbuffers/src/generated/scalar.rs +++ /dev/null @@ -1,300 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: Copyright the Vortex contributors - -// automatically generated by the FlatBuffers compiler, do not modify - - -// @generated - -use crate::dtype::*; -use core::mem; -use core::cmp::Ordering; - -extern crate flatbuffers; -use self::flatbuffers::{EndianScalar, Follow}; - -pub enum ScalarOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct Scalar<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for Scalar<'a> { - type Inner = Scalar<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> Scalar<'a> { - pub const VT_DTYPE: flatbuffers::VOffsetT = 4; - pub const VT_VALUE: flatbuffers::VOffsetT = 6; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - Scalar { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args ScalarArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = ScalarBuilder::new(_fbb); - if let Some(x) = args.value { builder.add_value(x); } - if let Some(x) = args.dtype { builder.add_dtype(x); } - builder.finish() - } - - - #[inline] - pub fn dtype(&self) -> DType<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(Scalar::VT_DTYPE, None).unwrap()} - } - #[inline] - pub fn value(&self) -> ScalarValue<'a> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>(Scalar::VT_VALUE, None).unwrap()} - } -} - -impl flatbuffers::Verifiable for Scalar<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>("dtype", Self::VT_DTYPE, true)? - .visit_field::>("value", Self::VT_VALUE, true)? - .finish(); - Ok(()) - } -} -pub struct ScalarArgs<'a> { - pub dtype: Option>>, - pub value: Option>>, -} -impl<'a> Default for ScalarArgs<'a> { - #[inline] - fn default() -> Self { - ScalarArgs { - dtype: None, // required field - value: None, // required field - } - } -} - -pub struct ScalarBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ScalarBuilder<'a, 'b, A> { - #[inline] - pub fn add_dtype(&mut self, dtype: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(Scalar::VT_DTYPE, dtype); - } - #[inline] - pub fn add_value(&mut self, value: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(Scalar::VT_VALUE, value); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ScalarBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - ScalarBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - self.fbb_.required(o, Scalar::VT_DTYPE,"dtype"); - self.fbb_.required(o, Scalar::VT_VALUE,"value"); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for Scalar<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("Scalar"); - ds.field("dtype", &self.dtype()); - ds.field("value", &self.value()); - ds.finish() - } -} -pub enum ScalarValueOffset {} -#[derive(Copy, Clone, PartialEq)] - -pub struct ScalarValue<'a> { - pub _tab: flatbuffers::Table<'a>, -} - -impl<'a> flatbuffers::Follow<'a> for ScalarValue<'a> { - type Inner = ScalarValue<'a>; - #[inline] - unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner { - Self { _tab: flatbuffers::Table::new(buf, loc) } - } -} - -impl<'a> ScalarValue<'a> { - pub const VT_FLEX: flatbuffers::VOffsetT = 4; - - #[inline] - pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self { - ScalarValue { _tab: table } - } - #[allow(unused_mut)] - pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr, A: flatbuffers::Allocator + 'bldr>( - _fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr, A>, - args: &'args ScalarValueArgs<'args> - ) -> flatbuffers::WIPOffset> { - let mut builder = ScalarValueBuilder::new(_fbb); - if let Some(x) = args.flex { builder.add_flex(x); } - builder.finish() - } - - - #[inline] - pub fn flex(&self) -> flatbuffers::Vector<'a, u8> { - // Safety: - // Created from valid Table for this object - // which contains a valid value in this slot - unsafe { self._tab.get::>>(ScalarValue::VT_FLEX, None).unwrap()} - } -} - -impl flatbuffers::Verifiable for ScalarValue<'_> { - #[inline] - fn run_verifier( - v: &mut flatbuffers::Verifier, pos: usize - ) -> Result<(), flatbuffers::InvalidFlatbuffer> { - use self::flatbuffers::Verifiable; - v.visit_table(pos)? - .visit_field::>>("flex", Self::VT_FLEX, true)? - .finish(); - Ok(()) - } -} -pub struct ScalarValueArgs<'a> { - pub flex: Option>>, -} -impl<'a> Default for ScalarValueArgs<'a> { - #[inline] - fn default() -> Self { - ScalarValueArgs { - flex: None, // required field - } - } -} - -pub struct ScalarValueBuilder<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> { - fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - start_: flatbuffers::WIPOffset, -} -impl<'a: 'b, 'b, A: flatbuffers::Allocator + 'a> ScalarValueBuilder<'a, 'b, A> { - #[inline] - pub fn add_flex(&mut self, flex: flatbuffers::WIPOffset>) { - self.fbb_.push_slot_always::>(ScalarValue::VT_FLEX, flex); - } - #[inline] - pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>) -> ScalarValueBuilder<'a, 'b, A> { - let start = _fbb.start_table(); - ScalarValueBuilder { - fbb_: _fbb, - start_: start, - } - } - #[inline] - pub fn finish(self) -> flatbuffers::WIPOffset> { - let o = self.fbb_.end_table(self.start_); - self.fbb_.required(o, ScalarValue::VT_FLEX,"flex"); - flatbuffers::WIPOffset::new(o.value()) - } -} - -impl core::fmt::Debug for ScalarValue<'_> { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let mut ds = f.debug_struct("ScalarValue"); - ds.field("flex", &self.flex()); - ds.finish() - } -} -#[inline] -/// Verifies that a buffer of bytes contains a `Scalar` -/// and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_scalar_unchecked`. -pub fn root_as_scalar(buf: &[u8]) -> Result { - flatbuffers::root::(buf) -} -#[inline] -/// Verifies that a buffer of bytes contains a size prefixed -/// `Scalar` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `size_prefixed_root_as_scalar_unchecked`. -pub fn size_prefixed_root_as_scalar(buf: &[u8]) -> Result { - flatbuffers::size_prefixed_root::(buf) -} -#[inline] -/// Verifies, with the given options, that a buffer of bytes -/// contains a `Scalar` and returns it. -/// Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_scalar_unchecked`. -pub fn root_as_scalar_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::root_with_opts::>(opts, buf) -} -#[inline] -/// Verifies, with the given verifier options, that a buffer of -/// bytes contains a size prefixed `Scalar` and returns -/// it. Note that verification is still experimental and may not -/// catch every error, or be maximally performant. For the -/// previous, unchecked, behavior use -/// `root_as_scalar_unchecked`. -pub fn size_prefixed_root_as_scalar_with_opts<'b, 'o>( - opts: &'o flatbuffers::VerifierOptions, - buf: &'b [u8], -) -> Result, flatbuffers::InvalidFlatbuffer> { - flatbuffers::size_prefixed_root_with_opts::>(opts, buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a Scalar and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid `Scalar`. -pub unsafe fn root_as_scalar_unchecked(buf: &[u8]) -> Scalar { - flatbuffers::root_unchecked::(buf) -} -#[inline] -/// Assumes, without verification, that a buffer of bytes contains a size prefixed Scalar and returns it. -/// # Safety -/// Callers must trust the given bytes do indeed contain a valid size prefixed `Scalar`. -pub unsafe fn size_prefixed_root_as_scalar_unchecked(buf: &[u8]) -> Scalar { - flatbuffers::size_prefixed_root_unchecked::(buf) -} -#[inline] -pub fn finish_scalar_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>( - fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, - root: flatbuffers::WIPOffset>) { - fbb.finish(root, None); -} - -#[inline] -pub fn finish_size_prefixed_scalar_buffer<'a, 'b, A: flatbuffers::Allocator + 'a>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a, A>, root: flatbuffers::WIPOffset>) { - fbb.finish_size_prefixed(root, None); -} diff --git a/vortex-io/Cargo.toml b/vortex-io/Cargo.toml index 4e0f57be89d..cef1c69e351 100644 --- a/vortex-io/Cargo.toml +++ b/vortex-io/Cargo.toml @@ -52,7 +52,6 @@ itertools = { workspace = true } rstest = { workspace = true } tempfile = { workspace = true } tokio = { workspace = true, features = ["full"] } -tracing-subscriber = { workspace = true } [features] object_store = ["dep:object_store", "vortex-error/object_store"] diff --git a/vortex/Cargo.toml b/vortex/Cargo.toml index f31bbda02e2..31f6daf0932 100644 --- a/vortex/Cargo.toml +++ b/vortex/Cargo.toml @@ -20,8 +20,6 @@ all-features = true workspace = true [dependencies] -fastlanes = { workspace = true } -rand = { workspace = true } vortex-alp = { workspace = true } vortex-array = { workspace = true } vortex-btrblocks = { workspace = true } @@ -58,9 +56,11 @@ vortex-zstd = { workspace = true, optional = true } anyhow = { workspace = true } arrow-array = { workspace = true } divan = { workspace = true } +fastlanes = { workspace = true } itertools = { workspace = true } mimalloc = { workspace = true } parquet = { workspace = true } +rand = { workspace = true } serde_json = { workspace = true } tokio = { workspace = true, features = ["full"] } tracing = { workspace = true } From 19a47985d5b207433ca8f68ac0d5c415776c2bbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Subiotto=20Marqu=C3=A9s?= Date: Tue, 23 Dec 2025 14:06:34 +0100 Subject: [PATCH 5/8] performance[vortex-array]: don't call is_valid to count bytes in varbinview (#5814) I noticed that the better blocks compressor uses count_referenced_bytes which calls is_valid on each view and results in an expensive scalar_at call. This was 30% of our system-wide CPU usage over 12 hours (see PR for attached screenshot). This commit iterates over the nullability mask directly to avoid these expensive calls. image Signed-off-by: Alfonso Subiotto Marques Signed-off-by: amorynan --- vortex-array/src/arrays/varbinview/compact.rs | 96 +++++++++++++------ 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/vortex-array/src/arrays/varbinview/compact.rs b/vortex-array/src/arrays/varbinview/compact.rs index 9df4dea11a6..033bdf6082c 100644 --- a/vortex-array/src/arrays/varbinview/compact.rs +++ b/vortex-array/src/arrays/varbinview/compact.rs @@ -8,12 +8,12 @@ use std::ops::Range; use vortex_error::VortexExpect; use vortex_error::VortexResult; +use vortex_mask::Mask; +use vortex_vector::binaryview::Ref; use crate::arrays::VarBinViewArray; use crate::builders::ArrayBuilder; use crate::builders::VarBinViewBuilder; -use crate::validity::Validity; -use crate::vtable::ValidityHelper; impl VarBinViewArray { /// Returns a compacted copy of the input array, where all wasted space has been cleaned up. This @@ -55,28 +55,42 @@ impl VarBinViewArray { bytes_referenced < buffer_total_bytes || buffer_total_bytes == 0 } - // count the number of bytes addressed by the views, not including null - // values or any inlined strings. - fn count_referenced_bytes(&self) -> u64 { - match self.validity() { - Validity::AllInvalid => 0u64, - Validity::NonNullable | Validity::AllValid | Validity::Array(_) => self - .views() - .iter() - .enumerate() - .map(|(idx, &view)| { - if !self.is_valid(idx) || view.is_inlined() { - 0u64 - } else { - view.len() as u64 + /// Iterates over all valid, non-inlined views, calling the provided + /// closure for each one. + #[inline(always)] + fn iter_valid_views(&self, mut f: F) + where + F: FnMut(&Ref), + { + match self.validity_mask() { + Mask::AllTrue(_) => { + for &view in self.views().iter() { + if !view.is_inlined() { + f(view.as_view()); + } + } + } + Mask::AllFalse(_) => {} + Mask::Values(v) => { + for (&view, is_valid) in self.views().iter().zip(v.bit_buffer().iter()) { + if is_valid && !view.is_inlined() { + f(view.as_view()); } - }) - .sum(), + } + } } } + /// Count the number of bytes addressed by the views, not including null + /// values or any inlined strings. + fn count_referenced_bytes(&self) -> u64 { + let mut total = 0u64; + self.iter_valid_views(|view| total += view.size as u64); + total + } + pub(crate) fn buffer_utilizations(&self) -> Vec { - let mut utilizations = self + let mut utilizations: Vec = self .buffers() .iter() .map(|buf| { @@ -85,18 +99,9 @@ impl VarBinViewArray { }) .collect(); - if matches!(self.validity(), Validity::AllInvalid) { - return utilizations; - } - - for (idx, &view) in self.views().iter().enumerate() { - if !self.is_valid(idx) || view.is_inlined() { - continue; - } - let view = view.as_view(); - - utilizations[view.buffer_index as usize].add(view.offset, view.size) - } + self.iter_valid_views(|view| { + utilizations[view.buffer_index as usize].add(view.offset, view.size); + }); utilizations } @@ -177,6 +182,7 @@ impl BufferUtilization { #[cfg(test)] mod tests { + use rstest::rstest; use vortex_buffer::buffer; use crate::IntoArray; @@ -433,4 +439,32 @@ mod tests { ); } } + + const LONG1: &str = "long string one!"; + const LONG2: &str = "long string two!"; + const SHORT: &str = "x"; + const EXPECTED_BYTES: u64 = (LONG1.len() + LONG2.len()) as u64; + + fn mixed_array() -> VarBinViewArray { + VarBinViewArray::from_iter_nullable_str([Some(LONG1), None, Some(LONG2), Some(SHORT)]) + } + + #[rstest] + #[case::non_nullable(VarBinViewArray::from_iter_str([LONG1, LONG2, SHORT]), EXPECTED_BYTES, &[1.0])] + #[case::all_valid(VarBinViewArray::from_iter_nullable_str([Some(LONG1), Some(LONG2), Some(SHORT)]), EXPECTED_BYTES, &[1.0])] + #[case::all_invalid(VarBinViewArray::from_iter_nullable_str([None::<&str>, None]), 0, &[])] + #[case::mixed_validity(mixed_array(), EXPECTED_BYTES, &[1.0])] + fn test_validity_code_paths( + #[case] arr: VarBinViewArray, + #[case] expected_bytes: u64, + #[case] expected_utils: &[f64], + ) { + assert_eq!(arr.count_referenced_bytes(), expected_bytes); + let utils: Vec = arr + .buffer_utilizations() + .iter() + .map(|u| u.overall_utilization()) + .collect(); + assert_eq!(utils, expected_utils); + } } From 497815022688dca9747ac9b4d5f6102b5f51e80f Mon Sep 17 00:00:00 2001 From: Pratham Agarwal <32198580+Pratham1812@users.noreply.github.com> Date: Wed, 24 Dec 2025 00:01:03 +0530 Subject: [PATCH 6/8] Removes vortex_unwrap completely in favor of vortex_expect (#5805) This change removes all the instances of `vortex_unwrap` and replaces them with `vortex_expect` essentially compelling the user to provide a justification of failure. Signed-off-by: Pratham Agarwal Signed-off-by: amorynan --- STYLE.md | 2 +- encodings/alp/src/alp_rd/mod.rs | 9 +-- encodings/fsst/src/compress.rs | 7 +- encodings/fsst/src/test_utils.rs | 5 +- encodings/pco/src/array.rs | 11 +-- encodings/runend/src/compute/filter.rs | 7 +- encodings/sparse/src/lib.rs | 4 +- fuzz/fuzz_targets/file_io.rs | 20 +++--- fuzz/src/array/fill_null.rs | 9 +-- fuzz/src/array/mask.rs | 8 +-- fuzz/src/array/mod.rs | 70 +++++++++++------- fuzz/src/array/scalar_at.rs | 17 +++-- vortex-array/benches/varbinview_compact.rs | 21 +++--- vortex-array/src/arrays/arbitrary.rs | 5 +- vortex-array/src/arrays/chunked/array.rs | 5 +- .../src/arrays/chunked/compute/filter.rs | 5 +- .../src/arrays/constant/compute/sum.rs | 8 +-- .../src/arrays/decimal/compute/sum.rs | 4 +- vortex-array/src/arrays/dict/array.rs | 8 +-- .../src/arrays/dict/compute/fill_null.rs | 6 +- vortex-array/src/arrays/dict_test.rs | 4 +- vortex-array/src/arrays/list/tests.rs | 12 ++-- .../src/arrays/primitive/compute/is_sorted.rs | 9 ++- .../src/arrays/struct_/compute/mod.rs | 5 +- vortex-array/src/arrays/varbin/mod.rs | 4 +- vortex-array/src/builders/decimal.rs | 3 +- vortex-array/src/builders/dict/bytes.rs | 4 +- .../src/compute/conformance/binary_numeric.rs | 12 ++-- vortex-array/src/compute/conformance/cast.rs | 20 +++--- .../src/compute/conformance/consistency.rs | 72 +++++++++++-------- .../src/compute/conformance/filter.rs | 32 +++++---- vortex-array/src/compute/conformance/mask.rs | 21 +++--- vortex-array/src/compute/conformance/take.rs | 41 +++++++---- vortex-array/src/compute/sum.rs | 4 +- vortex-array/src/expr/exprs/cast.rs | 5 +- vortex-array/src/expr/exprs/is_null.rs | 5 +- vortex-array/src/expr/mod.rs | 5 +- vortex-bench/src/lib.rs | 6 +- vortex-bench/src/measurements.rs | 14 ++-- vortex-btrblocks/src/float/stats.rs | 6 +- vortex-btrblocks/src/integer.rs | 9 ++- vortex-btrblocks/src/integer/stats.rs | 13 ++-- vortex-btrblocks/src/lib.rs | 12 +++- vortex-dtype/src/struct_.rs | 20 ++++-- vortex-duckdb/src/convert/vector.rs | 17 ++--- vortex-duckdb/src/duckdb/logical_type.rs | 3 +- vortex-duckdb/src/duckdb/object_cache.rs | 6 +- vortex-duckdb/src/duckdb/scalar_function.rs | 4 +- vortex-duckdb/src/duckdb/vector.rs | 4 +- vortex-duckdb/src/exporter/decimal.rs | 11 +-- vortex-duckdb/src/exporter/list.rs | 8 ++- vortex-duckdb/src/exporter/list_view.rs | 11 +-- vortex-duckdb/src/exporter/struct_.rs | 13 ++-- vortex-error/src/lib.rs | 23 ------ vortex-ffi/src/string.rs | 6 +- vortex-gpu/benches/gpu_bitunpack.rs | 8 +-- vortex-gpu/src/bit_unpack.rs | 10 +-- vortex-gpu/src/for_.rs | 6 +- vortex-gpu/src/for_bp.rs | 6 +- vortex-gpu/src/jit/arrays/bitpack.rs | 4 +- vortex-gpu/src/rle_decompress.rs | 4 +- vortex-io/src/limit.rs | 6 +- vortex-layout/src/gpu/layouts/flat/reader.rs | 5 +- vortex-layout/src/layouts/flat/reader.rs | 4 +- vortex-layout/src/layouts/flat/writer.rs | 4 +- vortex-layout/src/layouts/zoned/zone_map.rs | 10 +-- vortex-scalar/src/binary.rs | 13 ++-- vortex-scalar/src/scalar_value.rs | 4 +- vortex-scalar/src/utf8.rs | 13 ++-- vortex-tui/src/browse/app.rs | 6 +- vortex-tui/src/browse/ui/segments.rs | 8 +-- vortex-vector/src/binaryview/view.rs | 10 +-- 72 files changed, 451 insertions(+), 345 deletions(-) diff --git a/STYLE.md b/STYLE.md index 3d44e6ba397..67f331220e7 100644 --- a/STYLE.md +++ b/STYLE.md @@ -54,7 +54,7 @@ - `vortex_panic!` for handling invariant violations - Add context to errors using `.with_context()` - Include backtraces for better debugging -- Use `VortexExpect` and `VortexUnwrap` traits when unwrapping is appropriate +- Use `VortexExpect` trait when unwrapping is appropriate with proper error context. ## Code Structure diff --git a/encodings/alp/src/alp_rd/mod.rs b/encodings/alp/src/alp_rd/mod.rs index 6cc781aa45f..be4a8f349cd 100644 --- a/encodings/alp/src/alp_rd/mod.rs +++ b/encodings/alp/src/alp_rd/mod.rs @@ -31,7 +31,6 @@ use vortex_dtype::DType; use vortex_dtype::NativePType; use vortex_dtype::match_each_integer_ptype; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_utils::aliases::hash_map::HashMap; @@ -229,7 +228,7 @@ impl RDEncoder { // SAFETY: by construction, all values in left_parts can be packed to left_bit_width. let packed_left = unsafe { bitpack_encode_unchecked(primitive_left, left_bit_width as _) - .vortex_unwrap() + .vortex_expect("bitpack_encode_unchecked should succeed for left parts") .into_array() }; @@ -237,7 +236,7 @@ impl RDEncoder { // SAFETY: by construction, all values in right_parts are right_bit_width + leading zeros. let packed_right = unsafe { bitpack_encode_unchecked(primitive_right, self.right_bit_width as _) - .vortex_unwrap() + .vortex_expect("bitpack_encode_unchecked should succeed for right parts") .into_array() }; @@ -252,7 +251,9 @@ impl RDEncoder { // SAFETY: We calculate bw such that it is wide enough to hold the largest position index. let packed_pos = unsafe { bitpack_encode_unchecked(exc_pos_array, bw) - .vortex_unwrap() + .vortex_expect( + "bitpack_encode_unchecked should succeed for exception positions", + ) .into_array() }; diff --git a/encodings/fsst/src/compress.rs b/encodings/fsst/src/compress.rs index 98a1c260723..6b958f9fdb3 100644 --- a/encodings/fsst/src/compress.rs +++ b/encodings/fsst/src/compress.rs @@ -13,7 +13,6 @@ use vortex_buffer::Buffer; use vortex_buffer::BufferMut; use vortex_dtype::DType; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use crate::FSSTArray; @@ -74,7 +73,11 @@ where uncompressed_lengths.push(0); } Some(s) => { - uncompressed_lengths.push(s.len().try_into().vortex_unwrap()); + uncompressed_lengths.push( + s.len() + .try_into() + .vortex_expect("string length must fit in i32"), + ); // SAFETY: buffer is large enough unsafe { compressor.compress_into(s, &mut buffer) }; diff --git a/encodings/fsst/src/test_utils.rs b/encodings/fsst/src/test_utils.rs index 457f202efe3..40cfb0b3133 100644 --- a/encodings/fsst/src/test_utils.rs +++ b/encodings/fsst/src/test_utils.rs @@ -14,7 +14,7 @@ use vortex_array::arrays::VarBinArray; use vortex_dtype::DType; use vortex_dtype::NativePType; use vortex_dtype::Nullability; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use crate::fsst_compress; use crate::fsst_train_compressor; @@ -56,5 +56,6 @@ pub fn gen_dict_fsst_test_data( let codes = (0..len) .map(|_| T::from(rng.random_range(0..unique_values)).unwrap()) .collect::(); - DictArray::try_new(codes.into_array(), values).vortex_unwrap() + DictArray::try_new(codes.into_array(), values) + .vortex_expect("DictArray::try_new should succeed for test data") } diff --git a/encodings/pco/src/array.rs b/encodings/pco/src/array.rs index 2c5478fedf0..71c2d4855e8 100644 --- a/encodings/pco/src/array.rs +++ b/encodings/pco/src/array.rs @@ -57,7 +57,6 @@ use vortex_dtype::half; use vortex_error::VortexError; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_bail; use vortex_error::vortex_ensure; use vortex_error::vortex_err; @@ -377,7 +376,7 @@ impl PcoArray { // may exceed the bounds of the slice, so we need to slice later. let (fd, _) = FileDecompressor::new(self.metadata.header.as_slice()) .map_err(vortex_err_from_pco) - .vortex_unwrap(); + .vortex_expect("FileDecompressor::new should succeed with valid header"); let mut decompressed_values = BufferMut::::with_capacity(slice_n_values); let mut page_idx = 0; let mut page_value_start = 0; @@ -406,7 +405,9 @@ impl PcoArray { let (new_cd, _) = fd .chunk_decompressor(chunk_meta_bytes) .map_err(vortex_err_from_pco) - .vortex_unwrap(); + .vortex_expect( + "chunk_decompressor should succeed with valid chunk metadata", + ); cd = Some(new_cd); } let mut pd = cd @@ -414,10 +415,10 @@ impl PcoArray { .unwrap() .page_decompressor(page, page_n_values) .map_err(vortex_err_from_pco) - .vortex_unwrap(); + .vortex_expect("page_decompressor should succeed with valid page data"); pd.decompress(&mut decompressed_values[old_len..new_len]) .map_err(vortex_err_from_pco) - .vortex_unwrap(); + .vortex_expect("decompress should succeed with valid compressed data"); } else { n_skipped_values += page_n_values; } diff --git a/encodings/runend/src/compute/filter.rs b/encodings/runend/src/compute/filter.rs index 3bc373d4fdf..821b0bc54c3 100644 --- a/encodings/runend/src/compute/filter.rs +++ b/encodings/runend/src/compute/filter.rs @@ -22,7 +22,6 @@ use vortex_dtype::NativePType; use vortex_dtype::match_each_unsigned_integer_ptype; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_mask::Mask; use crate::RunEndArray; @@ -118,9 +117,9 @@ fn filter_run_end_primitive + AsPrimitiv let end = min(run_ends[i].as_() - offset, length); // Safety: predicate must be the same length as the array the ends have been taken from - for pred in - (start..end).map(|i| unsafe { mask.value_unchecked(i.try_into().vortex_unwrap()) }) - { + for pred in (start..end).map(|i| unsafe { + mask.value_unchecked(i.try_into().vortex_expect("index must fit in usize")) + }) { count += >::from(pred); keep |= pred } diff --git a/encodings/sparse/src/lib.rs b/encodings/sparse/src/lib.rs index d14d942b6ca..f35daa91cde 100644 --- a/encodings/sparse/src/lib.rs +++ b/encodings/sparse/src/lib.rs @@ -533,7 +533,7 @@ mod test { use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_scalar::PrimitiveScalar; use vortex_scalar::Scalar; @@ -684,7 +684,7 @@ mod test { .into_array(), None, ) - .vortex_unwrap(); + .vortex_expect("SparseArray::encode should succeed for test data"); let canonical = sparse.to_primitive(); assert_eq!( sparse.validity_mask(), diff --git a/fuzz/fuzz_targets/file_io.rs b/fuzz/fuzz_targets/file_io.rs index df4cc45a2c4..894c2a91b56 100644 --- a/fuzz/fuzz_targets/file_io.rs +++ b/fuzz/fuzz_targets/file_io.rs @@ -21,7 +21,6 @@ use vortex_buffer::ByteBufferMut; use vortex_dtype::DType; use vortex_dtype::StructFields; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_file::OpenOptionsSessionExt; use vortex_file::WriteOptionsSessionExt; @@ -52,14 +51,15 @@ fuzz_target!(|fuzz: FuzzFileAction| -> Corpus { .clone() .unwrap_or_else(|| lit(true)) .evaluate(&array_data) - .vortex_unwrap(); + .vortex_expect("filter expression evaluation should succeed in fuzz test"); let mask = bool_mask.to_bool().to_mask_fill_null_false(); - let filtered = filter(&array_data, &mask).vortex_unwrap(); + let filtered = filter(&array_data, &mask) + .vortex_expect("filter operation should succeed in fuzz test"); projection_expr .clone() .unwrap_or_else(root) .evaluate(&filtered) - .vortex_unwrap() + .vortex_expect("projection expression evaluation should succeed in fuzz test") }; let write_options = match compressor_strategy { @@ -76,20 +76,20 @@ fuzz_target!(|fuzz: FuzzFileAction| -> Corpus { let _footer = write_options .blocking(&*RUNTIME) .write(&mut full_buff, array_data.to_array_iterator()) - .vortex_unwrap(); + .vortex_expect("file write should succeed in fuzz test"); let mut output = SESSION .open_options() .open_buffer(full_buff) - .vortex_unwrap() + .vortex_expect("open_buffer should succeed in fuzz test") .scan() - .vortex_unwrap() + .vortex_expect("scan should succeed in fuzz test") .with_projection(projection_expr.unwrap_or_else(root)) .with_some_filter(filter_expr) .into_array_iter(&*RUNTIME) - .vortex_unwrap() + .vortex_expect("into_array_iter should succeed in fuzz test") .try_collect::<_, Vec<_>, _>() - .vortex_unwrap(); + .vortex_expect("collect should succeed in fuzz test"); let output_array = match output.len() { 0 => Canonical::empty(expected_array.dtype()).into_array(), @@ -113,7 +113,7 @@ fuzz_target!(|fuzz: FuzzFileAction| -> Corpus { ); let bool_result = compare(&expected_array, &output_array, Operator::Eq) - .vortex_unwrap() + .vortex_expect("compare operation should succeed in fuzz test") .to_bool(); let true_count = bool_result.bit_buffer().true_count(); if true_count != expected_array.len() && (bool_result.all_valid() || expected_array.all_valid()) diff --git a/fuzz/src/array/fill_null.rs b/fuzz/src/array/fill_null.rs index 97a48fd517d..adb52d844c4 100644 --- a/fuzz/src/array/fill_null.rs +++ b/fuzz/src/array/fill_null.rs @@ -21,7 +21,6 @@ use vortex_dtype::match_each_decimal_value_type; use vortex_dtype::match_each_native_ptype; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_scalar::Scalar; /// Apply fill_null on the canonical form of the array to get a consistent baseline. @@ -87,7 +86,8 @@ fn fill_primitive_array( result_nullability: Nullability, ) -> ArrayRef { match_each_native_ptype!(array.ptype(), |T| { - let fill_val = T::try_from(fill_value).vortex_unwrap(); + let fill_val = T::try_from(fill_value) + .vortex_expect("fill value conversion should succeed in fuzz test"); match array.validity() { Validity::NonNullable | Validity::AllValid => PrimitiveArray::from_byte_buffer( @@ -129,7 +129,8 @@ fn fill_decimal_array( let decimal_scalar = fill_value.as_decimal(); match_each_decimal_value_type!(array.values_type(), |D| { - let fill_val = D::try_from(decimal_scalar).vortex_unwrap(); + let fill_val = D::try_from(decimal_scalar) + .vortex_expect("decimal fill value conversion should succeed in fuzz test"); match array.validity() { Validity::NonNullable | Validity::AllValid => DecimalArray::new( @@ -156,7 +157,7 @@ fn fill_decimal_array( } DecimalArray::try_new(new_data.freeze(), decimal_dtype, result_nullability.into()) - .vortex_unwrap() + .vortex_expect("DecimalArray creation should succeed in fuzz test") .into_array() } } diff --git a/fuzz/src/array/mask.rs b/fuzz/src/array/mask.rs index d604f299a66..fcff725c954 100644 --- a/fuzz/src/array/mask.rs +++ b/fuzz/src/array/mask.rs @@ -17,8 +17,8 @@ use vortex_array::arrays::VarBinViewArray; use vortex_array::vtable::ValidityHelper; use vortex_dtype::ExtDType; use vortex_dtype::match_each_decimal_value_type; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_mask::Mask; /// Apply mask on the canonical form of the array to get a consistent baseline. @@ -94,13 +94,13 @@ pub fn mask_canonical_array(canonical: Canonical, mask: &Mask) -> VortexResult { // Recursively mask the storage array - let masked_storage = - mask_canonical_array(array.storage().to_canonical(), mask).vortex_unwrap(); + let masked_storage = mask_canonical_array(array.storage().to_canonical(), mask) + .vortex_expect("mask_canonical_array should succeed in fuzz test"); if masked_storage.dtype().nullability() == array.ext_dtype().storage_dtype().nullability() diff --git a/fuzz/src/array/mod.rs b/fuzz/src/array/mod.rs index cd75f9742c7..e93fe96bf7f 100644 --- a/fuzz/src/array/mod.rs +++ b/fuzz/src/array/mod.rs @@ -50,7 +50,6 @@ use vortex_btrblocks::BtrBlocksCompressor; use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_mask::Mask; use vortex_scalar::Scalar; @@ -186,8 +185,8 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { ActionType::Slice => { let start = u.choose_index(current_array.len())?; let stop = u.int_in_range(start..=current_array.len())?; - current_array = - slice_canonical_array(¤t_array, start, stop).vortex_unwrap(); + current_array = slice_canonical_array(¤t_array, start, stop) + .vortex_expect("slice_canonical_array should succeed in fuzz test"); ( Action::Slice(start..stop), @@ -202,7 +201,8 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { let indices = random_vec_in_range(u, 0, current_array.len() - 1)?; let nullable = indices.contains(&None); - current_array = take_canonical_array(¤t_array, &indices).vortex_unwrap(); + current_array = take_canonical_array(¤t_array, &indices) + .vortex_expect("take_canonical_array should succeed in fuzz test"); let indices_array = if nullable { PrimitiveArray::from_option_iter( indices.iter().map(|i| i.map(|i| i as u64)), @@ -220,7 +220,7 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { let compressed = BtrBlocksCompressor::default() .compress(&indices_array) - .vortex_unwrap(); + .vortex_expect("BtrBlocksCompressor compress should succeed in fuzz test"); ( Action::Take(compressed), ExpectedValue::Array(current_array.to_array()), @@ -241,7 +241,8 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { return Err(EmptyChoose); } - let sorted = sort_canonical_array(¤t_array).vortex_unwrap(); + let sorted = sort_canonical_array(¤t_array) + .vortex_expect("sort_canonical_array should succeed in fuzz test"); let side = if u.arbitrary()? { SearchSortedSide::Left @@ -251,7 +252,9 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { ( Action::SearchSorted(scalar.clone(), side), ExpectedValue::Search( - search_sorted_canonical_array(&sorted, &scalar, side).vortex_unwrap(), + search_sorted_canonical_array(&sorted, &scalar, side).vortex_expect( + "search_sorted_canonical_array should succeed in fuzz test", + ), ), ) } @@ -259,7 +262,8 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { let mask = (0..current_array.len()) .map(|_| bool::arbitrary(u)) .collect::>>()?; - current_array = filter_canonical_array(¤t_array, &mask).vortex_unwrap(); + current_array = filter_canonical_array(¤t_array, &mask) + .vortex_expect("filter_canonical_array should succeed in fuzz test"); ( Action::Filter(Mask::from_iter(mask)), ExpectedValue::Array(current_array.to_array()), @@ -302,14 +306,14 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { } // Sum - returns a scalar, does NOT update current_array (terminal operation) - let sum_result = - sum_canonical_array(current_array.to_canonical()).vortex_unwrap(); + let sum_result = sum_canonical_array(current_array.to_canonical()) + .vortex_expect("sum_canonical_array should succeed in fuzz test"); (Action::Sum, ExpectedValue::Scalar(sum_result)) } ActionType::MinMax => { // MinMax - returns a scalar, does NOT update current_array (terminal operation) - let min_max_result = - min_max_canonical_array(current_array.to_canonical()).vortex_unwrap(); + let min_max_result = min_max_canonical_array(current_array.to_canonical()) + .vortex_expect("min_max_canonical_array should succeed in fuzz test"); (Action::MinMax, ExpectedValue::MinMax(min_max_result)) } ActionType::FillNull => { @@ -335,7 +339,7 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { // Compute expected result on canonical form let expected_result = fill_null_canonical_array(current_array.to_canonical(), &fill_value) - .vortex_unwrap(); + .vortex_expect("fill_null_canonical_array should succeed in fuzz test"); // Update current_array to the result for chaining current_array = expected_result.clone(); ( @@ -354,7 +358,7 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { current_array.to_canonical(), &Mask::from_iter(mask.iter().copied()), ) - .vortex_unwrap(); + .vortex_expect("mask_canonical_array should succeed in fuzz test"); // Update current_array to the result for chaining current_array = expected_result.clone(); ( @@ -382,7 +386,9 @@ impl<'a> Arbitrary<'a> for FuzzArrayAction { .iter() .map(|&idx| { scalar_at_canonical_array(current_array.to_canonical(), idx) - .vortex_unwrap() + .vortex_expect( + "scalar_at_canonical_array should succeed in fuzz test", + ) }) .collect(); @@ -493,8 +499,10 @@ pub fn compress_array(array: &dyn Array, strategy: CompressorStrategy) -> ArrayR match strategy { CompressorStrategy::Default => BtrBlocksCompressor::default() .compress(array) - .vortex_unwrap(), - CompressorStrategy::Compact => CompactCompressor::default().compress(array).vortex_unwrap(), + .vortex_expect("BtrBlocksCompressor compress should succeed in fuzz test"), + CompressorStrategy::Compact => CompactCompressor::default() + .compress(array) + .vortex_expect("CompactCompressor compress should succeed in fuzz test"), } } @@ -503,7 +511,7 @@ pub fn compress_array(array: &dyn Array, strategy: CompressorStrategy) -> ArrayR pub fn compress_array(array: &dyn Array, _strategy: CompressorStrategy) -> ArrayRef { BtrBlocksCompressor::default() .compress(array) - .vortex_unwrap() + .vortex_expect("BtrBlocksCompressor compress should succeed in fuzz test") } /// Run a fuzz action and return whether to keep it in the corpus. @@ -542,11 +550,13 @@ pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> crate::error::VortexFuzz if indices.is_empty() { return Ok(false); // Reject } - current_array = take(¤t_array, &indices).vortex_unwrap(); + current_array = take(¤t_array, &indices) + .vortex_expect("take operation should succeed in fuzz test"); assert_array_eq(&expected.array(), ¤t_array, i)?; } Action::SearchSorted(s, side) => { - let mut sorted = sort_canonical_array(¤t_array).vortex_unwrap(); + let mut sorted = sort_canonical_array(¤t_array) + .vortex_expect("sort_canonical_array should succeed in fuzz test"); if !current_array.is_canonical() { sorted = compress_array(&sorted, CompressorStrategy::Default); @@ -554,7 +564,8 @@ pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> crate::error::VortexFuzz assert_search_sorted(sorted, s, side, expected.search(), i)?; } Action::Filter(mask_val) => { - current_array = filter(¤t_array, &mask_val).vortex_unwrap(); + current_array = filter(¤t_array, &mask_val) + .vortex_expect("filter operation should succeed in fuzz test"); assert_array_eq(&expected.array(), ¤t_array, i)?; } Action::Compare(v, op) => { @@ -563,7 +574,7 @@ pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> crate::error::VortexFuzz &ConstantArray::new(v.clone(), current_array.len()).into_array(), op, ) - .vortex_unwrap(); + .vortex_expect("compare operation should succeed in fuzz test"); if let Err(e) = assert_array_eq(&expected.array(), &compare_result, i) { vortex_panic!( "Failed to compare {}with {op} {v}\nError: {e}", @@ -573,7 +584,8 @@ pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> crate::error::VortexFuzz current_array = compare_result; } Action::Cast(to) => { - let cast_result = cast(¤t_array, &to).vortex_unwrap(); + let cast_result = cast(¤t_array, &to) + .vortex_expect("cast operation should succeed in fuzz test"); if let Err(e) = assert_array_eq(&expected.array(), &cast_result, i) { vortex_panic!( "Failed to cast {} to dtype {to}\nError: {e}", @@ -583,19 +595,23 @@ pub fn run_fuzz_action(fuzz_action: FuzzArrayAction) -> crate::error::VortexFuzz current_array = cast_result; } Action::Sum => { - let sum_result = sum(¤t_array).vortex_unwrap(); + let sum_result = + sum(¤t_array).vortex_expect("sum operation should succeed in fuzz test"); assert_scalar_eq(&expected.scalar(), &sum_result, i)?; } Action::MinMax => { - let min_max_result = min_max(¤t_array).vortex_unwrap(); + let min_max_result = min_max(¤t_array) + .vortex_expect("min_max operation should succeed in fuzz test"); assert_min_max_eq(&expected.min_max(), &min_max_result, i)?; } Action::FillNull(fill_value) => { - current_array = fill_null(¤t_array, &fill_value).vortex_unwrap(); + current_array = fill_null(¤t_array, &fill_value) + .vortex_expect("fill_null operation should succeed in fuzz test"); assert_array_eq(&expected.array(), ¤t_array, i)?; } Action::Mask(mask_val) => { - current_array = mask(¤t_array, &mask_val).vortex_unwrap(); + current_array = mask(¤t_array, &mask_val) + .vortex_expect("mask operation should succeed in fuzz test"); assert_array_eq(&expected.array(), ¤t_array, i)?; } Action::ScalarAt(indices) => { diff --git a/fuzz/src/array/scalar_at.rs b/fuzz/src/array/scalar_at.rs index e2bcce4b35e..98b533ffdf0 100644 --- a/fuzz/src/array/scalar_at.rs +++ b/fuzz/src/array/scalar_at.rs @@ -9,8 +9,8 @@ use vortex_array::arrays::varbin_scalar; use vortex_dtype::DType; use vortex_dtype::match_each_decimal_value_type; use vortex_dtype::match_each_native_ptype; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_scalar::DecimalValue; use vortex_scalar::Scalar; @@ -44,7 +44,10 @@ pub fn scalar_at_canonical_array(canonical: Canonical, index: usize) -> VortexRe Canonical::List(array) => { let list = array.list_elements_at(index); let children: Vec = (0..list.len()) - .map(|i| scalar_at_canonical_array(list.to_canonical(), i).vortex_unwrap()) + .map(|i| { + scalar_at_canonical_array(list.to_canonical(), i) + .vortex_expect("scalar_at_canonical_array should succeed in fuzz test") + }) .collect(); Scalar::list( Arc::new(list.dtype().clone()), @@ -55,7 +58,10 @@ pub fn scalar_at_canonical_array(canonical: Canonical, index: usize) -> VortexRe Canonical::FixedSizeList(array) => { let list = array.fixed_size_list_elements_at(index); let children: Vec = (0..list.len()) - .map(|i| scalar_at_canonical_array(list.to_canonical(), i).vortex_unwrap()) + .map(|i| { + scalar_at_canonical_array(list.to_canonical(), i) + .vortex_expect("scalar_at_canonical_array should succeed in fuzz test") + }) .collect(); Scalar::fixed_size_list(list.dtype().clone(), children, array.dtype().nullability()) } @@ -63,7 +69,10 @@ pub fn scalar_at_canonical_array(canonical: Canonical, index: usize) -> VortexRe let field_scalars: Vec = array .fields() .iter() - .map(|field| scalar_at_canonical_array(field.to_canonical(), index).vortex_unwrap()) + .map(|field| { + scalar_at_canonical_array(field.to_canonical(), index) + .vortex_expect("scalar_at_canonical_array should succeed in fuzz test") + }) .collect(); Scalar::struct_(array.dtype().clone(), field_scalars) } diff --git a/vortex-array/benches/varbinview_compact.rs b/vortex-array/benches/varbinview_compact.rs index e6d5cbe636a..bcbe2a8225c 100644 --- a/vortex-array/benches/varbinview_compact.rs +++ b/vortex-array/benches/varbinview_compact.rs @@ -14,7 +14,7 @@ use vortex_array::compute::take; use vortex_buffer::Buffer; use vortex_dtype::DType; use vortex_dtype::Nullability; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; fn main() { divan::main(); @@ -42,12 +42,15 @@ fn compact_impl(bencher: Bencher, (output_size, utilization_pct): (usize, usize) let base_size = (output_size * 100) / utilization_pct; let base_array = build_varbinview_fixture(base_size); let indices = random_indices(output_size, base_size); - let taken = take(base_array.as_ref(), &indices).vortex_unwrap(); + let taken = + take(base_array.as_ref(), &indices).vortex_expect("operation should succeed in benchmark"); let array = taken.to_varbinview(); - bencher - .with_inputs(|| &array) - .bench_refs(|array| array.compact_buffers().vortex_unwrap()) + bencher.with_inputs(|| &array).bench_refs(|array| { + array + .compact_buffers() + .vortex_expect("operation should succeed in benchmark") + }) } fn compact_sliced_impl(bencher: Bencher, (output_size, utilization_pct): (usize, usize)) { @@ -56,9 +59,11 @@ fn compact_sliced_impl(bencher: Bencher, (output_size, utilization_pct): (usize, let sliced = base_array.as_ref().slice(0..output_size); let array = sliced.to_varbinview(); - bencher - .with_inputs(|| &array) - .bench_refs(|array| array.compact_buffers().vortex_unwrap()) + bencher.with_inputs(|| &array).bench_refs(|array| { + array + .compact_buffers() + .vortex_expect("operation should succeed in benchmark") + }) } /// Creates a base VarBinViewArray with mix of inlined and outlined strings. diff --git a/vortex-array/src/arrays/arbitrary.rs b/vortex-array/src/arrays/arbitrary.rs index 22e0d95e915..64da1c49778 100644 --- a/vortex-array/src/arrays/arbitrary.rs +++ b/vortex-array/src/arrays/arbitrary.rs @@ -16,7 +16,6 @@ use vortex_dtype::Nullability; use vortex_dtype::PType; use vortex_dtype::match_each_decimal_value_type; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_scalar::Scalar; use vortex_scalar::arbitrary::random_scalar; @@ -78,7 +77,7 @@ fn random_array(u: &mut Unstructured, dtype: &DType, len: Option) -> Resu } else { let dtype = chunks[0].dtype().clone(); Ok(ChunkedArray::try_new(chunks, dtype) - .vortex_unwrap() + .vortex_expect("operation should succeed in arbitrary impl") .into_array()) } } @@ -158,7 +157,7 @@ fn random_array_chunk( resolved_len, random_validity(u, *n, resolved_len)?, ) - .vortex_unwrap() + .vortex_expect("operation should succeed in arbitrary impl") .into_array()) } DType::List(elem_dtype, null) => random_list(u, elem_dtype, *null, chunk_len), diff --git a/vortex-array/src/arrays/chunked/array.rs b/vortex-array/src/arrays/chunked/array.rs index 07f68ebe3be..9f41b7e6847 100644 --- a/vortex-array/src/arrays/chunked/array.rs +++ b/vortex-array/src/arrays/chunked/array.rs @@ -13,7 +13,6 @@ use vortex_buffer::BufferMut; use vortex_dtype::DType; use vortex_error::VortexExpect as _; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_bail; use crate::Array; @@ -83,7 +82,9 @@ impl ChunkedArray { Self { dtype, - len: curr_offset.try_into().vortex_unwrap(), + len: curr_offset + .try_into() + .vortex_expect("chunk offset must fit in usize"), chunk_offsets, chunks, stats_set: Default::default(), diff --git a/vortex-array/src/arrays/chunked/compute/filter.rs b/vortex-array/src/arrays/chunked/compute/filter.rs index e397232651b..b0ccb5ab07d 100644 --- a/vortex-array/src/arrays/chunked/compute/filter.rs +++ b/vortex-array/src/arrays/chunked/compute/filter.rs @@ -4,7 +4,6 @@ use vortex_buffer::BufferMut; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_mask::Mask; use vortex_mask::MaskIter; @@ -195,7 +194,9 @@ pub(crate) fn find_chunk_idx(idx: usize, chunk_ends: &[u64]) -> (usize, usize) { .search_sorted(&(idx as u64), SearchSortedSide::Right) .to_ends_index(chunk_ends.len()) .saturating_sub(1); - let chunk_begin: usize = chunk_ends[chunk_id].try_into().vortex_unwrap(); + let chunk_begin: usize = chunk_ends[chunk_id] + .try_into() + .vortex_expect("chunk end must fit in usize"); let chunk_offset = idx - chunk_begin; (chunk_id, chunk_offset) diff --git a/vortex-array/src/arrays/constant/compute/sum.rs b/vortex-array/src/arrays/constant/compute/sum.rs index 628b0cdaa35..75a412d50c3 100644 --- a/vortex-array/src/arrays/constant/compute/sum.rs +++ b/vortex-array/src/arrays/constant/compute/sum.rs @@ -175,7 +175,7 @@ mod tests { use vortex_dtype::Nullability::Nullable; use vortex_dtype::PType; use vortex_dtype::i256; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_scalar::DecimalValue; use vortex_scalar::Scalar; @@ -292,10 +292,10 @@ mod tests { fn test_sum_float_non_multiply() { let acc = -2048669276050936500000000000f64; let array = ConstantArray::new(6.1811675e16f64, 25); - let sum = - sum_with_accumulator(array.as_ref(), &Scalar::primitive(acc, Nullable)).vortex_unwrap(); + let sum = sum_with_accumulator(array.as_ref(), &Scalar::primitive(acc, Nullable)) + .vortex_expect("operation should succeed in test"); assert_eq!( - f64::try_from(sum).vortex_unwrap(), + f64::try_from(sum).vortex_expect("operation should succeed in test"), -2048669274505644600000000000f64 ); } diff --git a/vortex-array/src/arrays/decimal/compute/sum.rs b/vortex-array/src/arrays/decimal/compute/sum.rs index a61cc67d63d..d48e1141081 100644 --- a/vortex-array/src/arrays/decimal/compute/sum.rs +++ b/vortex-array/src/arrays/decimal/compute/sum.rs @@ -129,7 +129,7 @@ mod tests { use vortex_dtype::DType; use vortex_dtype::DecimalDType; use vortex_dtype::Nullability; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_scalar::DecimalValue; use vortex_scalar::Scalar; use vortex_scalar::ScalarValue; @@ -371,7 +371,7 @@ mod tests { ); assert_eq!( - sum(decimal.as_ref()).vortex_unwrap(), + sum(decimal.as_ref()).vortex_expect("operation should succeed in test"), Scalar::null(DType::Decimal(decimal_dtype, Nullability::Nullable)) ); } diff --git a/vortex-array/src/arrays/dict/array.rs b/vortex-array/src/arrays/dict/array.rs index 2b320014c51..a8395808b2c 100644 --- a/vortex-array/src/arrays/dict/array.rs +++ b/vortex-array/src/arrays/dict/array.rs @@ -80,8 +80,9 @@ impl DictArray { #[cfg(debug_assertions)] { - use vortex_error::VortexUnwrap; - self.validate_all_values_referenced().vortex_unwrap() + use vortex_error::VortexExpect; + self.validate_all_values_referenced() + .vortex_expect("validation should succeed when all values are referenced") } self @@ -219,7 +220,6 @@ mod test { use vortex_dtype::PType; use vortex_dtype::UnsignedPType; use vortex_error::VortexExpect; - use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_mask::AllOr; @@ -332,7 +332,7 @@ mod test { .collect::(); DictArray::try_new(codes.into_array(), values.into_array()) - .vortex_unwrap() + .vortex_expect("DictArray creation should succeed in arbitrary impl") .into_array() }) .collect::() diff --git a/vortex-array/src/arrays/dict/compute/fill_null.rs b/vortex-array/src/arrays/dict/compute/fill_null.rs index d63892c4412..a4436522c6e 100644 --- a/vortex-array/src/arrays/dict/compute/fill_null.rs +++ b/vortex-array/src/arrays/dict/compute/fill_null.rs @@ -67,7 +67,7 @@ mod tests { use vortex_buffer::BitBuffer; use vortex_buffer::buffer; use vortex_dtype::Nullability; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_scalar::Scalar; use crate::IntoArray; @@ -88,13 +88,13 @@ mod tests { .into_array(), PrimitiveArray::new(buffer![10, 20, 20], Validity::AllValid).into_array(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); let filled = fill_null( dict.as_ref(), &Scalar::primitive(20, Nullability::NonNullable), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); let filled_primitive = filled.to_primitive(); assert_arrays_eq!(filled_primitive, PrimitiveArray::from_iter([10, 20, 20])); assert!(filled_primitive.all_valid()); diff --git a/vortex-array/src/arrays/dict_test.rs b/vortex-array/src/arrays/dict_test.rs index 486465f6fa2..0eee899f357 100644 --- a/vortex-array/src/arrays/dict_test.rs +++ b/vortex-array/src/arrays/dict_test.rs @@ -12,8 +12,8 @@ use rand::prelude::IndexedRandom; use rand::prelude::StdRng; use vortex_buffer::Buffer; use vortex_dtype::NativePType; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use super::ChunkedArray; use super::DictArray; @@ -82,7 +82,7 @@ where (0..chunk_count) .map(|_| { gen_primitive_dict::(len, unique_values) - .vortex_unwrap() + .vortex_expect("operation should succeed in test") .into_array() }) .collect::() diff --git a/vortex-array/src/arrays/list/tests.rs b/vortex-array/src/arrays/list/tests.rs index 8eb263f57c9..6eaf62127ef 100644 --- a/vortex-array/src/arrays/list/tests.rs +++ b/vortex-array/src/arrays/list/tests.rs @@ -8,7 +8,7 @@ use vortex_buffer::buffer; use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType::I32; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_mask::Mask; use vortex_scalar::Scalar; @@ -359,7 +359,7 @@ fn test_offset_to_0() { ) .as_list(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); builder .append_value( Scalar::list( @@ -369,7 +369,7 @@ fn test_offset_to_0() { ) .as_list(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); builder .append_value( Scalar::list( @@ -379,7 +379,7 @@ fn test_offset_to_0() { ) .as_list(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); builder .append_value( Scalar::list( @@ -389,7 +389,7 @@ fn test_offset_to_0() { ) .as_list(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); builder .append_value( Scalar::list( @@ -399,7 +399,7 @@ fn test_offset_to_0() { ) .as_list(), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); let list = builder.finish().slice(2..4); // The sliced list should be a ListArray since we built it with ListBuilder diff --git a/vortex-array/src/arrays/primitive/compute/is_sorted.rs b/vortex-array/src/arrays/primitive/compute/is_sorted.rs index 82c8d804547..5ff6a22909f 100644 --- a/vortex-array/src/arrays/primitive/compute/is_sorted.rs +++ b/vortex-array/src/arrays/primitive/compute/is_sorted.rs @@ -92,7 +92,7 @@ fn compute_is_sorted(array: &PrimitiveArray, strict: bool) -> Vo #[cfg(test)] mod tests { use rstest::rstest; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use super::*; use crate::compute::is_sorted; @@ -105,7 +105,10 @@ mod tests { #[case(PrimitiveArray::from_option_iter([None, None, Some(1i32), Some(1)]), true)] #[case(PrimitiveArray::from_option_iter([None, Some(5_u8), None]), false)] fn test_primitive_is_sorted(#[case] array: PrimitiveArray, #[case] expected: bool) { - assert_eq!(is_sorted(array.as_ref()).vortex_unwrap(), Some(expected)); + assert_eq!( + is_sorted(array.as_ref()).vortex_expect("operation should succeed in test"), + Some(expected) + ); } #[rstest] @@ -116,7 +119,7 @@ mod tests { #[case(PrimitiveArray::from_option_iter([None, Some(5_u8), None]), false)] fn test_primitive_is_strict_sorted(#[case] array: PrimitiveArray, #[case] expected: bool) { assert_eq!( - is_strict_sorted(array.as_ref()).vortex_unwrap(), + is_strict_sorted(array.as_ref()).vortex_expect("operation should succeed in test"), Some(expected) ); } diff --git a/vortex-array/src/arrays/struct_/compute/mod.rs b/vortex-array/src/arrays/struct_/compute/mod.rs index a34bf99b456..19b89cc5dd3 100644 --- a/vortex-array/src/arrays/struct_/compute/mod.rs +++ b/vortex-array/src/arrays/struct_/compute/mod.rs @@ -21,7 +21,7 @@ mod tests { use vortex_dtype::Nullability; use vortex_dtype::PType; use vortex_dtype::StructFields; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_mask::Mask; use crate::Array; @@ -316,7 +316,8 @@ mod tests { #[test] fn test_empty_struct_is_constant() { let array = StructArray::new_fieldless_with_len(2); - let is_constant = is_constant(array.as_ref()).vortex_unwrap(); + let is_constant = + is_constant(array.as_ref()).vortex_expect("operation should succeed in test"); assert_eq!(is_constant, Some(true)); } diff --git a/vortex-array/src/arrays/varbin/mod.rs b/vortex-array/src/arrays/varbin/mod.rs index cfadc93ffe8..11aa256c6b5 100644 --- a/vortex-array/src/arrays/varbin/mod.rs +++ b/vortex-array/src/arrays/varbin/mod.rs @@ -17,7 +17,7 @@ mod accessor; use vortex_buffer::ByteBuffer; use vortex_dtype::DType; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_error::vortex_err; use vortex_scalar::Scalar; @@ -25,7 +25,7 @@ pub fn varbin_scalar(value: ByteBuffer, dtype: &DType) -> Scalar { if matches!(dtype, DType::Utf8(_)) { Scalar::try_utf8(value, dtype.nullability()) .map_err(|err| vortex_err!("Failed to create scalar from utf8 buffer: {}", err)) - .vortex_unwrap() + .vortex_expect("UTF-8 scalar creation should succeed") } else { Scalar::binary(value, dtype.nullability()) } diff --git a/vortex-array/src/builders/decimal.rs b/vortex-array/src/builders/decimal.rs index 96be211e64d..4f504d40cab 100644 --- a/vortex-array/src/builders/decimal.rs +++ b/vortex-array/src/builders/decimal.rs @@ -13,7 +13,6 @@ use vortex_dtype::match_each_decimal_value; use vortex_dtype::match_each_decimal_value_type; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_ensure; use vortex_error::vortex_err; use vortex_error::vortex_panic; @@ -234,7 +233,7 @@ impl DecimalBuffer { T::DECIMAL_TYPE, ) }) - .vortex_unwrap(), + .vortex_expect("operation should succeed in builder"), ) }); } diff --git a/vortex-array/src/builders/dict/bytes.rs b/vortex-array/src/builders/dict/bytes.rs index ac769037e26..d6343e62e99 100644 --- a/vortex-array/src/builders/dict/bytes.rs +++ b/vortex-array/src/builders/dict/bytes.rs @@ -11,7 +11,6 @@ use vortex_buffer::ByteBufferMut; use vortex_dtype::DType; use vortex_dtype::UnsignedPType; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_utils::aliases::hash_map::DefaultHashBuilder; use vortex_utils::aliases::hash_map::HashTable; @@ -107,7 +106,8 @@ impl BytesDictBuilder { let view = BinaryView::make_view( val, 0, - u32::try_from(self.values.len()).vortex_unwrap(), + u32::try_from(self.values.len()) + .vortex_expect("values length must fit in u32"), ); let additional_bytes = if view.is_inlined() { size_of::() diff --git a/vortex-array/src/compute/conformance/binary_numeric.rs b/vortex-array/src/compute/conformance/binary_numeric.rs index 78e36147acc..42b99befb5e 100644 --- a/vortex-array/src/compute/conformance/binary_numeric.rs +++ b/vortex-array/src/compute/conformance/binary_numeric.rs @@ -28,7 +28,7 @@ use num_traits::Num; use vortex_dtype::DType; use vortex_dtype::NativePType; use vortex_dtype::PType; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_error::vortex_err; use vortex_error::vortex_panic; use vortex_scalar::NumericOperator; @@ -93,8 +93,10 @@ where let one = T::from(1) .ok_or_else(|| vortex_err!("could not convert 1 into array native type")) - .vortex_unwrap(); - let scalar_one = Scalar::from(one).cast(array.dtype()).vortex_unwrap(); + .vortex_expect("operation should succeed in conformance test"); + let scalar_one = Scalar::from(one) + .cast(array.dtype()) + .vortex_expect("operation should succeed in conformance test"); let operators: [NumericOperator; 6] = [ NumericOperator::Add, @@ -327,7 +329,7 @@ where let scalar = Scalar::from(scalar_value) .cast(array.dtype()) - .vortex_unwrap(); + .vortex_expect("operation should succeed in conformance test"); // Only test operators that make sense for the given scalar let operators = if scalar_value == T::zero() { @@ -362,7 +364,7 @@ where continue; } - let result = result.vortex_unwrap(); + let result = result.vortex_expect("operation should succeed in conformance test"); let actual_values = to_vec_of_scalar(&result); // Check each element for overflow/underflow diff --git a/vortex-array/src/compute/conformance/cast.rs b/vortex-array/src/compute/conformance/cast.rs index 691dc22ae4c..2e918914952 100644 --- a/vortex-array/src/compute/conformance/cast.rs +++ b/vortex-array/src/compute/conformance/cast.rs @@ -4,8 +4,7 @@ use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType; -use vortex_error::VortexExpect as _; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_error::vortex_panic; use vortex_scalar::Scalar; @@ -52,7 +51,8 @@ pub fn test_cast_conformance(array: &dyn Array) { fn test_cast_identity(array: &dyn Array) { // Casting to the same type should be a no-op - let result = cast(array, array.dtype()).vortex_unwrap(); + let result = + cast(array, array.dtype()).vortex_expect("cast should succeed in conformance test"); assert_eq!(result.len(), array.len()); assert_eq!(result.dtype(), array.dtype()); @@ -64,7 +64,7 @@ fn test_cast_identity(array: &dyn Array) { fn test_cast_from_null(array: &dyn Array) { // Null can be cast to itself - let result = cast(array, &DType::Null).vortex_unwrap(); + let result = cast(array, &DType::Null).vortex_expect("cast should succeed in conformance test"); assert_eq!(result.len(), array.len()); assert_eq!(result.dtype(), &DType::Null); @@ -78,7 +78,7 @@ fn test_cast_from_null(array: &dyn Array) { ]; for dtype in nullable_types { - let result = cast(array, &dtype).vortex_unwrap(); + let result = cast(array, &dtype).vortex_expect("cast should succeed in conformance test"); assert_eq!(result.len(), array.len()); assert_eq!(result.dtype(), &dtype); @@ -188,7 +188,7 @@ fn fits(value: &Scalar, ptype: PType) -> bool { } fn test_cast_to_primitive(array: &dyn Array, target_ptype: PType, test_round_trip: bool) { - let maybe_min_max = min_max(array).vortex_unwrap(); + let maybe_min_max = min_max(array).vortex_expect("cast should succeed in conformance test"); if let Some(MinMaxResult { min, max }) = maybe_min_max && (!fits(&min, target_ptype) || !fits(&max, target_ptype)) @@ -228,14 +228,18 @@ fn test_cast_to_primitive(array: &dyn Array, target_ptype: PType, test_round_tri let original = array.scalar_at(i); let casted = casted.scalar_at(i); assert_eq!( - original.cast(casted.dtype()).vortex_unwrap(), + original + .cast(casted.dtype()) + .vortex_expect("cast should succeed in conformance test"), casted, "{i} {original} {casted}" ); if test_round_trip { assert_eq!( original, - casted.cast(original.dtype()).vortex_unwrap(), + casted + .cast(original.dtype()) + .vortex_expect("cast should succeed in conformance test"), "{i} {original} {casted}" ); } diff --git a/vortex-array/src/compute/conformance/consistency.rs b/vortex-array/src/compute/conformance/consistency.rs index df9797849d1..c345b3900e0 100644 --- a/vortex-array/src/compute/conformance/consistency.rs +++ b/vortex-array/src/compute/conformance/consistency.rs @@ -23,7 +23,7 @@ use vortex_buffer::BitBuffer; use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_error::vortex_panic; use vortex_mask::Mask; @@ -63,7 +63,7 @@ fn test_filter_take_consistency(array: &dyn Array) { let mask = Mask::from_buffer(mask_pattern.clone()); // Filter the array - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); // Create indices where mask is true let indices: Vec = mask_pattern @@ -74,7 +74,8 @@ fn test_filter_take_consistency(array: &dyn Array) { let indices_array = PrimitiveArray::from_iter(indices).into_array(); // Take using those indices - let taken = take(array, &indices_array).vortex_unwrap(); + let taken = + take(array, &indices_array).vortex_expect("take should succeed in conformance test"); // Results should be identical assert_eq!( @@ -123,8 +124,9 @@ fn test_double_mask_consistency(array: &dyn Array) { let mask2: Mask = (0..len).map(|i| i % 2 == 0).collect(); // Apply masks sequentially - let first_masked = mask(array, &mask1).vortex_unwrap(); - let double_masked = mask(&first_masked, &mask2).vortex_unwrap(); + let first_masked = mask(array, &mask1).vortex_expect("mask should succeed in conformance test"); + let double_masked = + mask(&first_masked, &mask2).vortex_expect("mask should succeed in conformance test"); // Create combined mask (OR operation - element is masked if EITHER mask is true) let combined_pattern: BitBuffer = mask1 @@ -136,7 +138,8 @@ fn test_double_mask_consistency(array: &dyn Array) { let combined_mask = Mask::from_buffer(combined_pattern); // Apply combined mask directly - let directly_masked = mask(array, &combined_mask).vortex_unwrap(); + let directly_masked = + mask(array, &combined_mask).vortex_expect("mask should succeed in conformance test"); // Results should be identical assert_eq!( @@ -180,7 +183,8 @@ fn test_filter_identity(array: &dyn Array) { } let all_true_mask = Mask::new_true(len); - let filtered = filter(array, &all_true_mask).vortex_unwrap(); + let filtered = + filter(array, &all_true_mask).vortex_expect("filter should succeed in conformance test"); // Filtered array should be identical to original assert_eq!( @@ -223,7 +227,8 @@ fn test_mask_identity(array: &dyn Array) { } let all_false_mask = Mask::new_false(len); - let masked = mask(array, &all_false_mask).vortex_unwrap(); + let masked = + mask(array, &all_false_mask).vortex_expect("mask should succeed in conformance test"); // Masked array should have same values (just nullable) assert_eq!( @@ -278,7 +283,7 @@ fn test_slice_filter_consistency(array: &dyn Array) { mask_pattern[1..4.min(len)].fill(true); let mask = Mask::from_iter(mask_pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); // Slice should produce the same result let sliced = array.slice(1..4.min(len)); @@ -325,7 +330,7 @@ fn test_take_slice_consistency(array: &dyn Array) { // Take indices [1, 2, 3] let end = 4.min(len); let indices = PrimitiveArray::from_iter((1..end).map(|i| i as u64)).into_array(); - let taken = take(array, &indices).vortex_unwrap(); + let taken = take(array, &indices).vortex_expect("take should succeed in conformance test"); // Slice from 1 to end let sliced = array.slice(1..end); @@ -361,7 +366,7 @@ fn test_filter_preserves_order(array: &dyn Array) { let mask_pattern: Vec = (0..len).map(|i| i == 0 || i == 2 || i == 3).collect(); let mask = Mask::from_iter(mask_pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); // Verify the filtered array contains the right elements in order assert_eq!(filtered.len(), 3.min(len)); @@ -381,7 +386,7 @@ fn test_take_repeated_indices(array: &dyn Array) { // Take the first element three times let indices = PrimitiveArray::from_iter([0u64, 0, 0]).into_array(); - let taken = take(array, &indices).vortex_unwrap(); + let taken = take(array, &indices).vortex_expect("take should succeed in conformance test"); assert_eq!(taken.len(), 3); for i in 0..3 { @@ -399,15 +404,17 @@ fn test_mask_filter_null_consistency(array: &dyn Array) { // First mask some elements let mask_pattern: Vec = (0..len).map(|i| i % 2 == 0).collect(); let mask_array = Mask::from_iter(mask_pattern); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); // Then filter to remove the nulls let filter_pattern: Vec = (0..len).map(|i| i % 2 != 0).collect(); let filter_mask = Mask::from_iter(filter_pattern); - let filtered = filter(&masked, &filter_mask).vortex_unwrap(); + let filtered = + filter(&masked, &filter_mask).vortex_expect("filter should succeed in conformance test"); // This should be equivalent to directly filtering the original array - let direct_filtered = filter(array, &filter_mask).vortex_unwrap(); + let direct_filtered = + filter(array, &filter_mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), direct_filtered.len()); for i in 0..filtered.len() { @@ -420,13 +427,15 @@ fn test_empty_operations_consistency(array: &dyn Array) { let len = array.len(); // Empty filter - let empty_filter = filter(array, &Mask::new_false(len)).vortex_unwrap(); + let empty_filter = filter(array, &Mask::new_false(len)) + .vortex_expect("filter should succeed in conformance test"); assert_eq!(empty_filter.len(), 0); assert_eq!(empty_filter.dtype(), array.dtype()); // Empty take let empty_indices = PrimitiveArray::empty::(Nullability::NonNullable).into_array(); - let empty_take = take(array, &empty_indices).vortex_unwrap(); + let empty_take = + take(array, &empty_indices).vortex_expect("take should succeed in conformance test"); assert_eq!(empty_take.len(), 0); assert_eq!(empty_take.dtype(), array.dtype()); @@ -447,7 +456,7 @@ fn test_take_preserves_properties(array: &dyn Array) { // Take all elements in original order let indices = PrimitiveArray::from_iter((0..len).map(|i| i as u64)).into_array(); - let taken = take(array, &indices).vortex_unwrap(); + let taken = take(array, &indices).vortex_expect("take should succeed in conformance test"); // Should be identical to original assert_eq!(taken.len(), array.len()); @@ -483,7 +492,7 @@ fn test_nullable_indices_consistency(array: &dyn Array) { // Create nullable indices where some indices are null let indices = PrimitiveArray::from_option_iter([Some(0u64), None, Some(2u64)]).into_array(); - let taken = take(array, &indices).vortex_unwrap(); + let taken = take(array, &indices).vortex_expect("take should succeed in conformance test"); // Result should have nulls where indices were null assert_eq!( @@ -535,12 +544,13 @@ fn test_large_array_consistency(array: &dyn Array) { // Test with every 10th element let indices: Vec = (0..len).step_by(10).map(|i| i as u64).collect(); let indices_array = PrimitiveArray::from_iter(indices).into_array(); - let taken = take(array, &indices_array).vortex_unwrap(); + let taken = + take(array, &indices_array).vortex_expect("take should succeed in conformance test"); // Create equivalent filter mask let mask_pattern: Vec = (0..len).map(|i| i % 10 == 0).collect(); let mask = Mask::from_iter(mask_pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); // Results should match assert_eq!(taken.len(), filtered.len()); @@ -590,7 +600,8 @@ fn test_comparison_inverse_consistency(array: &dyn Array) { compare(array, const_array.as_ref(), Operator::Eq), compare(array, const_array.as_ref(), Operator::NotEq), ) { - let inverted_eq = invert(&eq_result).vortex_unwrap(); + let inverted_eq = + invert(&eq_result).vortex_expect("invert should succeed in conformance test"); assert_eq!( inverted_eq.len(), @@ -614,7 +625,8 @@ fn test_comparison_inverse_consistency(array: &dyn Array) { compare(array, const_array.as_ref(), Operator::Gt), compare(array, const_array.as_ref(), Operator::Lte), ) { - let inverted_gt = invert(>_result).vortex_unwrap(); + let inverted_gt = + invert(>_result).vortex_expect("invert should succeed in conformance test"); for i in 0..inverted_gt.len() { let inv_val = inverted_gt.scalar_at(i); @@ -632,7 +644,8 @@ fn test_comparison_inverse_consistency(array: &dyn Array) { compare(array, const_array.as_ref(), Operator::Lt), compare(array, const_array.as_ref(), Operator::Gte), ) { - let inverted_lt = invert(<_result).vortex_unwrap(); + let inverted_lt = + invert(<_result).vortex_expect("invert should succeed in conformance test"); for i in 0..inverted_lt.len() { let inv_val = inverted_lt.scalar_at(i); @@ -751,8 +764,10 @@ fn test_boolean_demorgan_consistency(array: &dyn Array) { // Test first De Morgan's law: NOT(A AND B) = (NOT A) OR (NOT B) if let (Ok(a_and_b), Ok(not_a), Ok(not_b)) = (and(array, mask), invert(array), invert(mask)) { - let not_a_and_b = invert(&a_and_b).vortex_unwrap(); - let not_a_or_not_b = or(¬_a, ¬_b).vortex_unwrap(); + let not_a_and_b = + invert(&a_and_b).vortex_expect("invert should succeed in conformance test"); + let not_a_or_not_b = + or(¬_a, ¬_b).vortex_expect("or should succeed in conformance test"); assert_eq!( not_a_and_b.len(), @@ -773,8 +788,9 @@ fn test_boolean_demorgan_consistency(array: &dyn Array) { // Test second De Morgan's law: NOT(A OR B) = (NOT A) AND (NOT B) if let (Ok(a_or_b), Ok(not_a), Ok(not_b)) = (or(array, mask), invert(array), invert(mask)) { - let not_a_or_b = invert(&a_or_b).vortex_unwrap(); - let not_a_and_not_b = and(¬_a, ¬_b).vortex_unwrap(); + let not_a_or_b = invert(&a_or_b).vortex_expect("invert should succeed in conformance test"); + let not_a_and_not_b = + and(¬_a, ¬_b).vortex_expect("and should succeed in conformance test"); for i in 0..not_a_or_b.len() { let left = not_a_or_b.scalar_at(i); diff --git a/vortex-array/src/compute/conformance/filter.rs b/vortex-array/src/compute/conformance/filter.rs index 66d84f0edaa..6db22fb7e5d 100644 --- a/vortex-array/src/compute/conformance/filter.rs +++ b/vortex-array/src/compute/conformance/filter.rs @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: Copyright the Vortex contributors use vortex_dtype::DType; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_mask::Mask; use crate::Array; @@ -63,7 +63,7 @@ pub fn create_runs_pattern(len: usize, run_length: usize) -> Vec { fn test_all_filter(array: &dyn Array) { let len = array.len(); let mask = Mask::new_true(len); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_arrays_eq!(filtered, array); } @@ -71,7 +71,7 @@ fn test_all_filter(array: &dyn Array) { fn test_none_filter(array: &dyn Array) { let len = array.len(); let mask = Mask::new_false(len); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 0); assert_eq!(filtered.dtype(), array.dtype()); } @@ -86,7 +86,7 @@ fn test_selective_filter(array: &dyn Array) { let mask_values: Vec = (0..len).map(|i| i % 2 == 0).collect(); let expected_count = mask_values.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(mask_values); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); // Verify correct elements are kept @@ -100,7 +100,8 @@ fn test_selective_filter(array: &dyn Array) { mask_values[0] = true; mask_values[len - 1] = true; let mask = Mask::from_iter(mask_values); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = + filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 2); assert_eq!(filtered.scalar_at(0), array.scalar_at(0)); assert_eq!(filtered.scalar_at(1), array.scalar_at(len - 1)); @@ -117,7 +118,7 @@ fn test_single_element_filter(array: &dyn Array) { let mut mask_values = vec![false; len]; mask_values[0] = true; let mask = Mask::from_iter(mask_values); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 1); assert_eq!(filtered.scalar_at(0), array.scalar_at(0)); @@ -126,7 +127,8 @@ fn test_single_element_filter(array: &dyn Array) { let mut mask_values = vec![false; len]; mask_values[len - 1] = true; let mask = Mask::from_iter(mask_values); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = + filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 1); assert_eq!(filtered.scalar_at(0), array.scalar_at(len - 1)); } @@ -137,11 +139,13 @@ fn test_empty_array_filter(dtype: &DType) { let empty_array = Canonical::empty(dtype).into_array(); let empty_mask = Mask::new_false(0); - let filtered = filter(&empty_array, &empty_mask).vortex_unwrap(); + let filtered = filter(&empty_array, &empty_mask) + .vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 0); let empty_mask = Mask::new_true(0); - let filtered = filter(&empty_array, &empty_mask).vortex_unwrap(); + let filtered = filter(&empty_array, &empty_mask) + .vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), 0); } @@ -174,7 +178,7 @@ fn test_alternating_pattern_filter(array: &dyn Array) { let expected_count = pattern.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(pattern.clone()); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); // Verify correct elements are kept @@ -199,7 +203,7 @@ fn test_runs_pattern_filter(array: &dyn Array) { let expected_count = pattern.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); } @@ -215,7 +219,7 @@ fn test_sparse_true_filter(array: &dyn Array) { let expected_count = pattern.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); } @@ -231,7 +235,7 @@ fn test_sparse_false_filter(array: &dyn Array) { let expected_count = pattern.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); } @@ -246,6 +250,6 @@ fn test_random_pattern_filter(array: &dyn Array) { let expected_count = pattern.iter().filter(|&&v| v).count(); let mask = Mask::from_iter(pattern); - let filtered = filter(array, &mask).vortex_unwrap(); + let filtered = filter(array, &mask).vortex_expect("filter should succeed in conformance test"); assert_eq!(filtered.len(), expected_count); } diff --git a/vortex-array/src/compute/conformance/mask.rs b/vortex-array/src/compute/conformance/mask.rs index 719b0e0b406..c3d4abc96e8 100644 --- a/vortex-array/src/compute/conformance/mask.rs +++ b/vortex-array/src/compute/conformance/mask.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_mask::Mask; use crate::Array; @@ -39,7 +39,7 @@ fn test_heterogenous_mask(array: &dyn Array) { let mask_pattern: Vec = (0..len).map(|i| i % 3 != 1).collect(); let mask_array = Mask::from_iter(mask_pattern.clone()); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert_eq!(masked.len(), array.len()); // Verify masked elements are null and unmasked elements are preserved @@ -58,7 +58,7 @@ fn test_empty_mask(array: &dyn Array) { let all_unmasked = vec![false; len]; let mask_array = Mask::from_iter(all_unmasked); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert_eq!(masked.len(), array.len()); // All elements should be preserved @@ -73,7 +73,7 @@ fn test_full_mask(array: &dyn Array) { let all_masked = vec![true; len]; let mask_array = Mask::from_iter(all_masked); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert_eq!(masked.len(), array.len()); // All elements should be null @@ -88,7 +88,7 @@ fn test_alternating_mask(array: &dyn Array) { let pattern: Vec = (0..len).map(|i| i % 2 == 0).collect(); let mask_array = Mask::from_iter(pattern); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert_eq!(masked.len(), array.len()); for i in 0..len { @@ -111,7 +111,7 @@ fn test_sparse_mask(array: &dyn Array) { let pattern: Vec = (0..len).map(|i| i % 10 == 0).collect(); let mask_array = Mask::from_iter(pattern.clone()); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert_eq!(masked.len(), array.len()); // Count how many elements are valid after masking @@ -136,7 +136,7 @@ fn test_single_element_mask(array: &dyn Array) { pattern[0] = true; let mask_array = Mask::from_iter(pattern); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); assert!(!masked.is_valid(0)); for i in 1..len { @@ -155,8 +155,9 @@ fn test_double_mask(array: &dyn Array) { let mask1 = Mask::from_iter(mask1_pattern.clone()); let mask2 = Mask::from_iter(mask2_pattern.clone()); - let first_masked = mask(array, &mask1).vortex_unwrap(); - let double_masked = mask(&first_masked, &mask2).vortex_unwrap(); + let first_masked = mask(array, &mask1).vortex_expect("mask should succeed in conformance test"); + let double_masked = + mask(&first_masked, &mask2).vortex_expect("mask should succeed in conformance test"); // Elements should be null if either mask is true for i in 0..len { @@ -187,7 +188,7 @@ fn test_nullable_mask_input(array: &dyn Array) { let nullable_mask = BoolArray::from_bit_buffer(bool_array.bit_buffer().clone(), validity); let mask_array = nullable_mask.to_mask_fill_null_false(); - let masked = mask(array, &mask_array).vortex_unwrap(); + let masked = mask(array, &mask_array).vortex_expect("mask should succeed in conformance test"); // Elements are masked only if the mask is true AND valid for i in 0..len { diff --git a/vortex-array/src/compute/conformance/take.rs b/vortex-array/src/compute/conformance/take.rs index 453e65f7671..dd82e9ccc70 100644 --- a/vortex-array/src/compute/conformance/take.rs +++ b/vortex-array/src/compute/conformance/take.rs @@ -3,7 +3,7 @@ use vortex_buffer::buffer; use vortex_dtype::Nullability; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use crate::Array; use crate::Canonical; @@ -55,7 +55,8 @@ pub fn test_take_conformance(array: &dyn Array) { fn test_take_all(array: &dyn Array) { let len = array.len(); let indices = PrimitiveArray::from_iter(0..len as u64); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), len); assert_eq!(result.dtype(), array.dtype()); @@ -76,7 +77,8 @@ fn test_take_all(array: &dyn Array) { fn test_take_none(array: &dyn Array) { let indices: PrimitiveArray = PrimitiveArray::from_iter::<[u64; 0]>([]); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), 0); assert_eq!(result.dtype(), array.dtype()); @@ -91,7 +93,8 @@ fn test_take_selective(array: &dyn Array) { let expected_len = indices.len(); let indices_array = PrimitiveArray::from_iter(indices.clone()); - let result = take(array, indices_array.as_ref()).vortex_unwrap(); + let result = take(array, indices_array.as_ref()) + .vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), expected_len); // Verify the taken elements @@ -106,7 +109,8 @@ fn test_take_selective(array: &dyn Array) { fn test_take_first_and_last(array: &dyn Array) { let len = array.len(); let indices = PrimitiveArray::from_iter([0u64, (len - 1) as u64]); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), 2); assert_eq!(array.scalar_at(0), result.scalar_at(0)); @@ -127,7 +131,8 @@ fn test_take_with_nullable_indices(array: &dyn Array) { }; let indices = PrimitiveArray::from_option_iter(indices_vec.clone()); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), indices_vec.len()); assert_eq!( @@ -157,7 +162,8 @@ fn test_take_repeated_indices(array: &dyn Array) { // Take the first element multiple times let indices = buffer![0u64, 0, 0].into_array(); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), 3); let first_elem = array.scalar_at(0); @@ -168,7 +174,8 @@ fn test_take_repeated_indices(array: &dyn Array) { fn test_empty_indices(array: &dyn Array) { let indices = PrimitiveArray::empty::(Nullability::NonNullable); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), 0); assert_eq!(result.dtype(), array.dtype()); @@ -178,7 +185,8 @@ fn test_take_reverse(array: &dyn Array) { let len = array.len(); // Take elements in reverse order let indices = PrimitiveArray::from_iter((0..len as u64).rev()); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), len); @@ -193,7 +201,8 @@ fn test_take_single_middle(array: &dyn Array) { let middle_idx = len / 2; let indices = PrimitiveArray::from_iter([middle_idx as u64]); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), 1); assert_eq!(array.scalar_at(middle_idx), result.scalar_at(0)); @@ -212,7 +221,8 @@ fn test_take_random_unsorted(array: &dyn Array) { } let indices_array = PrimitiveArray::from_iter(indices.clone()); - let result = take(array, indices_array.as_ref()).vortex_unwrap(); + let result = take(array, indices_array.as_ref()) + .vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), indices.len()); @@ -229,7 +239,8 @@ fn test_take_contiguous_range(array: &dyn Array) { // Take a contiguous range from the middle let indices = PrimitiveArray::from_iter(start as u64..end as u64); - let result = take(array, indices.as_ref()).vortex_unwrap(); + let result = + take(array, indices.as_ref()).vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), end - start); @@ -256,7 +267,8 @@ fn test_take_mixed_repeated(array: &dyn Array) { ]; let indices_array = PrimitiveArray::from_iter(indices.clone()); - let result = take(array, indices_array.as_ref()).vortex_unwrap(); + let result = take(array, indices_array.as_ref()) + .vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), indices.len()); @@ -278,7 +290,8 @@ fn test_take_large_indices(array: &dyn Array) { .collect(); let indices_array = PrimitiveArray::from_iter(indices.clone()); - let result = take(array, indices_array.as_ref()).vortex_unwrap(); + let result = take(array, indices_array.as_ref()) + .vortex_expect("take should succeed in conformance test"); assert_eq!(result.len(), num_indices); diff --git a/vortex-array/src/compute/sum.rs b/vortex-array/src/compute/sum.rs index 0d189f8bcf1..5cca3111df7 100644 --- a/vortex-array/src/compute/sum.rs +++ b/vortex-array/src/compute/sum.rs @@ -273,7 +273,7 @@ mod test { use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_scalar::Scalar; use crate::IntoArray as _; @@ -327,7 +327,7 @@ mod test { ], DType::Primitive(PType::I32, Nullability::NonNullable), ) - .vortex_unwrap(); + .vortex_expect("operation should succeed in test"); // compute sum with accumulator to populate stats sum_with_accumulator( array.as_ref(), diff --git a/vortex-array/src/expr/exprs/cast.rs b/vortex-array/src/expr/exprs/cast.rs index cc14a4793ff..80d8009e379 100644 --- a/vortex-array/src/expr/exprs/cast.rs +++ b/vortex-array/src/expr/exprs/cast.rs @@ -173,7 +173,7 @@ mod tests { use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::PType; - use vortex_error::VortexUnwrap as _; + use vortex_error::VortexExpect as _; use super::cast; use crate::IntoArray; @@ -197,7 +197,8 @@ mod tests { #[test] fn replace_children() { let expr = cast(root(), DType::Bool(Nullability::Nullable)); - expr.with_children(vec![root()]).vortex_unwrap(); + expr.with_children(vec![root()]) + .vortex_expect("operation should succeed in test"); } #[test] diff --git a/vortex-array/src/expr/exprs/is_null.rs b/vortex-array/src/expr/exprs/is_null.rs index c5dac482f70..193b1bf5682 100644 --- a/vortex-array/src/expr/exprs/is_null.rs +++ b/vortex-array/src/expr/exprs/is_null.rs @@ -140,7 +140,7 @@ mod tests { use vortex_dtype::FieldPath; use vortex_dtype::FieldPathSet; use vortex_dtype::Nullability; - use vortex_error::VortexUnwrap as _; + use vortex_error::VortexExpect as _; use vortex_scalar::Scalar; use vortex_utils::aliases::hash_map::HashMap; use vortex_utils::aliases::hash_set::HashSet; @@ -170,7 +170,8 @@ mod tests { #[test] fn replace_children() { let expr = is_null(root()); - expr.with_children([root()]).vortex_unwrap(); + expr.with_children([root()]) + .vortex_expect("operation should succeed in test"); } #[test] diff --git a/vortex-array/src/expr/mod.rs b/vortex-array/src/expr/mod.rs index 169a639d129..6f20e864846 100644 --- a/vortex-array/src/expr/mod.rs +++ b/vortex-array/src/expr/mod.rs @@ -16,7 +16,7 @@ use std::sync::Arc; use arcref::ArcRef; use vortex_dtype::FieldName; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_utils::aliases::hash_set::HashSet; use crate::expr::traversal::NodeExt; @@ -61,7 +61,8 @@ impl VortexExprExt for Expression { fn field_references(&self) -> HashSet { let mut collector = ReferenceCollector::new(); // The collector is infallible, so we can unwrap the result - self.accept(&mut collector).vortex_unwrap(); + self.accept(&mut collector) + .vortex_expect("reference collector should never fail"); collector.into_fields() } } diff --git a/vortex-bench/src/lib.rs b/vortex-bench/src/lib.rs index 8409b3fd64e..fea3d15488d 100644 --- a/vortex-bench/src/lib.rs +++ b/vortex-bench/src/lib.rs @@ -25,7 +25,7 @@ use tpcds::TpcDsBenchmark; use tpch::benchmark::TpcHBenchmark; pub use utils::file::*; pub use utils::logging::*; -use vortex::error::VortexUnwrap; +use vortex::error::VortexExpect; use vortex::error::vortex_err; use vortex::file::VortexWriteOptions; use vortex::file::WriteStrategyBuilder; @@ -94,7 +94,7 @@ impl FromStr for Target { e ) }) - .vortex_unwrap(), + .vortex_expect("operation should succeed in benchmark"), format: Format::from_str(format_str, true) .map_err(|e| { vortex_err!( @@ -104,7 +104,7 @@ impl FromStr for Target { e ) }) - .vortex_unwrap(), + .vortex_expect("operation should succeed in benchmark"), }) } } diff --git a/vortex-bench/src/measurements.rs b/vortex-bench/src/measurements.rs index b6962a57d69..f49349cd95e 100644 --- a/vortex-bench/src/measurements.rs +++ b/vortex-bench/src/measurements.rs @@ -15,7 +15,7 @@ use serde::Deserialize; use serde::Serialize; use serde::Serializer; use target_lexicon::Triple; -use vortex::error::VortexUnwrap; +use vortex::error::VortexExpect; use vortex::error::vortex_panic; use crate::BenchmarkDataset; @@ -184,8 +184,10 @@ impl TimingMeasurement { let total_nanos: u128 = self.runs.iter().map(|d| d.as_nanos()).sum(); let mean_nanos = total_nanos / len as u128; Duration::new( - u64::try_from(mean_nanos / 1_000_000_000).vortex_unwrap(), - u32::try_from(mean_nanos % 1_000_000_000).vortex_unwrap(), + u64::try_from(mean_nanos / 1_000_000_000) + .vortex_expect("nanosecond conversion must fit in u64/u32"), + u32::try_from(mean_nanos % 1_000_000_000) + .vortex_expect("nanosecond conversion must fit in u64/u32"), ) } @@ -263,8 +265,10 @@ impl QueryMeasurement { let mid2 = sorted_runs[len / 2]; let avg_nanos = (mid1.as_nanos() + mid2.as_nanos()) / 2; Duration::new( - u64::try_from(avg_nanos / 1_000_000_000).vortex_unwrap(), - u32::try_from(avg_nanos % 1_000_000_000).vortex_unwrap(), + u64::try_from(avg_nanos / 1_000_000_000) + .vortex_expect("nanosecond conversion must fit in u64/u32"), + u32::try_from(avg_nanos % 1_000_000_000) + .vortex_expect("nanosecond conversion must fit in u64/u32"), ) } } diff --git a/vortex-btrblocks/src/float/stats.rs b/vortex-btrblocks/src/float/stats.rs index 6c6e0b2d8be..312bc2570e2 100644 --- a/vortex-btrblocks/src/float/stats.rs +++ b/vortex-btrblocks/src/float/stats.rs @@ -14,7 +14,6 @@ use vortex_dtype::NativePType; use vortex_dtype::PType; use vortex_dtype::half::f16; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_error::vortex_panic; use vortex_mask::AllOr; use vortex_utils::aliases::hash_set::HashSet; @@ -200,7 +199,10 @@ where .try_into() .vortex_expect("null_count must fit in u32"); let distinct_values_count = if count_distinct_values { - distinct_values.len().try_into().vortex_unwrap() + distinct_values + .len() + .try_into() + .vortex_expect("distinct values count must fit in u32") } else { u32::MAX }; diff --git a/vortex-btrblocks/src/integer.rs b/vortex-btrblocks/src/integer.rs index 55a75c16898..5d93e96c045 100644 --- a/vortex-btrblocks/src/integer.rs +++ b/vortex-btrblocks/src/integer.rs @@ -17,8 +17,8 @@ use vortex_array::arrays::MaskedArray; use vortex_array::arrays::PrimitiveArray; use vortex_array::arrays::PrimitiveVTable; use vortex_array::vtable::ValidityHelper; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_bail; use vortex_error::vortex_err; use vortex_fastlanes::FoRArray; @@ -277,7 +277,12 @@ impl Scheme for FORScheme { } // Difference between max and min - let full_width: u32 = stats.src.ptype().bit_width().try_into().vortex_unwrap(); + let full_width: u32 = stats + .src + .ptype() + .bit_width() + .try_into() + .vortex_expect("bit width must fit in u32"); let bw = match stats.typed.max_minus_min().checked_ilog2() { Some(l) => l + 1, // If max-min == 0, it we should use a different compression scheme diff --git a/vortex-btrblocks/src/integer/stats.rs b/vortex-btrblocks/src/integer/stats.rs index 40b7fc38e8c..c8365a8cef8 100644 --- a/vortex-btrblocks/src/integer/stats.rs +++ b/vortex-btrblocks/src/integer/stats.rs @@ -15,7 +15,6 @@ use vortex_dtype::IntegerPType; use vortex_dtype::match_each_integer_ptype; use vortex_error::VortexError; use vortex_error::VortexExpect; -use vortex_error::VortexUnwrap; use vortex_mask::AllOr; use vortex_scalar::PValue; use vortex_scalar::Scalar; @@ -242,7 +241,7 @@ where AllOr::All => { for chunk in &mut chunks { inner_loop_nonnull( - chunk.try_into().vortex_unwrap(), + chunk.try_into().vortex_expect("chunk size must be 64"), count_distinct_values, &mut loop_state, ) @@ -268,13 +267,13 @@ where 0 => continue, // Inner loop for when validity check can be elided 64 => inner_loop_nonnull( - chunk.try_into().vortex_unwrap(), + chunk.try_into().vortex_expect("chunk size must be 64"), count_distinct_values, &mut loop_state, ), // Inner loop for when we need to check validity _ => inner_loop_nullable( - chunk.try_into().vortex_unwrap(), + chunk.try_into().vortex_expect("chunk size must be 64"), count_distinct_values, &validity, &mut loop_state, @@ -305,7 +304,11 @@ where let runs = loop_state.runs; let distinct_values_count = if count_distinct_values { - loop_state.distinct_values.len().try_into().vortex_unwrap() + loop_state + .distinct_values + .len() + .try_into() + .vortex_expect("distinct values count must fit in u32") } else { u32::MAX }; diff --git a/vortex-btrblocks/src/lib.rs b/vortex-btrblocks/src/lib.rs index 996c32cc379..39b1672f642 100644 --- a/vortex-btrblocks/src/lib.rs +++ b/vortex-btrblocks/src/lib.rs @@ -51,8 +51,8 @@ use vortex_array::vtable::ValidityHelper; use vortex_dtype::DType; use vortex_dtype::Nullability; use vortex_dtype::datetime::TemporalMetadata; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use crate::decimal::compress_decimal; pub use crate::float::FloatCompressor; @@ -186,7 +186,8 @@ fn estimate_compression_ratio_with_sampling( // We want to sample about 1% of data, while keeping a minimal sample of 640 values. let sample_count = usize::max( - (source_len / 100) / usize::try_from(SAMPLE_SIZE).vortex_unwrap(), + (source_len / 100) + / usize::try_from(SAMPLE_SIZE).vortex_expect("SAMPLE_SIZE must fit in usize"), 10, ); @@ -196,7 +197,12 @@ fn estimate_compression_ratio_with_sampling( source_len ); - stats.sample(SAMPLE_SIZE, sample_count.try_into().vortex_unwrap()) + stats.sample( + SAMPLE_SIZE, + sample_count + .try_into() + .vortex_expect("sample count must fit in u32"), + ) }; let after = compressor diff --git a/vortex-dtype/src/struct_.rs b/vortex-dtype/src/struct_.rs index 78ffc93a076..42df2ae95ae 100644 --- a/vortex-dtype/src/struct_.rs +++ b/vortex-dtype/src/struct_.rs @@ -10,7 +10,6 @@ use std::sync::OnceLock; use itertools::Itertools; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_bail; use vortex_error::vortex_err; use vortex_error::vortex_panic; @@ -349,17 +348,30 @@ impl StructFields { /// of the first field encountered with a given name. pub fn field(&self, name: impl AsRef) -> Option { let index = self.find(name)?; - Some(self.0.dtypes[index].value().vortex_unwrap()) + Some( + self.0.dtypes[index] + .value() + .vortex_expect("field DType must be valid"), + ) } /// Get the [`DType`] of a field by index. pub fn field_by_index(&self, index: usize) -> Option { - Some(self.0.dtypes.get(index)?.value().vortex_unwrap()) + Some( + self.0 + .dtypes + .get(index)? + .value() + .vortex_expect("field DType must be valid"), + ) } /// Returns an ordered iterator over the fields. pub fn fields(&self) -> impl ExactSizeIterator + '_ { - self.0.dtypes.iter().map(|dt| dt.value().vortex_unwrap()) + self.0 + .dtypes + .iter() + .map(|dt| dt.value().vortex_expect("field DType must be valid")) } /// Project a subset of fields from the struct diff --git a/vortex-duckdb/src/convert/vector.rs b/vortex-duckdb/src/convert/vector.rs index 431a285b593..3b0c554e45e 100644 --- a/vortex-duckdb/src/convert/vector.rs +++ b/vortex-duckdb/src/convert/vector.rs @@ -228,10 +228,10 @@ pub fn flat_vector_to_vortex(vector: &mut Vector, len: usize) -> VortexResult VortexResult { pub fn put(&self, key: &str, entry: T) -> *mut T { let key_cstr = CString::new(key) .map_err(|e| vortex_err!("invalid key: {}", e)) - .vortex_unwrap(); + .vortex_expect("object cache key should be valid C string"); let opaque_ptr = Box::into_raw(Box::new(entry)); unsafe { @@ -50,7 +50,7 @@ impl ObjectCacheRef<'_> { pub fn get(&self, key: &str) -> Option<&T> { let key_cstr = CString::new(key) .map_err(|e| vortex_err!("invalid key: {}", e)) - .vortex_unwrap(); + .vortex_expect("object cache key should be valid C string"); unsafe { let opaque_ptr = cpp::duckdb_vx_object_cache_get(self.as_ptr(), key_cstr.as_ptr()); diff --git a/vortex-duckdb/src/duckdb/scalar_function.rs b/vortex-duckdb/src/duckdb/scalar_function.rs index 6b95683b1c0..c27af3c43b6 100644 --- a/vortex-duckdb/src/duckdb/scalar_function.rs +++ b/vortex-duckdb/src/duckdb/scalar_function.rs @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: Copyright the Vortex contributors -use vortex::error::VortexUnwrap; +use vortex::error::VortexExpect; use vortex::error::vortex_err; use crate::cpp; @@ -17,7 +17,7 @@ impl ScalarFunction { std::ffi::CStr::from_ptr(name_ptr) .to_str() .map_err(|e| vortex_err!("invalid utf-8: {e}")) - .vortex_unwrap() + .vortex_expect("scalar function name should be valid UTF-8") } } diff --git a/vortex-duckdb/src/duckdb/vector.rs b/vortex-duckdb/src/duckdb/vector.rs index 8343b4eef3e..1b448df8f6f 100644 --- a/vortex-duckdb/src/duckdb/vector.rs +++ b/vortex-duckdb/src/duckdb/vector.rs @@ -12,8 +12,8 @@ use bitvec::view::BitView; use vortex::array::validity::Validity; use vortex::buffer::BitBuffer; use vortex::buffer::Buffer; +use vortex::error::VortexExpect; use vortex::error::VortexResult; -use vortex::error::VortexUnwrap; use vortex::error::vortex_bail; use vortex::error::vortex_err; @@ -102,7 +102,7 @@ impl Vector { pub fn set_dictionary_id(&mut self, dict_id: String) { let dict_id = CString::new(dict_id) .map_err(|e| vortex_err!("cstr creation error {e}")) - .vortex_unwrap(); + .vortex_expect("dictionary ID should be valid C string"); unsafe { cpp::duckdb_vx_set_dictionary_vector_id( self.ptr, diff --git a/vortex-duckdb/src/exporter/decimal.rs b/vortex-duckdb/src/exporter/decimal.rs index a30d64be249..5a1139c036e 100644 --- a/vortex-duckdb/src/exporter/decimal.rs +++ b/vortex-duckdb/src/exporter/decimal.rs @@ -216,7 +216,7 @@ pub fn precision_to_duckdb_storage_size(decimal_dtype: &DecimalDType) -> VortexR mod tests { use vortex::array::arrays::DecimalArray; use vortex::dtype::DecimalDType; - use vortex::error::VortexUnwrap; + use vortex::error::VortexExpect; use super::*; use crate::duckdb::DataChunk; @@ -249,7 +249,8 @@ mod tests { ); // Create a DuckDB integer chunk since decimal will be stored as i32 for this precision - let mut chunk = DataChunk::new([LogicalType::decimal_type(10, 2).vortex_unwrap()]); + let mut chunk = DataChunk::new([LogicalType::decimal_type(10, 2) + .vortex_expect("LogicalType creation should succeed for test data")]); new_zero_copy_exporter(&arr) .unwrap() @@ -275,7 +276,8 @@ mod tests { decimal_dtype, ); - let mut chunk = DataChunk::new([LogicalType::decimal_type(5, 1).vortex_unwrap()]); + let mut chunk = DataChunk::new([LogicalType::decimal_type(5, 1) + .vortex_expect("LogicalType creation should succeed for test data")]); // Export first 3 elements new_zero_copy_exporter(&arr) @@ -300,7 +302,8 @@ mod tests { let arr = DecimalArray::from_option_iter([Some(123456i32), None, Some(789012i32)], decimal_dtype); - let mut chunk = DataChunk::new([LogicalType::decimal_type(8, 3).vortex_unwrap()]); + let mut chunk = DataChunk::new([LogicalType::decimal_type(8, 3) + .vortex_expect("LogicalType creation should succeed for test data")]); new_zero_copy_exporter(&arr) .unwrap() diff --git a/vortex-duckdb/src/exporter/list.rs b/vortex-duckdb/src/exporter/list.rs index b63be464726..4b985f5e1ba 100644 --- a/vortex-duckdb/src/exporter/list.rs +++ b/vortex-duckdb/src/exporter/list.rs @@ -261,7 +261,7 @@ mod tests { use vortex::array::validity::Validity; use vortex::buffer::Buffer; use vortex::buffer::buffer; - use vortex::error::VortexUnwrap; + use vortex::error::VortexExpect; use super::*; use crate::duckdb::DataChunk; @@ -280,7 +280,8 @@ mod tests { } .into_array(); - let list_type = LogicalType::list_type(LogicalType::int32()).vortex_unwrap(); + let list_type = LogicalType::list_type(LogicalType::int32()) + .vortex_expect("LogicalType creation should succeed for test data"); let mut chunk = DataChunk::new([list_type]); new_array_exporter(&list, &ConversionCache::default()) @@ -314,7 +315,8 @@ mod tests { } .into_array(); - let list_type = LogicalType::list_type(LogicalType::varchar()).vortex_unwrap(); + let list_type = LogicalType::list_type(LogicalType::varchar()) + .vortex_expect("LogicalType creation should succeed for test data"); let mut chunk = DataChunk::new([list_type]); new_array_exporter(&list, &ConversionCache::default()) diff --git a/vortex-duckdb/src/exporter/list_view.rs b/vortex-duckdb/src/exporter/list_view.rs index df574431c59..7476b683a4d 100644 --- a/vortex-duckdb/src/exporter/list_view.rs +++ b/vortex-duckdb/src/exporter/list_view.rs @@ -289,7 +289,7 @@ mod tests { use vortex::array::validity::Validity; use vortex::buffer::Buffer; use vortex::buffer::buffer; - use vortex::error::VortexUnwrap; + use vortex::error::VortexExpect; use super::*; use crate::duckdb::DataChunk; @@ -310,7 +310,8 @@ mod tests { } .into_array(); - let list_type = LogicalType::list_type(LogicalType::int32()).vortex_unwrap(); + let list_type = LogicalType::list_type(LogicalType::varchar()) + .vortex_expect("LogicalType creation should succeed for test data"); let mut chunk = DataChunk::new([list_type]); new_array_exporter(&list, &ConversionCache::default()) @@ -340,7 +341,8 @@ mod tests { } .into_array(); - let list_type = LogicalType::list_type(LogicalType::int32()).vortex_unwrap(); + let list_type = LogicalType::list_type(LogicalType::int32()) + .vortex_expect("LogicalType creation should succeed for test data"); let mut chunk = DataChunk::new([list_type]); new_array_exporter(&list, &ConversionCache::default()) @@ -376,7 +378,8 @@ mod tests { } .into_array(); - let list_type = LogicalType::list_type(LogicalType::varchar()).vortex_unwrap(); + let list_type = LogicalType::list_type(LogicalType::varchar()) + .vortex_expect("LogicalType creation should succeed for test data"); let mut chunk = DataChunk::new([list_type]); new_array_exporter(&list, &ConversionCache::default()) diff --git a/vortex-duckdb/src/exporter/struct_.rs b/vortex-duckdb/src/exporter/struct_.rs index 1a3f154bdaf..7af59e64b73 100644 --- a/vortex-duckdb/src/exporter/struct_.rs +++ b/vortex-duckdb/src/exporter/struct_.rs @@ -105,7 +105,6 @@ mod tests { use vortex::buffer::BitBuffer; use vortex::buffer::buffer; use vortex::error::VortexExpect; - use vortex::error::VortexUnwrap; use super::*; use crate::cpp; @@ -127,7 +126,7 @@ mod tests { ], vec![CString::new("col1").unwrap(), CString::new("col2").unwrap()], ) - .vortex_unwrap()]); + .vortex_expect("LogicalType creation should succeed for test data")]); new_exporter(&arr, &ConversionCache::default()) .unwrap() @@ -179,7 +178,7 @@ mod tests { true, true, true, false, false, false, true, true, true, true, ])), ) - .vortex_unwrap(); + .vortex_expect("StructArray creation should succeed for test data"); let mut chunk = DataChunk::new([LogicalType::struct_type( vec![ LogicalType::new(cpp::duckdb_type::DUCKDB_TYPE_INTEGER), @@ -187,7 +186,7 @@ mod tests { ], vec![CString::new("col1").unwrap(), CString::new("col2").unwrap()], ) - .vortex_unwrap()]); + .vortex_expect("LogicalType creation should succeed for test data")]); new_exporter(&arr, &ConversionCache::default()) .unwrap() @@ -210,7 +209,7 @@ mod tests { buffer![0u8, 1, 1, 2, 2, 2, 2, 3, 3, 4].into_array(), VarBinViewArray::from_iter_str(vec!["b", "c", "d", "g", "h"]).into_array(), ) - .vortex_unwrap() + .vortex_expect("DictArray creation should succeed for test data") .into_array(); let arr = StructArray::try_new( ["col1", "col2"].into(), @@ -220,7 +219,7 @@ mod tests { true, true, true, false, false, false, true, true, true, true, ])), ) - .vortex_unwrap(); + .vortex_expect("StructArray creation should succeed for test data"); let mut chunk = DataChunk::new([LogicalType::struct_type( vec![ LogicalType::new(cpp::duckdb_type::DUCKDB_TYPE_INTEGER), @@ -228,7 +227,7 @@ mod tests { ], vec![CString::new("col1").unwrap(), CString::new("col2").unwrap()], ) - .vortex_unwrap()]); + .vortex_expect("LogicalType creation should succeed for test data")]); new_exporter(&arr, &ConversionCache::default()) .unwrap() diff --git a/vortex-error/src/lib.rs b/vortex-error/src/lib.rs index b0ab255ce5a..50e59b0e02e 100644 --- a/vortex-error/src/lib.rs +++ b/vortex-error/src/lib.rs @@ -306,29 +306,6 @@ impl From<&Arc> for VortexError { } } -/// A trait for unwrapping a VortexResult. -pub trait VortexUnwrap { - /// The type of the value being unwrapped. - type Output; - - /// Returns the value of the result if it is Ok, otherwise panics with the error. - /// Should be called only in contexts where the error condition represents a bug (programmer error). - fn vortex_unwrap(self) -> Self::Output; -} - -impl VortexUnwrap for Result -where - E: Into, -{ - type Output = T; - - #[inline(always)] - fn vortex_unwrap(self) -> Self::Output { - self.map_err(|err| err.into()) - .unwrap_or_else(|err| vortex_panic!(err)) - } -} - /// A trait for expect-ing a VortexResult or an Option. pub trait VortexExpect { /// The type of the value being expected. diff --git a/vortex-ffi/src/string.rs b/vortex-ffi/src/string.rs index f28fa3c0dc7..04c7f3c6f04 100644 --- a/vortex-ffi/src/string.rs +++ b/vortex-ffi/src/string.rs @@ -5,7 +5,7 @@ use std::ffi::CStr; use std::ffi::c_char; use std::slice; -use vortex::error::VortexUnwrap; +use vortex::error::VortexExpect; use vortex::error::vortex_err; use crate::arc_dyn_wrapper; @@ -34,7 +34,7 @@ pub unsafe extern "C-unwind" fn vx_string_new(ptr: *const c_char, len: usize) -> let slice = unsafe { slice::from_raw_parts(ptr.cast(), len) }; let string = String::from_utf8(slice.to_vec()) .map_err(|e| vortex_err!("invalid utf-8: {e}")) - .vortex_unwrap(); + .vortex_expect("CString creation should succeed"); vx_string::new(string.into()) } @@ -44,7 +44,7 @@ pub unsafe extern "C-unwind" fn vx_string_new_from_cstr(ptr: *const c_char) -> * let string = unsafe { CStr::from_ptr(ptr) } .to_str() .map_err(|e| vortex_err!("invalid utf-8: {e}")) - .vortex_unwrap(); + .vortex_expect("CString creation should succeed"); vx_string::new(string.into()) } diff --git a/vortex-gpu/benches/gpu_bitunpack.rs b/vortex-gpu/benches/gpu_bitunpack.rs index 7fe48daa526..b043c151493 100644 --- a/vortex-gpu/benches/gpu_bitunpack.rs +++ b/vortex-gpu/benches/gpu_bitunpack.rs @@ -15,7 +15,7 @@ use vortex_alp::{ALPArray, Exponents}; use vortex_array::{Array, ArrayRef, IntoArray, ToCanonical}; use vortex_buffer::BufferMut; use vortex_dtype::NativePType; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; use vortex_fastlanes::{BitPackedArray, FoRArray}; // Data sizes: 1GB, 2.5GB, 5GB, 10GB @@ -59,7 +59,7 @@ fn make_for_bitpackable_array(len: usize) -> FoRArray { let bitpacked = BitPackedArray::encode(values.as_ref(), 6).unwrap(); // Wrap in FoR encoding with reference value - FoRArray::try_new(bitpacked.into_array(), reference.into()).vortex_unwrap() + FoRArray::try_new(bitpacked.into_array(), reference.into()).vortex_expect("operation should succeed in benchmark") } fn make_alp_array(len: usize) -> ArrayRef { @@ -79,12 +79,12 @@ fn make_alp_array(len: usize) -> ArrayRef { // Wrap in FoR encoding with reference value ALPArray::try_new( FoRArray::try_new(bitpacked.into_array(), reference.into()) - .vortex_unwrap() + .vortex_expect("operation should succeed in benchmark") .into_array(), Exponents { e: 4, f: 5 }, None, ) - .vortex_unwrap() + .vortex_expect("operation should succeed in benchmark") .into_array() } diff --git a/vortex-gpu/src/bit_unpack.rs b/vortex-gpu/src/bit_unpack.rs index 1040444e437..9325fbac040 100644 --- a/vortex-gpu/src/bit_unpack.rs +++ b/vortex-gpu/src/bit_unpack.rs @@ -225,7 +225,7 @@ mod tests { use vortex_array::arrays::PrimitiveArray; use vortex_array::validity::Validity; use vortex_buffer::Buffer; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_fastlanes::BitPackedArray; use super::*; @@ -251,7 +251,7 @@ mod tests { Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_expect("operation should succeed in test"); let unpacked = cuda_bit_unpack(&array, ctx).unwrap(); assert_eq!( @@ -290,7 +290,7 @@ mod tests { Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_expect("operation should succeed in test"); let unpacked = cuda_bit_unpack(&array, ctx).unwrap(); assert_eq!( @@ -345,7 +345,7 @@ mod tests { Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_expect("operation should succeed in test"); let unpacked = cuda_bit_unpack(&array, ctx).unwrap(); assert_eq!( @@ -432,7 +432,7 @@ mod tests { Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), bit_width).vortex_expect("operation should succeed in test"); let unpacked = cuda_bit_unpack(&array, ctx).unwrap(); assert_eq!( diff --git a/vortex-gpu/src/for_.rs b/vortex-gpu/src/for_.rs index dabad294f5f..776bce9144e 100644 --- a/vortex-gpu/src/for_.rs +++ b/vortex-gpu/src/for_.rs @@ -137,7 +137,7 @@ mod tests { use vortex_array::validity::Validity; use vortex_array::{IntoArray, ToCanonical}; use vortex_buffer::Buffer; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_fastlanes::{BitPackedArray, FoRArray}; use super::*; @@ -148,8 +148,8 @@ mod tests { (0u32..4096).map(|i| i % 63).collect::>(), Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), 6).vortex_unwrap(); - let array = FoRArray::try_new(array.into_array(), 1u32.into()).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), 6).vortex_expect("operation should succeed in test"); + let array = FoRArray::try_new(array.into_array(), 1u32.into()).vortex_expect("operation should succeed in test"); let ctx = CudaContext::new(0).unwrap(); ctx.set_blocking_synchronize().unwrap(); let unpacked = cuda_for_unpack(&array, ctx).unwrap(); diff --git a/vortex-gpu/src/for_bp.rs b/vortex-gpu/src/for_bp.rs index 16d416d9336..78d29a9fa07 100644 --- a/vortex-gpu/src/for_bp.rs +++ b/vortex-gpu/src/for_bp.rs @@ -148,7 +148,7 @@ mod tests { use vortex_array::validity::Validity; use vortex_array::{IntoArray, ToCanonical}; use vortex_buffer::Buffer; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_fastlanes::{BitPackedArray, FoRArray}; use super::*; @@ -159,8 +159,8 @@ mod tests { (0u32..4096).map(|i| i % 8).collect::>(), Validity::NonNullable, ); - let array = BitPackedArray::encode(primitive_array.as_ref(), 6).vortex_unwrap(); - let array = FoRArray::try_new(array.into_array(), 8u32.into()).vortex_unwrap(); + let array = BitPackedArray::encode(primitive_array.as_ref(), 6).vortex_expect("operation should succeed in test"); + let array = FoRArray::try_new(array.into_array(), 8u32.into()).vortex_expect("operation should succeed in test"); let ctx = CudaContext::new(0).unwrap(); ctx.set_blocking_synchronize().unwrap(); let unpacked = cuda_for_bp_unpack(&array, ctx).unwrap(); diff --git a/vortex-gpu/src/jit/arrays/bitpack.rs b/vortex-gpu/src/jit/arrays/bitpack.rs index da9a4a28fce..bda4429dc02 100644 --- a/vortex-gpu/src/jit/arrays/bitpack.rs +++ b/vortex-gpu/src/jit/arrays/bitpack.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use cudarc::driver::{CudaSlice, CudaStream, DeviceRepr, LaunchArgs, PushKernelArg}; use vortex_buffer::Buffer; use vortex_dtype::{NativePType, PType, match_each_native_ptype}; -use vortex_error::{VortexResult, VortexUnwrap, vortex_err}; +use vortex_error::{VortexResult, VortexExpect, vortex_err}; use vortex_fastlanes::BitPackedArray; use crate::indent::IndentedWrite; @@ -36,7 +36,7 @@ pub fn new_jit( let cuda_slice = stream .memcpy_stod(values.as_slice()) .map_err(|e| vortex_err!("Failed to copy to device: {e}")) - .vortex_unwrap(); + .vortex_expect("operation should succeed"); let step_id = allocator.fresh_id(); Box::new(BitPack::

{ step_id, diff --git a/vortex-gpu/src/rle_decompress.rs b/vortex-gpu/src/rle_decompress.rs index 37b8ffd76bb..94244022830 100644 --- a/vortex-gpu/src/rle_decompress.rs +++ b/vortex-gpu/src/rle_decompress.rs @@ -215,7 +215,7 @@ mod tests { use vortex_array::validity::Validity; use vortex_buffer::Buffer; use vortex_dtype::NativePType; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_fastlanes::RLEArray; use crate::rle_decompress::cuda_rle_decompress; @@ -233,7 +233,7 @@ mod tests { #[case::f64((-2000..2000).map(|i| i as f64).collect::>())] fn test_cuda_rle_decompress(#[case] values: Buffer) { let primitive_array = PrimitiveArray::new(values, Validity::NonNullable); - let array = RLEArray::encode(&primitive_array).vortex_unwrap(); + let array = RLEArray::encode(&primitive_array).vortex_expect("operation should succeed in test"); let ctx = CudaContext::new(0).unwrap(); ctx.set_blocking_synchronize().unwrap(); let unpacked = cuda_rle_decompress(&array, ctx).unwrap(); diff --git a/vortex-io/src/limit.rs b/vortex-io/src/limit.rs index 9d07256815a..52c7c4b285d 100644 --- a/vortex-io/src/limit.rs +++ b/vortex-io/src/limit.rs @@ -14,7 +14,7 @@ use pin_project_lite::pin_project; use tokio::sync::OwnedSemaphorePermit; use tokio::sync::Semaphore; use tokio::sync::TryAcquireError; -use vortex_error::VortexUnwrap; +use vortex_error::VortexExpect; pin_project! { /// [`Future`] that carries the amount of memory it will require to hold the completed value. @@ -84,7 +84,7 @@ where let permits = self .bytes_available .clone() - .acquire_many_owned(bytes.try_into().vortex_unwrap()) + .acquire_many_owned(bytes.try_into().vortex_expect("bytes must fit in u32")) .await .unwrap_or_else(|_| unreachable!("pushing to closed semaphore")); @@ -105,7 +105,7 @@ where match self .bytes_available .clone() - .try_acquire_many_owned(bytes.try_into().vortex_unwrap()) + .try_acquire_many_owned(bytes.try_into().vortex_expect("bytes must fit in u32")) { Ok(permits) => { let sized_fut = SizedFut { diff --git a/vortex-layout/src/gpu/layouts/flat/reader.rs b/vortex-layout/src/gpu/layouts/flat/reader.rs index 536913931cd..fd62335ac2e 100644 --- a/vortex-layout/src/gpu/layouts/flat/reader.rs +++ b/vortex-layout/src/gpu/layouts/flat/reader.rs @@ -12,8 +12,8 @@ use vortex_array::serde::ArrayParts; use vortex_array::stats::Precision; use vortex_dtype::DType; use vortex_dtype::FieldMask; +use vortex_error::VortexExpect as _; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap as _; use vortex_gpu::create_run_jit_kernel; use crate::GpuArrayFuture; @@ -46,7 +46,8 @@ impl GpuFlatReader { /// Register the segment request and return a future that would resolve into the deserialised array. fn array_future(&self) -> ShareGpuArrayFuture { - let row_count = usize::try_from(self.layout.row_count()).vortex_unwrap(); + let row_count = + usize::try_from(self.layout.row_count()).vortex_expect("row count must fit in usize"); // We create the segment_fut here to ensure we give the segment reader visibility into // how to prioritize this segment, even if the `array` future has already been initialized. diff --git a/vortex-layout/src/layouts/flat/reader.rs b/vortex-layout/src/layouts/flat/reader.rs index 39309911d93..5e85bca07fe 100644 --- a/vortex-layout/src/layouts/flat/reader.rs +++ b/vortex-layout/src/layouts/flat/reader.rs @@ -20,7 +20,6 @@ use vortex_dtype::DType; use vortex_dtype::FieldMask; use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap as _; use vortex_mask::Mask; use vortex_session::VortexSession; @@ -61,7 +60,8 @@ impl FlatReader { /// Register the segment request and return a future that would resolve into the deserialised array. fn array_future(&self) -> SharedArrayFuture { - let row_count = usize::try_from(self.layout.row_count()).vortex_unwrap(); + let row_count = + usize::try_from(self.layout.row_count()).vortex_expect("row count must fit in usize"); // We create the segment_fut here to ensure we give the segment reader visibility into // how to prioritize this segment, even if the `array` future has already been initialized. diff --git a/vortex-layout/src/layouts/flat/writer.rs b/vortex-layout/src/layouts/flat/writer.rs index 07402978aa6..6843697a762 100644 --- a/vortex-layout/src/layouts/flat/writer.rs +++ b/vortex-layout/src/layouts/flat/writer.rs @@ -182,7 +182,7 @@ mod tests { use vortex_dtype::FieldName; use vortex_dtype::FieldNames; use vortex_dtype::Nullability; - use vortex_error::VortexUnwrap; + use vortex_error::VortexExpect; use vortex_io::runtime::single::block_on; use vortex_mask::AllOr; @@ -248,7 +248,7 @@ mod tests { array .statistics() .compute_all(&Stat::all().collect::>()) - .vortex_unwrap() + .vortex_expect("stats computation should succeed for test array") .into_iter(), ); diff --git a/vortex-layout/src/layouts/zoned/zone_map.rs b/vortex-layout/src/layouts/zoned/zone_map.rs index 804fc2b680c..5a4fdad9ae8 100644 --- a/vortex-layout/src/layouts/zoned/zone_map.rs +++ b/vortex-layout/src/layouts/zoned/zone_map.rs @@ -288,7 +288,6 @@ mod tests { use vortex_dtype::Nullability; use vortex_dtype::PType; use vortex_error::VortexExpect; - use vortex_error::VortexUnwrap; use crate::layouts::zoned::MAX_IS_TRUNCATED; use crate::layouts::zoned::MIN_IS_TRUNCATED; @@ -308,8 +307,10 @@ mod tests { builder2.append_value("wait a minute"); let mut acc = StatsAccumulator::new(builder.dtype(), &[Stat::Max, Stat::Min, Stat::Sum], 12); - acc.push_chunk(&builder.finish()).vortex_unwrap(); - acc.push_chunk(&builder2.finish()).vortex_unwrap(); + acc.push_chunk(&builder.finish()) + .vortex_expect("push_chunk should succeed for test data"); + acc.push_chunk(&builder2.finish()) + .vortex_expect("push_chunk should succeed for test data"); let stats_table = acc.as_stats_table().vortex_expect("Must have stats table"); assert_eq!( stats_table.array.names().as_ref(), @@ -334,7 +335,8 @@ mod tests { fn always_adds_is_truncated_column() { let array = buffer![0, 1, 2].into_array(); let mut acc = StatsAccumulator::new(array.dtype(), &[Stat::Max, Stat::Min, Stat::Sum], 12); - acc.push_chunk(&array).vortex_unwrap(); + acc.push_chunk(&array) + .vortex_expect("push_chunk should succeed for test array"); let stats_table = acc.as_stats_table().vortex_expect("Must have stats table"); assert_eq!( stats_table.array.names().as_ref(), diff --git a/vortex-scalar/src/binary.rs b/vortex-scalar/src/binary.rs index 2c3232683c4..5c8c8060b2b 100644 --- a/vortex-scalar/src/binary.rs +++ b/vortex-scalar/src/binary.rs @@ -279,7 +279,6 @@ mod tests { use vortex_buffer::buffer; use vortex_dtype::Nullability; use vortex_error::VortexExpect; - use vortex_error::VortexUnwrap; use crate::BinaryScalar; use crate::Scalar; @@ -290,9 +289,10 @@ mod tests { let expected = Scalar::binary(buffer![0u8, 5], Nullability::NonNullable); assert_eq!( BinaryScalar::try_from(&binary) - .vortex_unwrap() + .vortex_expect("binary scalar conversion should succeed") .lower_bound(2), - BinaryScalar::try_from(&expected).vortex_unwrap() + BinaryScalar::try_from(&expected) + .vortex_expect("binary scalar conversion should succeed") ); } @@ -302,10 +302,11 @@ mod tests { let expected = Scalar::binary(buffer![0u8, 6, 0], Nullability::NonNullable); assert_eq!( BinaryScalar::try_from(&binary) - .vortex_unwrap() + .vortex_expect("binary scalar conversion should succeed") .upper_bound(3) .vortex_expect("must have upper bound"), - BinaryScalar::try_from(&expected).vortex_unwrap() + BinaryScalar::try_from(&expected) + .vortex_expect("binary scalar conversion should succeed") ); } @@ -314,7 +315,7 @@ mod tests { let binary = Scalar::binary(buffer![255u8, 255, 255], Nullability::NonNullable); assert!( BinaryScalar::try_from(&binary) - .vortex_unwrap() + .vortex_expect("binary scalar conversion should succeed") .upper_bound(2) .is_none() ); diff --git a/vortex-scalar/src/scalar_value.rs b/vortex-scalar/src/scalar_value.rs index 0e202f6bee8..6d6cf573146 100644 --- a/vortex-scalar/src/scalar_value.rs +++ b/vortex-scalar/src/scalar_value.rs @@ -11,8 +11,8 @@ use vortex_buffer::BufferString; use vortex_buffer::ByteBuffer; use vortex_dtype::NativeDType; use vortex_dtype::i256; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_bail; use vortex_error::vortex_err; use vortex_proto::scalar as pb; @@ -83,7 +83,7 @@ impl ScalarValue { pb_scalar .encode(&mut buf) .map_err(|e| vortex_err!("Failed to serialize protobuf {e}")) - .vortex_unwrap(); + .vortex_expect("protobuf encoding should succeed"); buf } diff --git a/vortex-scalar/src/utf8.rs b/vortex-scalar/src/utf8.rs index 01200070916..8b7b164ecb0 100644 --- a/vortex-scalar/src/utf8.rs +++ b/vortex-scalar/src/utf8.rs @@ -350,7 +350,6 @@ mod tests { use rstest::rstest; use vortex_dtype::Nullability; use vortex_error::VortexExpect; - use vortex_error::VortexUnwrap; use crate::Scalar; use crate::Utf8Scalar; @@ -360,8 +359,10 @@ mod tests { let utf8 = Scalar::utf8("snowman⛄️snowman", Nullability::NonNullable); let expected = Scalar::utf8("snowman", Nullability::NonNullable); assert_eq!( - Utf8Scalar::try_from(&utf8).vortex_unwrap().lower_bound(9), - Utf8Scalar::try_from(&expected).vortex_unwrap() + Utf8Scalar::try_from(&utf8) + .vortex_expect("utf8 scalar conversion should succeed") + .lower_bound(9), + Utf8Scalar::try_from(&expected).vortex_expect("utf8 scalar conversion should succeed") ); } @@ -371,10 +372,10 @@ mod tests { let expected = Scalar::utf8("chas", Nullability::NonNullable); assert_eq!( Utf8Scalar::try_from(&utf8) - .vortex_unwrap() + .vortex_expect("utf8 scalar conversion should succeed") .upper_bound(5) .vortex_expect("must have upper bound"), - Utf8Scalar::try_from(&expected).vortex_unwrap() + Utf8Scalar::try_from(&expected).vortex_expect("utf8 scalar conversion should succeed") ); } @@ -383,7 +384,7 @@ mod tests { let utf8 = Scalar::utf8("πŸ‚‘πŸ‚’πŸ‚“", Nullability::NonNullable); assert!( Utf8Scalar::try_from(&utf8) - .vortex_unwrap() + .vortex_expect("utf8 scalar conversion should succeed") .upper_bound(2) .is_none() ); diff --git a/vortex-tui/src/browse/app.rs b/vortex-tui/src/browse/app.rs index 38b8ab64da7..aae03f05e22 100644 --- a/vortex-tui/src/browse/app.rs +++ b/vortex-tui/src/browse/app.rs @@ -11,7 +11,6 @@ use vortex::array::serde::ArrayParts; use vortex::dtype::DType; use vortex::error::VortexExpect; use vortex::error::VortexResult; -use vortex::error::VortexUnwrap; use vortex::file::Footer; use vortex::file::OpenOptionsSessionExt; use vortex::file::SegmentSpec; @@ -104,9 +103,10 @@ impl LayoutCursor { /// NOTE: this is only safe to run against a FLAT layout. pub fn flatbuffer_size(&self) -> usize { let segment_id = self.layout.as_::().segment_id(); - let segment = block_on(self.segment_source.request(segment_id)).vortex_unwrap(); + let segment = block_on(self.segment_source.request(segment_id)) + .vortex_expect("operation should succeed in TUI"); ArrayParts::try_from(segment) - .vortex_unwrap() + .vortex_expect("operation should succeed in TUI") .metadata() .len() } diff --git a/vortex-tui/src/browse/ui/segments.rs b/vortex-tui/src/browse/ui/segments.rs index abed64388b5..ff563ea157f 100644 --- a/vortex-tui/src/browse/ui/segments.rs +++ b/vortex-tui/src/browse/ui/segments.rs @@ -31,7 +31,6 @@ use taffy::TraversePartialTree; use vortex::dtype::FieldName; use vortex::error::VortexExpect; use vortex::error::VortexResult; -use vortex::error::VortexUnwrap; use vortex::error::vortex_err; use vortex::file::SegmentSpec; use vortex::layout::Layout; @@ -110,7 +109,7 @@ pub fn segments_ui(app_state: &mut AppState, area: Rect, buf: &mut Buffer) { app_state.segment_grid_state.segment_tree = Some( to_display_segment_tree(segment_tree) .map_err(|e| vortex_err!("Fail to compute segment tree {e}")) - .vortex_unwrap(), + .vortex_expect("operation should succeed in TUI"), ); } @@ -125,7 +124,7 @@ pub fn segments_ui(app_state: &mut AppState, area: Rect, buf: &mut Buffer) { }; tree.compute_layout(*root_node, viewport_size) .map_err(|e| vortex_err!("Fail to compute layout {e}")) - .vortex_unwrap(); + .vortex_expect("operation should succeed in TUI"); app_state.frame_size = area.as_size(); let root_layout = tree.get_final_layout(*root_node); @@ -388,7 +387,8 @@ fn collect_segment_tree(root_layout: &dyn Layout, segments: &Arc<[SegmentSpec]>) segments: HashMap::new(), segment_ordering: Vec::new(), }; - segments_by_name_impl(root_layout, None, None, Some(0), segments, &mut tree).vortex_unwrap(); + segments_by_name_impl(root_layout, None, None, Some(0), segments, &mut tree) + .vortex_expect("operation should succeed in TUI"); tree } diff --git a/vortex-vector/src/binaryview/view.rs b/vortex-vector/src/binaryview/view.rs index 14e3f663fdb..56971026995 100644 --- a/vortex-vector/src/binaryview/view.rs +++ b/vortex-vector/src/binaryview/view.rs @@ -11,8 +11,8 @@ use std::ops::Range; use static_assertions::assert_eq_align; use static_assertions::assert_eq_size; use vortex_buffer::ByteBuffer; +use vortex_error::VortexExpect; use vortex_error::VortexResult; -use vortex_error::VortexUnwrap; use vortex_error::vortex_ensure; use vortex_error::vortex_err; @@ -55,7 +55,7 @@ impl Inlined { fn new(value: &[u8]) -> Self { debug_assert_eq!(value.len(), N); let mut inlined = Self { - size: N.try_into().vortex_unwrap(), + size: N.try_into().vortex_expect("inlined size must fit in u32"), data: [0u8; BinaryView::MAX_INLINED_SIZE], }; inlined.data[..N].copy_from_slice(&value[..N]); @@ -178,8 +178,10 @@ impl BinaryView { }, _ => Self { _ref: Ref { - size: u32::try_from(value.len()).vortex_unwrap(), - prefix: value[0..4].try_into().vortex_unwrap(), + size: u32::try_from(value.len()).vortex_expect("value length must fit in u32"), + prefix: value[0..4] + .try_into() + .vortex_expect("prefix must be exactly 4 bytes"), buffer_index: block, offset, }, From 9f47e6ee79ff039d366fa1d6e399c105f216a478 Mon Sep 17 00:00:00 2001 From: Connor Tsui <87130162+connortsui20@users.noreply.github.com> Date: Sat, 27 Dec 2025 09:52:44 +0900 Subject: [PATCH 7/8] Fix: decimal cast error message (#5821) This should also make sure that the fuzzer doesn't keep reporting the wrong error message. As for the TODO, see https://github.com/vortex-data/vortex/issues/5820 Signed-off-by: Connor Tsui Signed-off-by: amorynan --- vortex-array/src/arrays/decimal/compute/fill_null.rs | 10 ++++++---- vortex-array/src/compute/fill_null.rs | 8 ++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/vortex-array/src/arrays/decimal/compute/fill_null.rs b/vortex-array/src/arrays/decimal/compute/fill_null.rs index 0f17b9aa5c5..8d8016886b6 100644 --- a/vortex-array/src/arrays/decimal/compute/fill_null.rs +++ b/vortex-array/src/arrays/decimal/compute/fill_null.rs @@ -28,11 +28,13 @@ impl FillNullKernel for DecimalVTable { let is_invalid = is_valid.to_bool().bit_buffer().not(); match_each_decimal_value_type!(array.values_type(), |T| { let mut buffer = array.buffer::().into_mut(); - let fill_value = fill_value - .as_decimal() + let decimal_scalar = fill_value.as_decimal(); + let decimal_value = decimal_scalar .decimal_value() - .and_then(|v| v.cast::()) - .vortex_expect("top-level fill_null ensure non-null fill value"); + .vortex_expect("fill_null requires a non-null fill value"); + let fill_value = decimal_value + .cast::() + .vortex_expect("fill value does not fit in array's decimal storage type"); for invalid_index in is_invalid.set_indices() { buffer[invalid_index] = fill_value; } diff --git a/vortex-array/src/compute/fill_null.rs b/vortex-array/src/compute/fill_null.rs index 3c5379116d3..edbfd755d36 100644 --- a/vortex-array/src/compute/fill_null.rs +++ b/vortex-array/src/compute/fill_null.rs @@ -59,6 +59,14 @@ pub fn fill_null(array: &dyn Array, fill_value: &Scalar) -> VortexResult VortexResult; } From 4ba1a62173a0834dffff91a1e60481790ba2a053 Mon Sep 17 00:00:00 2001 From: Connor Tsui <87130162+connortsui20@users.noreply.github.com> Date: Sat, 27 Dec 2025 09:54:03 +0900 Subject: [PATCH 8/8] Fix: remove lance feature from vortex-bench CI (#5823) This should fix the random access and compression failures on the commit to develop workflow Signed-off-by: Connor Tsui Signed-off-by: amorynan --- .github/workflows/bench.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index c31e5a0c0b9..b1b416a5e71 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -66,9 +66,8 @@ jobs: shell: bash env: RUSTFLAGS: "-C target-cpu=native -C force-frame-pointers=yes" - # The main difference between this and `bench-pr.yml` is that we add the `lance` feature. run: | - cargo build --bin ${{ matrix.benchmark.id }} --package vortex-bench --profile release_debug --features lance + cargo build --bin ${{ matrix.benchmark.id }} --package vortex-bench --profile release_debug - name: Setup Polar Signals uses: polarsignals/gh-actions-ps-profiling@v0.6.0