Skip to content

Improve error message on invalid casts for structs #22730

Open
mkleen wants to merge 2 commits into
apache:mainfrom
mkleen:cast-null-fields-struct
Open

Improve error message on invalid casts for structs #22730
mkleen wants to merge 2 commits into
apache:mainfrom
mkleen:cast-null-fields-struct

Conversation

@mkleen
Copy link
Copy Markdown
Contributor

@mkleen mkleen commented Jun 3, 2026

Which issue does this PR close?

Rationale for this change

#22709 is a non-issue, the behavior is on purpose. This pr improves the error message for invalid casts for structs, making sure the exact error is not swallowed and avoid that it sound like it's a missing feature:

> select arrow_cast(struct(10), 'Struct("c0": non-null Int64)');
Optimizer rule 'simplify_expressions' failed
caused by
This feature is not implemented: Unsupported CAST from Struct("c0": Int64) to Struct("c0": non-null Int64)

becomes:

> select arrow_cast(struct(10), 'Struct("c0": non-null Int64)');
Optimizer rule 'simplify_expressions' failed
caused by
Error during planning: Cannot cast nullable struct field 'c0' to non-nullable field

The current cast behavior is on purpose see:

// Ensure nullability is compatible. It is invalid to cast a nullable
// source field to a non-nullable target field as this may discard
// null values.
if source_field.is_nullable() && !target_field.is_nullable() {
return _plan_err!(
"Cannot cast nullable struct field '{}' to non-nullable field",
target_field.name()
);
}
.

Most SQL systems treat NULL as a valid value of any type, so a cast that removes nullability would be logically inconsistent unless it raises an error on NULL input. On structs DuckDB/PSQL avoid this whole topic completely:

Since arrow allows non-null struct fields I would stick with the current behavior.

See also #19674 (comment)

What changes are included in this PR?

see above.

Are these changes tested?

Yes.

Are there any user-facing changes?

No.

@github-actions github-actions Bot added physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt) labels Jun 3, 2026
@mkleen mkleen changed the title Improve error message on cast structs to have non-nullable inner-fields Improve error message on cast structs Jun 3, 2026
fn can_cast_named_struct_types(source: &DataType, target: &DataType) -> bool {
validate_data_type_compatibility("", source, target).is_ok()
fn can_cast_named_struct_types(source: &DataType, target: &DataType) -> Result<bool> {
validate_data_type_compatibility("", source, target).map(|_| true)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This make sure that the error message is not swallowed here.

@mkleen mkleen force-pushed the cast-null-fields-struct branch 2 times, most recently from ecb535a to d1741b7 Compare June 3, 2026 11:51
@mkleen mkleen changed the title Improve error message on cast structs Improve error message on invalid casts for structs Jun 3, 2026
@mkleen mkleen force-pushed the cast-null-fields-struct branch from d1741b7 to 24e281c Compare June 3, 2026 12:44
@mkleen mkleen marked this pull request as ready for review June 3, 2026 14:38
@mkleen
Copy link
Copy Markdown
Contributor Author

mkleen commented Jun 5, 2026

@Jefffrey Could you maybe have a look at this?

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

Labels

physical-expr Changes to the physical-expr crates sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Be able to cast struct to have non-nullable inner field

1 participant