Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion datafusion/substrait/src/logical_plan/consumer/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,8 @@ fn ensure_field_compatibility(
if !DFSchema::datatype_is_logically_equal(
datafusion_field.data_type(),
substrait_field.data_type(),
) {
) && !is_safe_widening(datafusion_field.data_type(), substrait_field.data_type())
{
return substrait_err!(
"Field '{}' in Substrait schema has a different type ({}) than the corresponding field in the table schema ({}).",
substrait_field.name(),
Expand All @@ -348,6 +349,25 @@ fn ensure_field_compatibility(
Ok(())
}

/// Ensures that the given datafusion type can safely promoted to
/// Substrait type, declared in the plan, without loss of precision.
fn is_safe_widening(datafusion_type: &DataType, substrait_type: &DataType) -> bool {
matches!(
(datafusion_type, substrait_type),
// Signed integer widening
(DataType::Int8, DataType::Int16 | DataType::Int32 | DataType::Int64)
| (DataType::Int16, DataType::Int32 | DataType::Int64)
| (DataType::Int32, DataType::Int64)
// Unsigned integer widening
| (DataType::UInt8, DataType::UInt16 | DataType::UInt32 | DataType::UInt64)
| (DataType::UInt16, DataType::UInt32 | DataType::UInt64)
| (DataType::UInt32, DataType::UInt64)
// Float widening
| (DataType::Float16, DataType::Float32 | DataType::Float64)
| (DataType::Float32, DataType::Float64)
)
}

/// Returns true if the DataFusion and Substrait nullabilities are compatible, false otherwise
fn compatible_nullabilities(
datafusion_nullability: bool,
Expand Down
Loading