`DataFrame.concat(rows)` drops the schema of a zero-row receiver

Abierto
#2,131 1 comentario 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Kanish2002 ya está trabajando en esto.

Desde el 11/10/2026.

Evaluación

Dificultad
4/5
Tiempo estimado
1-2 días
Aptitud para principiantes
48/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
kotlin
Área
data

Línea de trabajo

Start from the DataFrame.concat(rows) implementation shown in the issue ((rows() + rows).concat()), which rebuilds from rows and therefore drops columns when the receiver is empty. Trace how empty frames (DataFrame.emptyOf) store schema versus how row-based concat unifies schemas. Add tests matching the acceptance criteria: empty iterable on emptyOf, and a zero-row receiver plus non-empty rows with a different runtime schema; keep existing non-empty-receiver unification unchanged.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

bug

Description

DataFrame.concat(rows: Iterable<DataRow<T>>) rebuilds the receiver from its rows:

public fun <T> DataFrame<T>.concat(rows: Iterable<DataRow<T>>): DataFrame<T> = (rows() + rows).concat()

Consequently, when the receiver has no rows, it contributes no columns to the result schema. The returned value still
has the static type DataFrame<T>, even though the runtime dataframe may no longer contain the columns declared by T.

How to reproduce

@DataSchema
interface BasicPerson {
    val name: String
    val age: Int
}

val df: DataFrame<BasicPerson> = dataFrameOf(
        "name" to columnOf("Alice", "Bob"),
        "age" to columnOf(20, 15),
    ).cast()

val emptyDf = DataFrame.emptyOf<BasicPerson>()
val result = emptyDf.concat(df.rows().take(0))

println(result.schema()) // []

println(result.age) // compiles, but fails at runtime with IllegalStateException (Column not found: 'age')

Expected behavior

The receiver should participate in schema unification even when it has no rows.

For the example above, result should:

  • contain zero rows;
  • preserve columns name and age;
  • have the same runtime schema as emptyDf.

Generally, the receiver's runtime schema should be preserved when rows are appended. If the iterable is non-empty, the result schema should be the union of the receiver's schema and the runtime schemas of the supplied rows.

Acceptance criteria

  • DataFrame.emptyOf<S>().concat(emptyList<DataRow<S>>()) preserves the runtime schema of the receiver.
  • A zero-row receiver contributes its columns when non-empty rows with a different runtime schema are appended.
  • The result contains the receiver rows first, followed by the supplied rows in their iteration order.
  • Existing schema-unification and missing-column behavior remains unchanged for non-empty receivers.
  • Tests cover both an empty supplied iterable and non-empty supplied rows.
Lenguaje dominante
Kotlin
Estrellas
1.1k
Forks
87
Merge medio
2 d 21 h
PR fusionados (30 d)
40

Preparar el entorno

Abrir en Codespaces

Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Kotlin/dataframe

Todos los issues de Kotlin/dataframe

Issues similares

Más issues de Kotlin

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.