Struct union type coercion takes field nullability from the wrong field when field order differs
Los mantenedores suelen responder en 1 día
@med9110 ya está trabajando en esto.
Desde el 14/10/2026.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 68/100
Línea de trabajo
Empieza en el brazo (DataType::Struct(lhs), DataType::Struct(rhs)), que se encuentra en type_union_resolution_coercion dentro de datafusion/expr-common/src/type_coercion/binary.rs. Haz que search_corresponding_coerced_type también devuelva el campo rhs con el mismo nombre y pasa ese campo a coerce_fields en lugar del zip posicional. Ejecuta los tests existentes de coerción de unión de structs en ese archivo y añade un caso con los campos en orden intercambiado. Está terminado cuando Struct { a: Int32 NOT NULL, b: Int32 NOT NULL } unido con Struct { b: Int32 NULL, a: Int32 NOT NULL } produce Struct { a: Int32 NOT NULL, b: Int32 NULL }.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Describe the bug
In the (DataType::Struct(lhs), DataType::Struct(rhs)) arm of type_union_resolution_coercion (type_coercion/binary.rs#L835-L872), each field's coerced type is computed by matching fields by name (search_corresponding_coerced_type), but the field's nullability is computed by zipping lhs and rhs positionally:
let coerced_types = lhs
.iter()
.map(|lhs_field| search_corresponding_coerced_type(lhs_field, rhs))
.collect::<Option<Vec<_>>>()?;
// preserve the field name and nullability
let orig_fields = std::iter::zip(lhs.iter(), rhs.iter());
let fields: Vec<FieldRef> = coerced_types
.into_iter()
.zip(orig_fields)
.map(|(datatype, (lhs, rhs))| coerce_fields(datatype, lhs, rhs))
.collect();
coerce_fields sets nullable = lhs.is_nullable() || rhs.is_nullable(). When the two structs have the same field names in a different order, the nullability of each output field comes from an unrelated right-hand field.
To Reproduce
Resolve the union type of:
lhs = Struct { a: Int32 NOT NULL, b: Int32 NOT NULL }rhs = Struct { b: Int32 NULL, a: Int32 NOT NULL }
The result is Struct { a: Int32 NULL, b: Int32 NOT NULL }. Field b is reported as non-nullable even though the right-hand b can contain nulls (and a is needlessly marked nullable).
Expected behavior
Nullability is taken from the name-matched pair, giving Struct { a: Int32 NOT NULL, b: Int32 NULL }. For example, have search_corresponding_coerced_type return the matched rhs_field along with the coerced type, and pass that field to coerce_fields.
Additional context
The nearby try_type_union_resolution_with_struct (about L900-L970) walks data_types three times, each re-matching DataType::Struct with an internal_err! fallback the first loop already rules out. It may be worth simplifying in the same change.
Line references are pinned to commit 0d79252f61bd.
- Lenguaje dominante
- Rust
- Estrellas
- 9.4k
- Forks
- 2.5k
- Merge medio
- 4 d 9 h
- PR fusionados (30 d)
- 329
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de apache/datafusion
-
bug help wanted unparser
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
apache/datafusion#26316 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Deduplicate bucket computation in width_bucket_interval_mdn_exactPosiblemente ocupada @nightcityblade la tomó hoy. Abiertoenhancement good first issue help wanted spark tech debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
apache/datafusion#26307 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
Use the shared aggr_test_schema in CSV scan tests instead of a local copyPosiblemente ocupada @med9110 la tomó hoy. Abiertocore enhancement good first issue help wanted tech debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 85/100
apache/datafusion#26306 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
gcd benchmarks pass number_rows: 0 for 100k-row inputsPosiblemente ocupada @med9110 la tomó hoy. Abiertobug functions good first issue help wanted tech debt
Dificultad 1/5 Menos de una hora Aptitud para principiantes 92/100
apache/datafusion#26297 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
apache/datafusion#26290 ·
Los mantenedores suelen responder en 1 día
Todos los issues de apache/datafusion
Issues similares
-
RUSTSEC-2026-0348: Brotli certificate decompression can allocate up to 1 GiB before authenticationAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 60/100
-
Dificultad 1/5 1-3 horas Aptitud para principiantes 62/100
-
core: Amount::from_str panics on values above 21M BTC instead of returning an errorPosiblemente ocupada @bhuvan-somisetty la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
crate: spate-s3
Dificultad 2/5 Medio día Aptitud para principiantes 62/100
Los mantenedores suelen responder en 1 día
-
write_iceberg ignores the table's write.parquet.compression-codec propertyPosiblemente ocupada @YuangGao la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Eventual-Inc/Daft#7606 ·
Los mantenedores suelen responder en 1 día