Skip to content

TRY_CAST rejects valid struct casts at planning time #26528

Open

Description

@ahlag

Describe the bug

TRY_CAST rejects some struct-to-struct casts at planning time even though CAST accepts them.

CAST validates struct casts by field name, allowing missing nullable fields in the target struct to be filled with NULL. In contrast, TRY_CAST uses Arrow's can_cast_types, which requires the source and target structs to have the same number of fields.

The runtime TryCastExpr already handles struct casts by field name. The inconsistency is therefore in the planning-time validation, which is stricter than necessary.

For example, casting STRUCT<x BIGINT> to STRUCT<x BIGINT, y VARCHAR> succeeds with CAST but fails during planning with TRY_CAST.

To Reproduce

Reproduced with DataFusion 55.2.0.

CAST succeeds:

SELECT cast(named_struct('x', 1) AS STRUCT<x BIGINT, y VARCHAR>) AS s;

Result:

{x: 1, y: }

TRY_CAST fails during planning:

SELECT try_cast(named_struct('x', 1) AS STRUCT<x BIGINT, y VARCHAR>) AS s;

Error:

This feature is not implemented: Unsupported TRY_CAST from Struct("x": Int64) to Struct("x": Int64, "y": Utf8View)

Expected behavior

TRY_CAST should accept this struct cast and return the same result as CAST:

{x: 1, y: }

More generally, TRY_CAST should accept at planning time every struct cast supported by CAST, while preserving its existing null-on-failure semantics.

Additional context

This issue was encountered in [delta-rs](delta-io/delta-rs#4889 (comment)), where a merge with schema evolution and safe_cast enabled failed because of this behavior.

As a workaround, [delta-rs PR #4917](delta-io/delta-rs#4917) uses CAST instead of TRY_CAST for widened fields.

Ion Koutsouris also noted that the same issue occurs in DataFusion 55.1.

Willingness to contribute

I plan to contribute a fix for this bug independently

Metadata

Metadata

Assignees

Labels

Prolific Authorauthor opened PRs or issues in more than 20 repositories in the last 30 daysbugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions