Skip to content

Commit

Permalink
support strucy
Browse files Browse the repository at this point in the history
Signed-off-by: jayzhan211 <[email protected]>
  • Loading branch information
jayzhan211 committed Oct 10, 2024
1 parent 0c7eb0d commit fec6c24
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
22 changes: 22 additions & 0 deletions datafusion/expr-common/src/type_coercion/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@ impl From<&DataType> for TypeCategory {
/// align with the behavior of Postgres. Therefore, we've made slight adjustments to the rules
/// to better match the behavior of both Postgres and DuckDB. For example, we expect adjusted
/// decimal precision and scale when coercing decimal types.
///
/// This function doesn't preserve correct field name and nullability for the nested data type, we only care about data type.
pub fn type_union_resolution(data_types: &[DataType]) -> Option<DataType> {
if data_types.is_empty() {
return None;
Expand Down Expand Up @@ -476,6 +478,26 @@ fn type_union_resolution_coercion(
type_union_resolution_coercion(lhs.data_type(), rhs.data_type());
new_item_type.map(|t| DataType::List(Arc::new(Field::new("item", t, true))))
}
(DataType::Struct(lhs), DataType::Struct(rhs)) => {
if lhs.len() != rhs.len() {
return None;
}

let types = std::iter::zip(lhs.iter(), rhs.iter())
.map(|(lhs, rhs)| {
type_union_resolution_coercion(lhs.data_type(), rhs.data_type())
})
.collect::<Option<Vec<DataType>>>()?;

let fields = types
.into_iter()
.enumerate()
.map(|(i, datatype)| {
Arc::new(Field::new(format!("c{i}"), datatype, true))
})
.collect::<Vec<FieldRef>>();
Some(DataType::Struct(fields.into()))
}
_ => {
// numeric coercion is the same as comparison coercion, both find the narrowest type
// that can accommodate both types
Expand Down
16 changes: 16 additions & 0 deletions datafusion/sqllogictest/test_files/struct.slt
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,19 @@ You reached the bottom!

statement ok
drop view complex_view;

statement ok
create table t(a struct<r1 varchar, c int>, b struct<r2 varchar, c float>) as values (struct('red', 1), struct('blue', 2.3));

query T
select arrow_typeof([a, b]) from t;
----
List(Field { name: "item", data_type: Struct([Field { name: "c0", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "c1", data_type: Float32, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }]), nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} })

query ?
select [a, b] from t;
----
[{c0: red, c1: 1.0}, {c0: blue, c1: 2.3}]

statement ok
drop table t;

0 comments on commit fec6c24

Please sign in to comment.