Skip to content

chore: bump DataFusion to 55.2.0 (arrow/parquet 59.3, MSRV 1.94) - #248

Merged
mwiewior merged 3 commits into
masterfrom
chore/bump-datafusion-55
Nov 13, 2026
Merged

mwiewior merged 3 commits into
masterfrom
chore/bump-datafusion-55

Conversation

@mwiewior

@mwiewior mwiewior commented Sep 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Moves the workspace from DataFusion 53.0.0 to 55.2.0 (arrow/parquet 59.3.2, rust-toolchain 1.94.0, which is DataFusion 55.2's MSRV).

Why now. DataFusion 53's external sorter frees its merge headroom and then re-acquires it from an empty reservation. Under FairSpillPool, with several partitions sorting concurrently, the last partition to enter its merge phase finds the pool full and fails with Resources exhausted ... ExternalSorterMerge[n] with 0.0 B already allocated. That is what kills the full-source SpliceAI plugin-cache builds on chr1/chr2 (biodatageeks/datafusion-bio-functions#235). No pool size or partition count fixes it, because the fair shares scale with the pool. apache/datafusion#20642 fixes the sorter and shipped in 54.0.0.

Refresh (2026-11-12): rebased onto master (v1.15.0, 24 commits), moved the pin from 55.0.0 to 55.2.0, and applied the same migration to the crates added since the first version: bio-format-msa, bio-format-structure, bio-format-foldcomp.

What changed

Almost entirely mechanical fallout of the 54/55 API changes, per the upstream upgrade guides:

  • as_any removed from DataFusion traits (trait upcasting): dropped from every ExecutionPlan / TableProvider / ScalarUDFImpl impl, .as_any() removed at the plan/provider downcast sites, unused std::any::Any imports removed. Arrow's Array::as_any is unaffected and untouched.
  • ExecutionPlan::apply_expressions is now required. No exec node in this workspace owns physical expressions, so all 25 are leaf implementations returning Continue.
  • partition_statistics returns Arc<Statistics>. The ensembl-cache scan's estimator is wrapped; its tests use StatisticsContext, the new caller-side API.
  • Test call sites moved off the deprecated with_new_children / required_input_distribution. This includes the new BED regression test from master.
  • New clippy lints from the 1.94 toolchain: bed doc comments, cram unwrap after is_some, and assertions_on_constants in the structure-codec bench harness.
  • CHANGELOG entry under Unreleased.

Not touched:

  • sandbox/cooler-spike (outside the workspace) still pins DataFusion 53 / arrow 58.
  • .github/workflows/structure-codecs-consumer.yml (manual dispatch only) builds a pinned DataFusion 53 polars-bio commit with Rust 1.91 and path-patches these crates into it. It cannot pass until polars-bio itself moves to DataFusion 55. That workflow's consumer pin needs re-pointing as part of the polars-bio bump.

Verification

  • cargo fmt --check, cargo clippy --workspace --all-targets --all-features -- -D warnings, and cargo doc --no-deps --all-features with RUSTDOCFLAGS=-D warnings are clean on 1.94.0.
  • cargo test --workspace --lib --all-features: 1047 passed, 0 failed.
  • Cargo.lock: one copy each of arrow / parquet / datafusion.
  • Downstream: chore: bump DataFusion to 55.2.0 and bio-formats to its DF 55 branch datafusion-bio-functions#332 pins this branch (d1eb0c3): clippy/doc clean, cargo test --all 1928 passed.

🤖 Generated with Claude Code

@mwiewior
mwiewior force-pushed the chore/bump-datafusion-55 branch from 8dae519 to d1eb0c3 Compare November 12, 2026 13:49
@mwiewior mwiewior changed the title chore: bump DataFusion to 55.0.0 (arrow/parquet 59.2, MSRV 1.94) chore: bump DataFusion to 55.2.0 (arrow/parquet 59.3, MSRV 1.94) Nov 12, 2026
@mwiewior

Copy link
Copy Markdown
Contributor Author

@claude review

@mwiewior

Copy link
Copy Markdown
Contributor Author

@codex review

@claude

claude Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

Claude finished @mwiewior's task in 2m 27s —— View job


PR Review: chore: bump DataFusion to 55.2.0

Tasks

  • Load review tools
  • Analyze git diff of PR changes
  • Review key changed files in depth
  • Post comprehensive review feedback

Summary

This is a mechanically thorough and correct DataFusion API migration. The changes are consistent across all 25 ExecutionPlan / TableProvider / ScalarUDFImpl implementations, the downstream verification story is solid (1047 + 1928 tests passing), and all the stated goals are achieved. No correctness or security issues found.


Findings

Bug (minor): CHANGELOG version mismatch

CHANGELOG.md:12 says arrow/parquet 59.2 but Cargo.lock and the PR title both say 59.3.2:

# Cargo.lock
name = "arrow"
version = "59.3.2"

The correct version to put in the CHANGELOG entry is 59.3.2 (or at minimum 59.3). Fix this →


Cosmetic: Stale test names and comments in FASTA and VCF write_exec

The call sites in tests were migrated from with_new_children → replace_children and required_input_distribution → input_distribution_requirements, but the function names and a comment weren't updated:

Not blocking — the tests are correct — but they'd confuse a future reader searching for with_new_children usage.


Observation: apply_expressions signature verbosity

The apply_expressions signature is repeated verbatim (fully qualified paths) across all 25 ExecutionPlan leaf implementations:

fn apply_expressions(
    &self,
    _f: &mut dyn FnMut(
        &std::sync::Arc<dyn datafusion::physical_expr::PhysicalExpr>,
    ) -> datafusion::common::Result<
        datafusion::common::tree_node::TreeNodeRecursion,
    >,
) -> datafusion::common::Result<datafusion::common::tree_node::TreeNodeRecursion> {
    Ok(datafusion::common::tree_node::TreeNodeRecursion::Continue)
}

Since every node is a leaf returning Continue, this is correct and cargo fmt accepts it. The verbosity is a consequence of avoiding new use imports in files that only removed the use std::any::Any import. Not a defect — just noting it in case a future cleanup pass wants to introduce use datafusion::common::{Result as DFResult, tree_node::TreeNodeRecursion} aliases to shorten this.


What looks good

  • Completeness: All 25 ExecutionPlan impls and all TableProvider / ScalarUDFImpl impls were updated uniformly. The search for remaining DataFusion-trait as_any() calls turned up none; the remaining as_any() usages are all Arrow Array::as_any() downcasts, which are correct and unaffected.
  • EnsemblCacheExec::partition_statistics refactoring: Clean extraction to partition_statistics_inner with .map(Arc::new) at the trait boundary. The test sites correctly use the new StatisticsContext::new().compute(...) caller API.
  • CRAM clippy fix: if reference_seqs.is_some() { ... .unwrap() } → if let Some(seqs) = reference_seqs.as_ref() is an improvement in both correctness-perception and style.
  • Structure-codecs harness: assert!(!cfg!(debug_assertions)) → if cfg!(debug_assertions) { panic!(...) } correctly suppresses the assertions_on_constants lint without changing semantics.
  • Sandbox isolation: sandbox/cooler-spike intentionally retains DataFusion 53; this is correctly called out in the PR description and not touched.
  • BED/BGEN/PGEN downcast: plan.as_any().downcast_ref::<T>() → plan.downcast_ref::<T>() is the right mechanical migration now that dyn ExecutionPlan has the Any supertrait removed from the external API.
  • VCF contradictory-bounds test: plan.as_any().is::<EmptyExec>() → plan.is::<EmptyExec>() is correct.
  • Single copy of arrow/parquet/datafusion in Cargo.lock: confirmed.

Verdict: Ready to merge after the CHANGELOG version correction (59.2 → 59.3.2). The stale test names are cosmetic and can be cleaned up at any time.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-13T17:10:04.815384Z 055e971 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: d1eb0c3764

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

mwiewior added a commit to biodatageeks/datafusion-bio-functions that referenced this pull request Nov 12, 2026
Follow biodatageeks/datafusion-bio-formats#248 to its review-nit commit
(test renames, shorter `apply_expressions` signatures, CHANGELOG arrow
version). No API change; vep and pileup stay on one formats rev.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@mwiewior

Copy link
Copy Markdown
Contributor Author

Thanks for the review. All three points are addressed in 99d7f81 (no behaviour change):

  1. CHANGELOG version. Fixed: the entry now says arrow/parquet 59.3.2, which matches Cargo.lock. I had updated the DataFusion version in that line during the rebase and missed the arrow one.

  2. Stale test names. Renamed to match the DataFusion 55 caller APIs their bodies use:

    • fasta test_with_new_children_wrong_count → test_replace_children_wrong_count
    • fasta test_with_new_children_preserves_properties → test_replace_children_preserves_properties
    • fasta test_required_input_distribution → test_input_distribution_requirements
    • vcf test_source_metadata_threaded_through_with_new_children → test_source_metadata_threaded_through_replace_children. Its inline comment changed too.

    The remaining fn with_new_children / fn required_input_distribution hits are trait implementations, which DataFusion 55 still requires, so they stay.

  3. apply_expressions verbosity. All 25 leaf impls now use imported Arc / PhysicalExpr / TreeNodeRecursion, plus Result in files that already import DataFusion's. Files without that import keep datafusion::common::Result rather than gaining an alias that could clash with a local Result. This matches the same cleanup in chore: bump DataFusion to 55.2.0 and bio-formats to its DF 55 branch datafusion-bio-functions#332.

Verification on 99d7f81:

  • cargo clippy --workspace --all-targets --all-features -- -D warnings, cargo fmt, RUSTDOCFLAGS=-D warnings cargo doc and the pre-commit hooks are clean.
  • fasta and vcf lib tests: 192 passed, 0 failed, with the four renamed tests running under their new names.

Downstream re-pins to 99d7f81:

Both lockfiles still have one copy each of datafusion-bio-format-core, datafusion and arrow.

🤖 Generated with Claude Code

@mwiewior

Copy link
Copy Markdown
Contributor Author

@codex review

@mwiewior

Copy link
Copy Markdown
Contributor Author

@claude review

@claude

claude Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Claude finished @mwiewior's task in 2m 47s —— View job


PR Review: chore: bump DataFusion to 55.2.0

Tasks

  • Load review tools
  • Analyze git diff of PR changes (both commits)
  • Verify previous review findings were addressed in 99d7f81
  • Review key changed files in depth
  • Post comprehensive review feedback

Summary

All three findings from the previous round are fully addressed in 99d7f81. No new correctness or security issues found. This is a clean, uniform, and complete DataFusion 55 migration.


Verification of Previous Findings

1. CHANGELOG version — fixed ✓

The entry now reads arrow/parquet 59.3.2, matching Cargo.lock.

2. Stale test names — fixed ✓

All four functions renamed correctly:

  • fasta: test_replace_children_wrong_count, test_replace_children_preserves_properties, test_input_distribution_requirements
  • vcf: test_source_metadata_threaded_through_replace_children with updated inline comment

The remaining fn with_new_children at vcf/src/write_exec.rs:182 is a trait implementation (still required by DataFusion 55), not a stale test name — correctly left alone.

3. apply_expressions verbosity — fixed ✓

All 25 leaf impls now use imported Arc / PhysicalExpr / TreeNodeRecursion, with Result used unqualified in files that already import DataFusion's. The result in files with a local Result correctly keeps the FQN to avoid ambiguity.


New Observations

Cosmetic: one apply_expressions still uses FQN Result

datafusion/bio-format-structure/src/table_provider.rs:212 already imports datafusion::common::Result via the grouped use datafusion::{ ..., common::Result, ... }, but the new apply_expressions body uses datafusion::common::Result<TreeNodeRecursion> rather than the shorter Result<TreeNodeRecursion>. Not a compiler error or logic issue — the nits cleanup in 99d7f81 touched this file (to add imports and remove as_any) but missed the FQN. Non-blocking; can be addressed in a later pass.

Undocumented CI matrix change

Both .github/workflows/structure-codecs-consumer.yml and .github/workflows/structures.yml changed macos-15 → macos-14 in the platform matrix (the ARM macOS runner). The PR description covers what wasn't touched in the workflows but doesn't mention this change. Looks like a routine runner-availability fix, but worth a one-liner in the description or commit message so reviewers aren't left wondering.


What Looks Good

  • Completeness: All 25 ExecutionPlan, all TableProvider, and all 8 ScalarUDFImpl implementations migrated consistently. Arrow Array::as_any() downcasts are correctly untouched throughout.
  • partition_statistics refactor: Clean extraction to partition_statistics_inner with .map(Arc::new) at the trait boundary; test sites correctly use StatisticsContext::new().compute(...).
  • CRAM if let fix: is_some() { .unwrap() } → if let Some(seqs) = reference_seqs.as_ref() confirmed at both callsites (lines 282 and 568).
  • BED/BGEN/PGEN/VCF downcast: plan.as_any().downcast_ref::<T>() / .is::<T>() → plan.downcast_ref::<T>() / plan.is::<T>() applied uniformly across all test sites.
  • BED regression test: replace_children with ReplaceChildrenOptions::new(ChildrenPropertiesMode::Recompute) is the correct new API.
  • Structure harness: if cfg!(debug_assertions) { panic!(...) } suppresses assertions_on_constants correctly.
  • Single dependency copies: Cargo.lock has exactly one entry each for arrow, parquet, and datafusion (confirmed: 3 unique matches, 1 each).
  • rust-toolchain.toml: pinned to 1.94.0 as required by DataFusion 55.2 MSRV.

Verdict: Ready to merge. The two observations above are cosmetic/documentation-only and non-blocking.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 99d7f810c4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

mwiewior and others added 3 commits November 13, 2026 17:50
Move the workspace from DataFusion 53.0.0 to 55.2.0. Besides the version
pins this is the mechanical fallout of the 54 and 55 API changes:

- `as_any` is gone from `ExecutionPlan`, `TableProvider` and
  `ScalarUDFImpl` (trait upcasting): drop it from every impl (including
  the msa, structure and foldcomp crates added since the first version of
  this change), drop the `.as_any()` hop at the plan/provider downcast
  sites, remove the now unused `std::any::Any` imports. Arrow
  `Array::as_any` is untouched.
- `ExecutionPlan::apply_expressions` is now required: no exec node in
  this workspace owns physical expressions, so all are leaf
  implementations that return `Continue`.
- `partition_statistics` returns `Arc<Statistics>`; the ensembl-cache
  scan's estimator is wrapped and its tests go through
  `StatisticsContext`, the new caller-side API.
- `with_new_children` / `required_input_distribution` call sites in tests
  move to `replace_children` / `input_distribution_requirements`.
- New clippy lints from the 1.94 toolchain (bed doc comments, cram
  unwrap-after-is_some, constant assertion in the structure-codec bench
  harness).

Why: DataFusion 53's external sorter frees its merge headroom and
re-acquires it from an empty reservation, which starves under
`FairSpillPool` when several partitions sort concurrently
(biodatageeks/datafusion-bio-functions#235). apache/datafusion#20642
fixes that and shipped in 54.0.0; 55.2.0 is the current release.

Not touched: `sandbox/cooler-spike` is outside the workspace and still
pins DataFusion 53 / arrow 58.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- CHANGELOG: the arrow/parquet version is 59.3.2, not 59.2.
- Rename the tests whose bodies moved to the DataFusion 55 caller APIs:
  fasta `test_with_new_children_wrong_count` /
  `test_with_new_children_preserves_properties` /
  `test_required_input_distribution` and vcf
  `test_source_metadata_threaded_through_with_new_children` now name
  `replace_children` / `input_distribution_requirements`, and the inline
  comment follows.
- The 25 leaf `apply_expressions` impls use imported `Arc` /
  `PhysicalExpr` / `TreeNodeRecursion` (and `Result` where the file
  already imports DataFusion's) instead of fully qualified paths,
  matching biodatageeks/datafusion-bio-functions#332.

No behaviour change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@mwiewior
mwiewior force-pushed the chore/bump-datafusion-55 branch from 99d7f81 to 055e971 Compare November 13, 2026 16:54
@mwiewior

Copy link
Copy Markdown
Contributor Author

Both observations from the second round are addressed. The branch is rebased onto master (94b06ab) and is now at 055e971.

  1. FQN Result in bio-format-structure. Fixed in 055e971. StructureExec::apply_expressions now uses the already-imported Result<TreeNodeRecursion>. I checked the other 24 leaf impls: the 10 that still spell out datafusion::common::Result have no DataFusion Result import, so they stay as they are, as explained in the previous round.
  2. macOS runner change (macos-15 → macos-14). This PR never changed a workflow. The branch was based on v1.15.0 (a754d55), before ci: move structure-reader macOS arm64 jobs off the retired macos-14 runner #273 (94b06ab) moved those jobs from macos-14 to macos-15. Against current master, a two-dot diff showed ci: move structure-reader macOS arm64 jobs off the retired macos-14 runner #273 as if this PR reverted it. Since the rebase, git diff origin/master...HEAD -- .github is empty.

Verification on 055e971:

  • cargo fmt --all -- --check and cargo clippy --workspace --all-targets --all-features -- -D warnings are clean.
  • cargo test -p datafusion-bio-format-structure: all passed, 0 failed.

🤖 Generated with Claude Code

@mwiewior

Copy link
Copy Markdown
Contributor Author

@claude review

@mwiewior

Copy link
Copy Markdown
Contributor Author

@codex review

@claude

claude Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Claude finished @mwiewior's task in 2m 20s —— View job


PR Review: chore: bump DataFusion to 55.2.0

Tasks

  • Load review tools
  • Analyze git diff (HEAD vs origin/master)
  • Verify previous round-2 findings are addressed in 055e971
  • Review key changed files in depth
  • Post comprehensive review feedback

Summary

This is a clean, complete, and consistent DataFusion 55 migration. All findings from the previous two review rounds are fully addressed. No new correctness or security issues found.


Verification of Round-2 Findings

1. FQN Result in StructureExec::apply_expressions — fixed ✓

055e971 changed both occurrences in bio-format-structure/src/table_provider.rs:215–218 from datafusion::common::Result<TreeNodeRecursion> to the already-imported Result<TreeNodeRecursion>, matching all other files that have a DataFusion Result import.

2. macOS runner change — was rebase artifact, now gone ✓

git diff origin/master...HEAD -- .github is empty. The difference noted in round 2 was produced by a two-dot diff against an older base; against the rebased master (94b06ab) the workflow files are unchanged.


Positive verification pass

  • 25 apply_expressions leaf impls: confirmed via grep — exactly 25 occurrences across 25 files, one per exec/plan node.
  • Zero DataFusion-trait fn as_any remaining: grepping the datafusion/ tree returns no matches. All remaining .as_any() calls are Arrow Array::as_any() downcasts, which are unaffected.
  • crate::errors::Result<T> in ensembl-cache is type Result<T> = datafusion::common::Result<T> — so EnsemblCacheExec::apply_expressions using the local Result alias is correct and type-compatible.
  • partition_statistics → Arc<Statistics>: partition_statistics_inner extraction and .map(Arc::new) wrapper confirmed; test sites correctly use StatisticsContext::new().compute(&exec, &StatisticsArgs::new().with_partition(...)).
  • Test renames (round 1): all four confirmed — test_replace_children_wrong_count, test_replace_children_preserves_properties, test_input_distribution_requirements (fasta), test_source_metadata_threaded_through_replace_children (vcf) with updated inline comment.
  • Downcast migrations: plan.as_any().downcast_ref::<T>() → plan.downcast_ref::<T>() and plan.as_any().is::<T>() → plan.is::<T>() applied uniformly across PGEN (7 sites), BGEN (6 sites), VCF (1 site).
  • BED regression test: replace_children(vec![...], ReplaceChildrenOptions::new(ChildrenPropertiesMode::Recompute)) correctly replaces the deprecated with_new_children call.
  • CHANGELOG: arrow/parquet 59.3.2 — matches Cargo.lock (arrow 59.3.2, parquet same).
  • Cargo.lock: single copies of datafusion (55.2.0), arrow (59.3.2), parquet — confirmed (1 occurrence each).
  • rust-toolchain.toml: 1.91.0 → 1.94.0 ✓
  • CRAM if let Some: both callsites (lines 279, 565) updated ✓
  • Structure harness: if cfg!(debug_assertions) { panic!(...) } suppresses assertions_on_constants lint correctly ✓

Verdict: Ready to merge.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 055e971164

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@mwiewior
mwiewior merged commit 86e12c0 into master Nov 13, 2026
14 of 16 checks passed
mwiewior added a commit to biodatageeks/datafusion-bio-functions that referenced this pull request Nov 14, 2026
Move every datafusion-bio-format-* dependency (vep and pileup) from the
pre-release rev to tag v1.16.0, which contains the DataFusion 55.2 bump
(biodatageeks/datafusion-bio-formats#248) and the OpenDAL 0.59.5 fix for
remote reads that retried forever under tokio 1.54 (#274). The lockfile
keeps a single copy of datafusion-bio-format-core, datafusion, arrow and
parquet, and drops the OpenDAL git revision.

Also import Session and PhysicalPlanningContext in the ranges planners
instead of spelling out their paths inline (review nit).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
mwiewior added a commit to biodatageeks/datafusion-bio-functions that referenced this pull request Nov 14, 2026
…332)

* chore: bump DataFusion to 55.2.0 and bio-formats to its DF 55 branch

Move the workspace from DataFusion 53.0.0 to 55.2.0 (arrow/parquet 59.3.2,
rust-toolchain and CI on 1.94.0, DataFusion 55.2's MSRV) and pin every
datafusion-bio-format-* dependency to biodatageeks/datafusion-bio-formats#248
(d1eb0c3), which carries the same bump rebased on formats v1.15.0, so it
includes everything the previous e0379fb pin did. pileup and vep share that
one rev so the graph holds one copy of datafusion-bio-format-core and
DataFusion.

Mechanical fallout of the 54/55 API changes:
- `as_any` removed from DataFusion traits: dropped from every impl, the
  `.as_any()` hop removed at plan/expr downcast sites (including the
  multi-line chains in the interval planner), unused `Any` imports
  removed. fastqc's own `QcModule::as_any` is unrelated and kept.
- `ExecutionPlan::apply_expressions` required: leaf implementations for
  the nodes without expressions; `IntervalJoinExec` visits its join keys
  and filter like DataFusion's own `HashJoinExec`.
- `QueryPlanner` / `PhysicalPlanner` take `&dyn Session`, and
  `create_physical_expr` gains the `PhysicalPlanningContext` argument.
- `create_hashes` takes DataFusion's `HashState`; the interval join uses
  `datafusion::common::hash_utils::RandomState` (ahash stays for the
  plain hash maps).
- `Distribution::HashPartitioned` -> `KeyPartitioned`.
- `MemoryPool` now requires `Display` and `name()`: TracingPool and the
  test-only RejectHashPool.
- `MutableArrayData::extend` is deprecated in arrow 59.3: the SIFT page
  gather uses `try_extend` and propagates the overflow error.
- `partition_statistics` returns `Arc<Statistics>` and is deprecated for
  callers; the interval join estimator and the plugin-cache join
  selector read statistics through `StatisticsContext`.

That last item is the one behavioural change. Under DataFusion 55 the
deprecated `partition_statistics` returns unknown statistics for
DataFusion's own nodes, so `choose_for_hash_plan` would have reported
MissingStatistics and silently forced every plugin-cache tier join onto
SortMergeJoin; the adaptive-join tests cover it.

Why: DataFusion 53's external sorter frees its merge headroom and then
re-acquires it from an empty reservation, which starves under
`FairSpillPool` when several partitions sort concurrently (#235).
apache/datafusion#20642 fixes that and shipped in 54.0.0.

Not touched: `research/lance_encoding_sandbox` is outside the workspace
and still pins arrow 58 / datafusion-common 53.

Supersedes #236 and dependabot #8.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* refactor: address review nits on the DataFusion 55.2 bump

- interval join: say why `hash_utils::RandomState::default()` is safe
  (foldhash `FixedState` with a compile-time constant seed, shared by
  both join sides), and fold `partition_statistics_inner` back into
  `partition_statistics` where it lived before the bump, with a note on
  why the partition argument is ignored. Drop the stray blank line left
  by the `Any` import removal.
- plugin-cache join selector: import `StatisticsContext` /
  `StatisticsArgs` instead of spelling the full paths inline.
- the ten leaf `apply_expressions` impls (fastqc, pileup, ranges, vep):
  use imported `Arc` / `PhysicalExpr` / `Result` / `TreeNodeRecursion`
  instead of fully qualified paths.

No behaviour change.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore: re-pin datafusion-bio-formats to 99d7f81

Follow biodatageeks/datafusion-bio-formats#248 to its review-nit commit
(test renames, shorter `apply_expressions` signatures, CHANGELOG arrow
version). No API change; vep and pileup stay on one formats rev.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore: pin datafusion-bio-formats to the v1.16.0 release

Move every datafusion-bio-format-* dependency (vep and pileup) from the
pre-release rev to tag v1.16.0, which contains the DataFusion 55.2 bump
(biodatageeks/datafusion-bio-formats#248) and the OpenDAL 0.59.5 fix for
remote reads that retried forever under tokio 1.54 (#274). The lockfile
keeps a single copy of datafusion-bio-format-core, datafusion, arrow and
parquet, and drops the OpenDAL git revision.

Also import Session and PhysicalPlanningContext in the ranges planners
instead of spelling out their paths inline (review nit).

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
mwiewior added a commit to biodatageeks/polars-bio that referenced this pull request Nov 14, 2026
* chore: bump DataFusion to 55.2.0 and PyO3 to 0.29

Move from DataFusion 53.0.0 to 55.2.0 together with the bio crates:
- datafusion 55.2.0, datafusion-python 55.0.0 (the newest published; it
  requires datafusion ^55.1.0, so the graph keeps one DataFusion 55.2.0)
- pyo3 0.28.3 -> 0.29.3, the line datafusion-python 55 and arrow-pyarrow
  59 require; pyo3-log 0.13.5 is the first release accepting pyo3 0.29
- arrow / arrow-schema / arrow-array 59.3.2
- rust-toolchain 1.94.0 (DataFusion 55.2's MSRV)
- Python `datafusion>=55.0.0,<56` in pyproject, uv.lock and the
  in-repo bioconda recipe
- datafusion-bio-format-* pinned to biodatageeks/datafusion-bio-formats#248
  (d1eb0c3) and datafusion-bio-function-* to
  biodatageeks/datafusion-bio-functions#332 (1099515) until both are
  tagged

Rust changes are the DataFusion 55 trait fallout only: `as_any` dropped
from the fastqc and depth table providers and from SchemaOverrideExec,
which also gets a leaf `apply_expressions` (it owns no physical
expressions). None of PyO3 0.29's breaking APIs are used here.

test_runtime_memory_limit_spills moves from a 2 MB to an 8 MB pool.
DataFusion 55's grouped aggregation needs more headroom before it can
spill: at 2 MB its hash table fills the pool and the follow-up
allocation fails with Resources exhausted (DataFusion 53 spilled 91
times there). From 4 MB up it spills and returns all 1M groups (4 MB: 31
spills, 8 MB: 15), so the test still exercises spilling.

Why: DataFusion 53's external sorter starves under FairSpillPool when
several partitions sort concurrently; apache/datafusion#20642 fixes it
in 54.0.0, and the bio crates already moved for it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* fix: pin the abi3 floor to 3.11 and build one wheel per platform

CI on the bump built a `cp314-abi3` Windows wheel, installable only on
Python 3.14+. With the bare `abi3` feature, PyO3 0.29 takes the abi3
floor from the build interpreter, and maturin's `--find-interpreter` on
the Windows runner found 3.14 first. Verified locally: the same tree
built against 3.14 gives `cp314-abi3`, against 3.11 `cp311-abi3`. The
`abi3-py311` feature matches `requires-python = ">=3.11"` and gives
`cp311-abi3` from any interpreter (checked by building with 3.14 and
running the wheel under 3.14).

The manylinux image also has 3.14t and PyPy 3.11, which abi3 cannot
cover. maturin added version-specific wheels for them, which broke the
smoke test's `pip install dist/*.whl` and would have published untested
free-threaded and PyPy wheels. Linux builds now target CPython 3.11 only,
so every platform ships one abi3 wheel as before the bump.

Also from review:
- OpenSpec delta (Codex P1): the MODIFIED requirement now carries the
  full current text, including the Polars exception and its scenario,
  so archiving does not drop them. The abi3 floor is recorded as an
  ADDED requirement.
- `SchemaOverrideExec::apply_expressions` uses imported names instead
  of fully qualified paths (Claude review nit).
- Re-pin datafusion-bio-formats to 99d7f81 (#248) and
  datafusion-bio-functions to 08a9e63 (#332), their review-nit commits.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* chore: pin bio-formats v1.16.0 and bio-functions v0.25.0

Move every datafusion-bio-format-* dependency from rev 99d7f81 to tag
v1.16.0 and every datafusion-bio-function-* dependency from rev 08a9e63
to tag v0.25.0, the DataFusion 55 releases of both. bio-formats v1.16.0
also moves OpenDAL to 0.59.5, so a remote read that fails mid-stream
returns an error instead of retrying forever under tokio 1.54
(biodatageeks/datafusion-bio-formats#274).

Cargo.lock keeps one copy each of datafusion-bio-format-core,
datafusion, arrow and parquet. Mark OpenSpec task 1.11 done.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant