0.87.0

Released 2026-10-02 — GitHub Release

Changes

⚠️ Breaks

  • break: probe_scalar must resolve validity internally (#10134) @joseph-isaacs

  • Move BitPacked serde logic from VTable to Plugin (#9937) @mhk197

  • ScalarFnVtable’s validity is parametrized by ReduceNode (#9932) @myrrc

  • Move the UUID extension dtype into encodings/uuid (#9588) @joseph-isaacs

  • Move FoR serde logic from VTable to Plugin (#10104) @mhk197

  • Register Delta, Zstd and Pco in the compression session, exclude them by builder mode (#10069) @mhk197

  • Filter compressor schemes by the session’s allowed serialized IDs on build (#10067) @mhk197

  • Remove unused unbound expression analysis and traversal helpers (#9993) @mhk197

  • Move compression schemes to CompressionSession and construct BtrBlocksCompressorBuilder from Session (#10066) @mhk197

  • Bind expressions before optimizing (#10002) @mhk197

  • break: nth_child to return reference instead of clone (#10051) @joseph-isaacs

  • fix(array): honor the execution allocator for RowFn outputs (#10014) @connortsui20

  • fix(array): require unsafe row initialization evidence (#10013) @connortsui20

  • Support i128 and i256 decimals in DecimalByteParts encoding (#9834) @mhk197

  • Rework AggregateVTable (#9816) @robert3005

  • Filter compression schemes by serialized IDs instead of array IDs (#9914) @mhk197

  • feat(array): scalar probes with one-off and repeated probe types (#9843) @joseph-isaacs

  • ffi: create bool arrays (#8899) @myrrc

✨ Features

  • bench(statpopgen): run the suite on DataFusion as well as DuckDB (#10212) @joseph-isaacs

  • Execute FoR iteratively (#10156) @joseph-isaacs

  • Refine FoRScheme to per-chunk references when fastlanes.for.v2 is allowed (#10136) @mhk197

  • Encode/Decode Kernels for BlockedFoR (#10118) @mhk197

  • Add SQL null semantics to list_contains (#10057) @robert3005

  • Blocked FoR with one reference per 1024-element chunk (#10105) @mhk197

  • Fold and/or constants on Arrays during .optimize() (#9997) @myrrc

  • feat(row): upstream vendored dtype and list key support (#10031) @gatesn

  • reduce is_null(array) to array’s validity (#9981) @myrrc

  • Add vortex.is_nan expression with stats-based pruning (#9949) @Ecthlion

  • feat(cmake): forward linker selection to Cargo (#9976) @0ax1

  • feat(cuda): support column projection and dictionary decoding in file scans (#9934) @0ax1

  • duckdb: return projection_ids handling (#9887) @myrrc

  • Add BoolArray::trim_bits, wire it to Canonical::compact that prunes unused bytes in the underlying buffer (#9374) @robert3005

  • feat: C/C++ API shared library targets (#9878) @0ax1

  • fix: support decimal-to-integer array casts (#9873) @XiangpengHao

  • refactor(array): allocate execution outputs through context (#9671) @gatesn

🚀 Performance

  • Optimise Patches::filter to better handle sparse masks and sparse patches (#10149) @robert3005

  • perf(compressor): count narrow integer ranges without hashing (#10041) @robert3005

  • perf(compressor): run-aware integer stats loop (#10037) @a10y

  • Reduce lazy masks into arrays with all-valid metadata (#10016) @connortsui20

  • feat: reduce allocations in Spark Decimal access (#9842) @xiaoh1024

  • perf(array): pack Boolean output during RowFn dense retry (#9986) @connortsui20

  • perf: specialize comparison bitmap packing for 8-bit inputs (#9948) @mhk197

  • perf(array): reduce RowFn UTF-8 decode overhead (#9985) @connortsui20

  • perf(array): reuse probe state in RLE, RunEnd and PCO (#9844) @joseph-isaacs

  • Support creating accumulators with already derived dtypes (#9972) @robert3005

  • perf(cuda): pipeline local file reads through cacheable pinned buffers (#9936) @0ax1

  • move Buffer/BufferMut panic helpers into separate functions (#9927) @myrrc

  • Move panic case in vortex_expect/bail/ensure to a cold handler (#9903) @myrrc

  • Constant canonicalisation uses similar techniques to SparseArray (#9889) @robert3005

  • perf: specialize whole-array sums for run-end arrays (#9823) @connortsui20

🐛 Bug Fixes

37 changes
  • fix(datafusion): skip projection pushdown for projections with lambdas (#10215) @joseph-isaacs

  • Fix FoR CastReduce kernel (#10169) @mhk197

  • fix(bench): write random-access Parquet with zstd level 3 (#10157) @joseph-isaacs

  • Reject get_field pushdown when its source cannot convert (#10083) @RainyPixel

  • fix(fsst, onpair): validate decoded lengths before allocation (#10110) @lorenzhs

  • Remove default-features from vortex -> vortex-file dependency (#10117) @robert3005

  • Fix wasm32-unknown-unknown regression, add a test to cover it (#10108) @robert3005

  • Canonicalize dictionary take results before downcasting (#10081) @RainyPixel

  • Gate compat fixture writes with editions (#10077) @mhk197

  • Make benchmark ingestion conflict-free and validate before transactions (#10073) @connortsui20

  • fix(python): treat a single-letter URL scheme as a filesystem path (#9957) @jackylee-ch

  • fix(row): compare fuzz list prefixes by length (#10033) @gatesn

  • fix(buffer): avoid shrinking allocations through grow (#10030) @connortsui20

  • list_contains([], null) = false (#10028) @myrrc

  • fix(layout): reject a zone map whose zone count disagrees with the layout (#9974) @jackylee-ch

  • Preserve Boolean buffer handles during mask reduction (#10018) @connortsui20

  • fix: alignment and padding of sliced CUDA Arrow bitmaps (#9926) @0ax1

  • fix(datafusion): report an unconvertible column statistic as absent (#9973) @jackylee-ch

  • Remove DeltaScheme from default BtrBlocksCompressor (#9967) @robert3005

  • fix(layout): reject a zone map whose zones overrun the layout row count (#9963) @jackylee-ch

  • Remove Delta compression hand-application from RLE and OnPair (#9964) @joseph-isaacs

  • fix: honor cmake BUILD_SHARED_LIBS (#9962) @0ax1

  • fix(duckdb): report an error instead of asserting when a decimal precision exceeds 38 (#9961) @jackylee-ch

  • ci: bypass broken CodSpeed simulation instrument cache (#9959) @0ax1

  • fix(python): build Decimal scalars from the unscaled integer and an exponent (#9885) @jackylee-ch

  • fix: honor the embedding project’s CUDA toolchain (#9929) @0ax1

  • Added support for REE scalars to scalar_from_df (#9931) @thorfour

  • fix: preserve device buffers when slicing decimal arrays (#9925) @0ax1

  • duckdb: disable function serialization (#9891) @myrrc

  • Add TPC-DS SLT plan tests (#9861) @joseph-isaacs

  • fix(buffer): include the bit offset in BitBufferMut::from_buffer’s bounds check (#9879) @jackylee-ch

  • ZSTDArray::append_to_builder falls back to canonical for non utf8/binary dtypes (#9897) @robert3005

  • Replace MaybeUninit transmutes with write_copy_of_slice (#9814) @robert3005

  • fix(array): convert f16 to signed integers instead of always failing (#9862) @jackylee-ch

  • Fix UB in reinterpreting 8-byte aligned memory range as alignment 1 (#9865) @myrrc

  • Resolve object-store URLs in the FFI via the cloud registry (#9558) @balicat

  • fix(python): match Python range semantics for empty and descending ranges (#9781) @jackylee-ch

📖 Documentation

5 changes

🧰 Maintenance

56 changes