Skip to content

Commit 2515825

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

File tree

1 file changed

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

1 file changed

+32
-9
lines changed

datafusion/expr/src/logical_plan/plan.rs

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,37 @@ 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().iter())
647+
.map(|(old, new)| {
648+
let new_field = old
649+
.1
650+
.as_ref()
651+
.clone()
652+
.with_data_type(new.1.data_type().clone())
653+
.with_nullable(new.1.is_nullable());
654+
(old.0.cloned(), Arc::new(new_field))
655+
})
656+
.collect::<Vec<_>>();
657+
658+
let schema = DFSchema::new_with_metadata(
659+
qualified_fields,
660+
schema.metadata().clone(),
661+
)?
662+
.with_functional_dependencies(schema.functional_dependencies().clone())?;
663+
Ok(LogicalPlan::Values(Values {
664+
schema: Arc::new(schema),
665+
values,
666+
}))
638667
}
639668
LogicalPlan::Filter(Filter { predicate, input }) => {
640669
Filter::try_new(predicate, input).map(LogicalPlan::Filter)
@@ -1474,13 +1503,7 @@ impl LogicalPlan {
14741503
})?
14751504
// always recompute the schema to ensure the changed in the schema's field should be
14761505
// 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-
})
1506+
.map_data(|plan| plan.recompute_schema())
14841507
})
14851508
.map(|res| res.data)
14861509
}

0 commit comments

Comments
 (0)