findepi commented on code in PR #12864:
URL: https://github.com/apache/datafusion/pull/12864#discussion_r1810554573


##########
datafusion/expr-common/src/type_coercion/binary.rs:
##########
@@ -529,6 +532,91 @@ fn type_union_resolution_coercion(
     }
 }
 
+pub fn try_type_union_resolution(data_types: &[DataType]) -> 
Result<Vec<DataType>> {
+    let mut errors = vec![];

Review Comment:
   could be Option, since there is at most one error



##########
datafusion/sql/src/values.rs:
##########
@@ -41,6 +44,11 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
                     .collect::<Result<Vec<_>>>()
             })
             .collect::<Result<Vec<_>>>()?;
-        LogicalPlanBuilder::values(values)?.build()
+
+        if schema.fields().is_empty() {
+            LogicalPlanBuilder::values(values, None)?.build()
+        } else {
+            LogicalPlanBuilder::values(values, Some(&schema))?.build()

Review Comment:
   - is this in spirit similar to 
https://github.com/apache/datafusion/pull/12104 which didn't seem accepted?
   
   - how do we know that VALUES being processed here should actually obey the 
schema of the "main table" of the query? For example:
      ```sql
     CREATE TABLE t AS SELECT a+1, 'foo' FROM (VALUES (3)) t(a)
     ```
     We have CREATE TABLE (which is the only case where 
`planner_context.table_schema()` exists), we have `VALUES`, but schema of the 
table, and schema of the values is not related.



##########
datafusion/expr-common/src/type_coercion/binary.rs:
##########
@@ -529,6 +532,91 @@ fn type_union_resolution_coercion(
     }
 }
 
+pub fn try_type_union_resolution(data_types: &[DataType]) -> 
Result<Vec<DataType>> {
+    let mut errors = vec![];
+    match try_type_union_resolution_with_struct(data_types) {
+        Ok(struct_types) => return Ok(struct_types),
+        Err(e) => {
+            errors.push(e);
+        }
+    }
+
+    if let Some(new_type) = type_union_resolution(data_types) {
+        Ok(vec![new_type; data_types.len()])
+    } else {
+        exec_err!("Fail to find the coerced type, errors: {:?}", errors)

Review Comment:
   if err from `type_union_resolution` is intentionally ignored, let's add a 
code comment explaining why



##########
datafusion/sql/src/planner.rs:
##########
@@ -154,6 +156,7 @@ impl PlannerContext {
             ctes: HashMap::new(),
             outer_query_schema: None,
             outer_from_schema: None,
+            table_schema: None,

Review Comment:
   a query may affect multiple tables, so ``main_table_schema``?



##########
datafusion/expr-common/src/type_coercion/binary.rs:
##########
@@ -529,6 +532,91 @@ fn type_union_resolution_coercion(
     }
 }
 
+pub fn try_type_union_resolution(data_types: &[DataType]) -> 
Result<Vec<DataType>> {
+    let mut errors = vec![];
+    match try_type_union_resolution_with_struct(data_types) {
+        Ok(struct_types) => return Ok(struct_types),
+        Err(e) => {
+            errors.push(e);
+        }
+    }
+
+    if let Some(new_type) = type_union_resolution(data_types) {
+        Ok(vec![new_type; data_types.len()])
+    } else {
+        exec_err!("Fail to find the coerced type, errors: {:?}", errors)
+    }
+}
+
+// Handle struct where we only change the data type but preserve the field 
name and nullability.
+// Since field name is the key of the struct, so it shouldn't be updated to 
the common column name like "c0" or "c1"
+pub fn try_type_union_resolution_with_struct(
+    data_types: &[DataType],
+) -> Result<Vec<DataType>> {
+    let mut keys_string: Option<String> = None;
+    for data_type in data_types {
+        if let DataType::Struct(fields) = data_type {
+            let keys = fields.iter().map(|f| f.name().to_owned()).join(",");

Review Comment:
   Is `,` disallowed in field names?
   
   Why not collect to Vec<String> instead?



##########
datafusion/sql/src/values.rs:
##########
@@ -31,8 +33,9 @@ impl<'a, S: ContextProvider> SqlToRel<'a, S> {
             rows,
         } = values;
 
-        // Values should not be based on any other schema
-        let schema = DFSchema::empty();
+        let schema = planner_context
+            .table_schema()
+            .unwrap_or(Arc::new(DFSchema::empty()));

Review Comment:
   ```suggestion
           let schema = planner_context
               .table_schema();
   ```
   
   and use `Option` below



-- 
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: github-unsubscr...@datafusion.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: github-unsubscr...@datafusion.apache.org
For additional commands, e-mail: github-h...@datafusion.apache.org

Reply via email to