kosiew commented on code in PR #19674:
URL: https://github.com/apache/datafusion/pull/19674#discussion_r2700584177


##########
datafusion/optimizer/src/optimizer.rs:
##########
@@ -409,6 +409,9 @@ impl Optimizer {
                     }
                     // OptimizerRule was unsuccessful, but skipped failed 
rules is off, return error
                     (Err(e), None) => {
+                        if matches!(e, DataFusionError::Plan(_)) {
+                            return Err(e);
+                        }

Review Comment:
   Removed this.



##########
datafusion/expr-common/src/type_coercion/binary.rs:
##########
@@ -1236,30 +1237,84 @@ fn coerce_numeric_type_to_decimal256(numeric_type: 
&DataType) -> Option<DataType
 
 fn struct_coercion(lhs_type: &DataType, rhs_type: &DataType) -> 
Option<DataType> {
     use arrow::datatypes::DataType::*;
+
     match (lhs_type, rhs_type) {
         (Struct(lhs_fields), Struct(rhs_fields)) => {
+            // Field count must match for coercion
             if lhs_fields.len() != rhs_fields.len() {
                 return None;
             }
 
-            let coerced_types = std::iter::zip(lhs_fields.iter(), 
rhs_fields.iter())
-                .map(|(lhs, rhs)| comparison_coercion(lhs.data_type(), 
rhs.data_type()))
-                .collect::<Option<Vec<DataType>>>()?;
-
-            // preserve the field name and nullability
-            let orig_fields = std::iter::zip(lhs_fields.iter(), 
rhs_fields.iter());
+            // If the two structs have exactly the same set of field names 
(possibly in
+            // different order), prefer name-based coercion. Otherwise fall 
back to
+            // positional coercion which preserves backward compatibility.
+            if fields_have_same_names(lhs_fields, rhs_fields) {
+                return coerce_struct_by_name(lhs_fields, rhs_fields);
+            }
 
-            let fields: Vec<FieldRef> = coerced_types
-                .into_iter()
-                .zip(orig_fields)
-                .map(|(datatype, (lhs, rhs))| coerce_fields(datatype, lhs, 
rhs))
-                .collect();
-            Some(Struct(fields.into()))
+            coerce_struct_by_position(lhs_fields, rhs_fields)
         }
         _ => None,
     }
 }
 
+/// Return true if every left-field name exists in the right fields (and 
lengths are equal).
+fn fields_have_same_names(lhs_fields: &Fields, rhs_fields: &Fields) -> bool {
+    let rhs_names: HashSet<&str> = rhs_fields.iter().map(|f| 
f.name().as_str()).collect();

Review Comment:
   Added comment



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to