Skip to content

fix: remove stale Interval -> Int64 arm from can_cast_types - #10939

Open
dylanpulver wants to merge 1 commit into
apache:mainfrom
dylanpulver:fix-can-cast-interval-to-int64
Open

fix: remove stale Interval -> Int64 arm from can_cast_types#10939
dylanpulver wants to merge 1 commit into
apache:mainfrom
dylanpulver:fix-can-cast-interval-to-int64

Conversation

@dylanpulver

@dylanpulver dylanpulver commented Sep 1, 2026

Copy link
Copy Markdown

Which issue does this PR close?

Rationale for this change

can_cast_types promised Interval(YearMonth) -> Int64 and Interval(DayTime) -> Int64; cast_with_options has no such arm and errors. #5769 removed the cast side deliberately and left the can_cast_types arm behind, so this restores the intended state rather than adding a cast. The user-visible effect is in cast/union.rs::resolve_child_array, which picks the first union child can_cast_types accepts: a union with an interval child and a Utf8 child failed to cast to Int64 even though the Utf8 child casts fine.

If you would rather have Interval -> Int64 actually implemented, this is the wrong direction and I am happy to close it — that would be a feature rather than a fix.

What changes are included in this PR?

The (Interval(_), Int64) arm is removed from can_cast_types. arrow/tests/array_cast.rs::get_all_types() gets Int64 back: it currently reads Int8, Int16, Int32, UInt64, UInt8, UInt16, UInt32, UInt64, so Int64 was never used as a cast target. Line 568 of that file has the intended sequence.

Are these changes tested?

Matched pair, cargo test -p arrow --features="chrono-tz prettyprint" --test array_cast test_can_cast_types: passes on unmodified main; with only Int64 restored and no source change it fails with from Interval(YearMonth) to Int64 but can_cast_types reported true; with both changes it passes. Restoring Int64 exposed that one mismatch and no others.

Two unit tests added in arrow-cast: test_can_cast_interval_to_int64_matches_cast asserts can_cast_types == cast(..).is_ok() for all three interval units rather than hard coding the answer, and test_cast_union_to_int64_skips_uncastable_interval_child covers the union path.

Reverting the source with the tests in place fails both of them and the integration test. A half fix (YearMonth => false, DayTime => true) still passes the union test but fails the enumerating one on Interval(DayTime), which is why the enumeration is there — test_can_cast_types panics on the first mismatch and would only ever have shown YearMonth.

cargo fmt --all -- --check clean, cargo clippy -p arrow-cast --all-targets -- -D warnings clean, cargo test -p arrow-cast 379 passed + 11 doc tests, --test array_cast 10 passed. rustc 1.97.1, matching rust-toolchain.toml.

Not tested: full workspace, miri, force_validate, --all-features, benchmarks. My sweep for other stale arms of this class was dispatch-level over null arrays, so value-level cast bugs were not covered.

Are there any user-facing changes?

can_cast_types(Interval(YearMonth) | Interval(DayTime), Int64) returns false instead of true. Nothing could have relied on the true, since the cast always failed. Casting a union to Int64 now succeeds in cases that previously errored.


AI disclosure, per CONTRIBUTING: the investigation, the patch and the tests were produced with AI assistance (Claude Opus 5). The measurements quoted above were run against this branch.

…st` cannot do

`can_cast_types` reported `true` for `Interval(YearMonth) -> Int64` and
`Interval(DayTime) -> Int64`, but `cast_with_options` has no such arm and returns
`CastError("Casting from Interval(YearMonth) to Int64 not supported")`.

Both sides were added together in apache#1196. apache#5769 made `IntervalDayTime` and
`IntervalMonthDayNano` structured types and deliberately removed the
`Interval <-> Int64` cast support, but left the `can_cast_types` arm behind.

This is not only an API-consistency issue. `cast/union.rs::resolve_child_array`
picks the first union child that `can_cast_types` accepts, so casting a union
containing an interval child to `Int64` selected the interval child and failed,
even when another child (e.g. `Utf8`) could actually be cast.

`arrow/tests/array_cast.rs::test_can_cast_types` exists to keep the two in sync
and did not catch this: `Int64` was missing from `get_all_types()`, where
`UInt64` appears in its place and then again in its own position. Restoring
`Int64` makes that test fail on main, and it is the only mismatch it exposes.
@github-actions github-actions Bot added arrow Changes to the arrow crate arrow-cast labels Sep 1, 2026

@Rich-T-kid Rich-T-kid left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the fix @dylanpulver.

I think we can trim this PR a bit, I left some suggestions

Comment on lines +324 to +327
// Note: there is deliberately no `(Interval(_), Int64)` arm. No interval unit has an
// unambiguous `i64` value (`YearMonth` is a count of months, `DayTime` packs days and
// milliseconds, `MonthDayNano` is 128 bits wide), and `cast_with_options` implements no
// such cast. Cast via `Duration` instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is strictly needed. we don't need to explain why certain cast don't exist.

if you think its still warranted I think we should shorted this.

Comment on lines +12451 to +12452
#[test]
fn test_can_cast_interval_to_int64_matches_cast() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar Idea for these test, I think we can add one test that asserts

  1. can_cast_types() reports false for interval(yearMonth/dayTime) -> int64
  2. cast(yearMonth/dayTime,int64) fails with an error as expected

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arrow Changes to the arrow crate arrow-cast

Projects

None yet

Development

Successfully merging this pull request may close these issues.

can_cast_types reports Interval -> Int64 as supported, but cast has no such arm

2 participants