Skip to content

Commit 17b5e71

Browse files
authored
Fix regression list Type Coercion List with inner type struct which has large/view types (#14385)
* Test for coercing inner structs * Fix but, update tests * Update tests
1 parent 86df9b9 commit 17b5e71

File tree

3 files changed

+65
-11
lines changed

3 files changed

+65
-11
lines changed

datafusion/expr-common/src/type_coercion/binary.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -566,18 +566,19 @@ fn type_union_resolution_coercion(
566566
None
567567
}
568568

569-
let types = lhs
569+
let coerced_types = lhs
570570
.iter()
571571
.map(|lhs_field| search_corresponding_coerced_type(lhs_field, rhs))
572572
.collect::<Option<Vec<_>>>()?;
573573

574-
let fields = types
574+
// preserve the field name and nullability
575+
let orig_fields = std::iter::zip(lhs.iter(), rhs.iter());
576+
577+
let fields: Vec<FieldRef> = coerced_types
575578
.into_iter()
576-
.enumerate()
577-
.map(|(i, datatype)| {
578-
Arc::new(Field::new(format!("c{i}"), datatype, true))
579-
})
580-
.collect::<Vec<FieldRef>>();
579+
.zip(orig_fields)
580+
.map(|(datatype, (lhs, rhs))| coerce_fields(datatype, lhs, rhs))
581+
.collect();
581582
Some(DataType::Struct(fields.into()))
582583
}
583584
_ => {

datafusion/sqllogictest/test_files/case.slt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,5 +416,58 @@ SELECT
416416
end
417417
FROM t;
418418

419+
statement ok
420+
drop table t
421+
422+
# Fix coercion of lists of structs
423+
# https://github.com/apache/datafusion/issues/14154
424+
425+
statement ok
426+
create or replace table t as values
427+
(
428+
100, -- column1 int (so the case isn't constant folded)
429+
[{ 'foo': arrow_cast('baz', 'Utf8View') }], -- column2 has List of Struct w/ Utf8View
430+
[{ 'foo': 'bar' }], -- column3 has List of Struct w/ Utf8
431+
[{ 'foo': 'blarg' }] -- column4 has List of Struct w/ Utf8
432+
);
433+
434+
# This case forces all branches to be coerced to the same type
435+
query ?
436+
SELECT
437+
case
438+
when column1 > 0 then column2
439+
when column1 < 0 then column3
440+
else column4
441+
end
442+
FROM t;
443+
----
444+
[{foo: baz}]
445+
446+
# different orders of the branches
447+
query ?
448+
SELECT
449+
case
450+
when column1 > 0 then column3 -- NB different order
451+
when column1 < 0 then column4
452+
else column2
453+
end
454+
FROM t;
455+
----
456+
[{foo: bar}]
457+
458+
# different orders of the branches
459+
query ?
460+
SELECT
461+
case
462+
when column1 > 0 then column4 -- NB different order
463+
when column1 < 0 then column2
464+
else column3
465+
end
466+
FROM t;
467+
----
468+
[{foo: blarg}]
469+
470+
471+
419472
statement ok
420473
drop table t

datafusion/sqllogictest/test_files/struct.slt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,14 +459,14 @@ create table t as values({r: 'a', c: 1}), ({r: 'b', c: 2.3});
459459
query ?
460460
select * from t;
461461
----
462-
{c0: a, c1: 1.0}
463-
{c0: b, c1: 2.3}
462+
{r: a, c: 1.0}
463+
{r: b, c: 2.3}
464464

465465
query T
466466
select arrow_typeof(column1) from t;
467467
----
468-
Struct([Field { name: "c0", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "c1", data_type: Float64, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
469-
Struct([Field { name: "c0", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "c1", data_type: Float64, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
468+
Struct([Field { name: "r", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "c", data_type: Float64, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
469+
Struct([Field { name: "r", data_type: Utf8, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }, Field { name: "c", data_type: Float64, nullable: true, dict_id: 0, dict_is_ordered: false, metadata: {} }])
470470

471471
statement ok
472472
drop table t;

0 commit comments

Comments
 (0)