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

Aperta
#2,131 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

@Kanish2002 ci sta già lavorando.

Dal 11/10/2026.

Valutazione

Difficoltà
4/5
Tempo stimato
1-2 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
kotlin
Ambito
data

Direzione di ricerca

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.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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.
Lingua principale
Kotlin
Stelle
1.1k
Fork
87
Merge medio
2g 21h
PR unite (30g)
40

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Kotlin/dataframe

Tutte le issue di Kotlin/dataframe

Issue simili

Altre issue su Kotlin

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.