Skip to content

Commit 82386a4

Browse files
committed
Refactor scalar expression casting in physical mutation logic
Simplify and correct the handling of scalar and column data type mismatches by introducing intermediate casting logic.Fixed potential issues with nullable type handling in conditional expressions.
1 parent 64d0780 commit 82386a4

File tree

1 file changed

+15
-17
lines changed

1 file changed

+15
-17
lines changed

src/query/sql/src/executor/physical_plans/physical_mutation.rs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -656,14 +656,26 @@ pub fn generate_update_list(
656656
Vec::with_capacity(update_list.len()),
657657
|mut acc, (index, scalar)| {
658658
let field = schema.field(*index);
659+
let data_type = scalar.data_type()?;
659660
let target_type = field.data_type();
660-
let nullable_type = target_type.wrap_nullable();
661+
let left = if data_type != *target_type {
662+
// change scalar's column datatype
663+
let mut tmp_scalar = scalar.clone();
664+
if data_type.wrap_nullable() == *target_type {
665+
if let ScalarExpr::BoundColumnRef(ref mut bound_ref) = tmp_scalar {
666+
bound_ref.column.data_type = Box::new(target_type.clone());
667+
}
668+
}
669+
wrap_cast(&tmp_scalar, target_type)
670+
} else {
671+
scalar.clone()
672+
};
661673

662674
let scalar = if col_indices.is_empty() {
663675
// The condition is always true.
664676
// Replace column to the result of the following expression:
665677
// CAST(expression, type)
666-
wrap_cast(scalar, &nullable_type)
678+
left
667679
} else {
668680
// Replace column to the result of the following expression:
669681
// if(condition, CAST(expression, type), column)
@@ -675,30 +687,16 @@ pub fn generate_update_list(
675687
field.name(),
676688
column_binding,
677689
) {
678-
// Create a new column_binding, ensuring its type is nullable
679-
let mut column = column_binding.clone();
680-
column.data_type = Box::new(nullable_type.clone());
681690
right = Some(ScalarExpr::BoundColumnRef(BoundColumnRef {
682691
span: None,
683-
column,
692+
column: column_binding.clone(),
684693
}));
685694
break;
686695
}
687696
}
688697

689698
let right = right.ok_or_else(|| ErrorCode::Internal("It's a bug"))?;
690699

691-
// Ensure the scalar type is also nullable
692-
let mut scalar = scalar.clone();
693-
if let ScalarExpr::BoundColumnRef(ref mut bound_ref) = scalar {
694-
bound_ref.column.data_type = Box::new(nullable_type.clone());
695-
}
696-
697-
// Convert left to nullable type
698-
let left = wrap_cast(&scalar, &nullable_type);
699-
let right = wrap_cast(&right, &nullable_type);
700-
let nullable_bool_type = DataType::Boolean.wrap_nullable();
701-
let predicate = wrap_cast(&predicate, &nullable_bool_type);
702700
// corner case: for merge into, if target_table's fields are not null, when after bind_join, it will
703701
// change into nullable, so we need to cast this. but we will do cast after all matched clauses,please
704702
// see `cast_data_type_for_merge()`.

0 commit comments

Comments
 (0)