Skip to content

Commit 819187e

Browse files
committed
recompute_schema for LogicalPlan::Values
1 parent 7f5c8f4 commit 819187e

File tree

1 file changed

+31
-9
lines changed
  • datafusion/expr/src/logical_plan

1 file changed

+31
-9
lines changed

datafusion/expr/src/logical_plan/plan.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,36 @@ impl LogicalPlan {
633633
LogicalPlan::Dml(_) => Ok(self),
634634
LogicalPlan::Copy(_) => Ok(self),
635635
LogicalPlan::Values(Values { schema, values }) => {
636-
// todo it isn't clear why the schema is not recomputed here
637-
Ok(LogicalPlan::Values(Values { schema, values }))
636+
// Using `values` alone cannot compute correct schema for the plan. For example:
637+
// Projection: col_1, col_2
638+
// Values: (Float32(1), Float32(10)), (Float32(100), Float32(10))
639+
//
640+
// Thus, we need to recompute a new schema from `values` and retain some
641+
// information from the original schema.
642+
let new_plan = LogicalPlanBuilder::values(values.clone())?.build()?;
643+
644+
let qualified_fields = schema
645+
.iter()
646+
.zip(new_plan.schema().fields().iter())
647+
.map(|((table_ref, old_field), new_field)| {
648+
let field = old_field
649+
.as_ref()
650+
.clone()
651+
.with_data_type(new_field.data_type().clone())
652+
.with_nullable(new_field.is_nullable());
653+
(table_ref.cloned(), Arc::new(field))
654+
})
655+
.collect::<Vec<_>>();
656+
657+
let schema = DFSchema::new_with_metadata(
658+
qualified_fields,
659+
schema.metadata().clone(),
660+
)?
661+
.with_functional_dependencies(schema.functional_dependencies().clone())?;
662+
Ok(LogicalPlan::Values(Values {
663+
schema: Arc::new(schema),
664+
values,
665+
}))
638666
}
639667
LogicalPlan::Filter(Filter { predicate, input }) => {
640668
Filter::try_new(predicate, input).map(LogicalPlan::Filter)
@@ -1474,13 +1502,7 @@ impl LogicalPlan {
14741502
})?
14751503
// always recompute the schema to ensure the changed in the schema's field should be
14761504
// poplulated to the plan's parent
1477-
.map_data(|plan| plan.recompute_schema())?
1478-
.map_data(|plan| match plan {
1479-
LogicalPlan::Values(Values { values, schema: _ }) => {
1480-
LogicalPlanBuilder::values(values)?.build()
1481-
}
1482-
_ => Ok(plan),
1483-
})
1505+
.map_data(|plan| plan.recompute_schema())
14841506
})
14851507
.map(|res| res.data)
14861508
}

0 commit comments

Comments
 (0)