@@ -11,13 +11,13 @@ import org.jetbrains.kotlinx.dataframe.api.ConvertSchemaDsl
11
11
import org.jetbrains.kotlinx.dataframe.api.ConverterScope
12
12
import org.jetbrains.kotlinx.dataframe.api.ExcessiveColumns
13
13
import org.jetbrains.kotlinx.dataframe.api.Infer
14
+ import org.jetbrains.kotlinx.dataframe.api.add
14
15
import org.jetbrains.kotlinx.dataframe.api.all
15
16
import org.jetbrains.kotlinx.dataframe.api.allNulls
16
17
import org.jetbrains.kotlinx.dataframe.api.asColumnGroup
17
18
import org.jetbrains.kotlinx.dataframe.api.concat
18
19
import org.jetbrains.kotlinx.dataframe.api.convertTo
19
20
import org.jetbrains.kotlinx.dataframe.api.emptyDataFrame
20
- import org.jetbrains.kotlinx.dataframe.api.getColumnPaths
21
21
import org.jetbrains.kotlinx.dataframe.api.isEmpty
22
22
import org.jetbrains.kotlinx.dataframe.api.map
23
23
import org.jetbrains.kotlinx.dataframe.api.name
@@ -29,12 +29,14 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup
29
29
import org.jetbrains.kotlinx.dataframe.columns.ColumnKind
30
30
import org.jetbrains.kotlinx.dataframe.columns.ColumnPath
31
31
import org.jetbrains.kotlinx.dataframe.columns.FrameColumn
32
+ import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy
32
33
import org.jetbrains.kotlinx.dataframe.columns.toColumnSet
33
34
import org.jetbrains.kotlinx.dataframe.exceptions.ExcessiveColumnsException
34
35
import org.jetbrains.kotlinx.dataframe.exceptions.TypeConversionException
35
36
import org.jetbrains.kotlinx.dataframe.impl.emptyPath
36
- import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyColumn
37
+ import org.jetbrains.kotlinx.dataframe.impl.getColumnPaths
37
38
import org.jetbrains.kotlinx.dataframe.impl.schema.createEmptyDataFrame
39
+ import org.jetbrains.kotlinx.dataframe.impl.schema.createNullFilledColumn
38
40
import org.jetbrains.kotlinx.dataframe.impl.schema.extractSchema
39
41
import org.jetbrains.kotlinx.dataframe.impl.schema.render
40
42
import org.jetbrains.kotlinx.dataframe.kind
@@ -252,22 +254,15 @@ internal fun AnyFrame.convertToImpl(
252
254
}
253
255
}.toMutableList()
254
256
255
- // when the target is nullable but the source does not contain a column, fill it in with nulls / empty dataframes
257
+ // when the target is nullable but the source does not contain a column,
258
+ // fill it in with nulls / empty dataframes
256
259
val size = this .size.nrow
257
260
schema.columns.forEach { (name, targetColumn) ->
258
- val isNullable =
259
- // like value column of type Int?
260
- targetColumn.nullable ||
261
- // like value column of type Int? (backup check)
262
- targetColumn.type.isMarkedNullable ||
263
- // like DataRow<Something?> for a group column (all columns in the group will be nullable)
264
- targetColumn.contentType?.isMarkedNullable == true ||
265
- // frame column can be filled with empty dataframes
266
- targetColumn.kind == ColumnKind .Frame
267
-
268
261
if (name !in visited) {
269
- newColumns + = targetColumn.createEmptyColumn(name, size)
270
- if (! isNullable) {
262
+ try {
263
+ newColumns + = targetColumn.createNullFilledColumn(name, size)
264
+ } catch (e: IllegalStateException ) {
265
+ // if this could not be done automatically, they need to be filled manually
271
266
missingPaths.add(path + name)
272
267
}
273
268
}
@@ -280,10 +275,16 @@ internal fun AnyFrame.convertToImpl(
280
275
var result = convertToSchema(marker.schema, emptyPath())
281
276
282
277
dsl.fillers.forEach { filler ->
283
- val paths = result.getColumnPaths(filler.columns)
284
- missingPaths.removeAll(paths.toSet())
285
- result = result.update { paths.toColumnSet() }.with {
286
- filler.expr(this , this )
278
+ val paths = result.getColumnPaths(UnresolvedColumnsPolicy .Create , filler.columns).toSet()
279
+ missingPaths - = paths
280
+ val (newPaths, existingPaths) = paths.partition { it in missingPaths }
281
+
282
+ // first fill cols that are already in the df
283
+ result = result.update { existingPaths.toColumnSet() }.with { filler.expr(this , this ) }
284
+
285
+ // then create any missing ones by filling
286
+ result = newPaths.fold(result) { df, newPath ->
287
+ df.add(newPath, Infer .Type ) { filler.expr(this , this ) }
287
288
}
288
289
}
289
290
0 commit comments