Skip to content

Commit 47a7fb4

Browse files
committed
Fix Delta IO compilation errors due to Delta Kernel API mismatches
1 parent ff74420 commit 47a7fb4

2 files changed

Lines changed: 69 additions & 56 deletions

File tree

sdks/java/io/delta/src/main/java/org/apache/beam/sdk/io/delta/DeltaIO.java

Lines changed: 66 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.delta.kernel.data.MapValue;
3131
import io.delta.kernel.defaults.engine.DefaultEngine;
3232
import io.delta.kernel.engine.Engine;
33+
import io.delta.kernel.engine.FileReadResult;
3334
import io.delta.kernel.internal.InternalScanFileUtils;
3435
import io.delta.kernel.internal.data.ScanStateRow;
3536
import io.delta.kernel.types.ArrayType;
@@ -52,7 +53,6 @@
5253
import io.delta.kernel.utils.CloseableIterator;
5354
import io.delta.kernel.utils.FileStatus;
5455
import java.io.Serializable;
55-
import java.math.BigDecimal;
5656
import java.util.ArrayList;
5757
import java.util.HashMap;
5858
import java.util.List;
@@ -67,7 +67,6 @@
6767
import org.apache.beam.sdk.values.PBegin;
6868
import org.apache.beam.sdk.values.PCollection;
6969
import org.apache.beam.sdk.values.Row;
70-
import org.apache.hadoop.conf.Configuration;
7170
import org.checkerframework.checker.nullness.qual.Nullable;
7271

7372
/**
@@ -127,25 +126,29 @@ public ReadRows withConfig(Map<String, String> config) {
127126

128127
@Override
129128
public PCollection<Row> expand(PBegin input) {
130-
if (getTablePath() == null) {
129+
String tablePath = getTablePath();
130+
if (tablePath == null) {
131131
throw new IllegalArgumentException("Table path must be set.");
132132
}
133133

134134
org.apache.hadoop.conf.Configuration hadoopConfig = getHadoopConfiguration(getHadoopConfig());
135135
Engine engine = DefaultEngine.create(hadoopConfig);
136-
Table table = Table.forPath(engine, getTablePath());
136+
Table table = Table.forPath(engine, tablePath);
137137

138138
try {
139139
Snapshot snapshot = buildSnapshot(engine, table);
140-
Scan scan = snapshot.getScanBuilder(engine).build();
141-
StructType readSchema = scan.getSchema(engine);
140+
Scan scan = snapshot.getScanBuilder().build();
141+
io.delta.kernel.data.Row scanState = scan.getScanState(engine);
142+
StructType readSchema = ScanStateRow.getLogicalSchema(scanState);
142143
org.apache.beam.sdk.schemas.Schema beamSchema = inferBeamSchema(readSchema);
143144

144-
List<DeltaFileDescriptor> fileDescriptors = buildFileDescriptors(engine, scan);
145+
List<DeltaFileDescriptor> fileDescriptors = buildFileDescriptors(engine, scan, tablePath);
145146

146147
return input
147-
.apply("CreateFileDescriptors", Create.of(fileDescriptors)
148-
.withCoder(SerializableCoder.of(DeltaFileDescriptor.class)))
148+
.apply(
149+
"CreateFileDescriptors",
150+
Create.of(fileDescriptors)
151+
.withCoder(SerializableCoder.of(DeltaFileDescriptor.class)))
149152
.apply("ReadFile", ParDo.of(new ReadFileFn(beamSchema)))
150153
.setRowSchema(beamSchema);
151154

@@ -155,34 +158,38 @@ public PCollection<Row> expand(PBegin input) {
155158
}
156159

157160
private Snapshot buildSnapshot(Engine engine, Table table) throws Exception {
158-
if (getVersion() != null) {
159-
return table.getSnapshotAsOfVersion(engine, getVersion());
160-
} else if (getTimestamp() != null) {
161-
long epochMillis = org.joda.time.Instant.parse(getTimestamp()).getMillis();
161+
Long version = getVersion();
162+
String timestamp = getTimestamp();
163+
if (version != null) {
164+
return table.getSnapshotAsOfVersion(engine, version);
165+
} else if (timestamp != null) {
166+
long epochMillis = org.joda.time.Instant.parse(timestamp).getMillis();
162167
return table.getSnapshotAsOfTimestamp(engine, epochMillis);
163168
} else {
164169
return table.getLatestSnapshot(engine);
165170
}
166171
}
167172

168-
private List<DeltaFileDescriptor> buildFileDescriptors(Engine engine, Scan scan) throws Exception {
173+
private List<DeltaFileDescriptor> buildFileDescriptors(
174+
Engine engine, Scan scan, String tablePath) throws Exception {
169175
List<DeltaFileDescriptor> descriptors = new ArrayList<>();
170176
try (CloseableIterator<FilteredColumnarBatch> scanFileIter = scan.getScanFiles(engine)) {
171177
while (scanFileIter.hasNext()) {
172178
FilteredColumnarBatch scanFilesBatch = scanFileIter.next();
173-
try (CloseableIterator<io.delta.kernel.data.Row> scanFileRows = scanFilesBatch.getRows()) {
179+
try (CloseableIterator<io.delta.kernel.data.Row> scanFileRows =
180+
scanFilesBatch.getRows()) {
174181
while (scanFileRows.hasNext()) {
175182
io.delta.kernel.data.Row scanFileRow = scanFileRows.next();
176183
FileStatus fileStatus = InternalScanFileUtils.getAddFileStatus(scanFileRow);
177-
descriptors.add(new DeltaFileDescriptor(
178-
getTablePath(),
179-
fileStatus.getPath(),
180-
fileStatus.getSize(),
181-
fileStatus.getModificationTime(),
182-
getHadoopConfig(),
183-
getVersion(),
184-
getTimestamp()
185-
));
184+
descriptors.add(
185+
new DeltaFileDescriptor(
186+
tablePath,
187+
fileStatus.getPath(),
188+
fileStatus.getSize(),
189+
fileStatus.getModificationTime(),
190+
getHadoopConfig(),
191+
getVersion(),
192+
getTimestamp()));
186193
}
187194
}
188195
}
@@ -256,47 +263,50 @@ public ReadFileFn(org.apache.beam.sdk.schemas.Schema beamSchema) {
256263
@ProcessElement
257264
public void processElement(ProcessContext c) throws Exception {
258265
DeltaFileDescriptor desc = c.element();
259-
org.apache.hadoop.conf.Configuration hadoopConfig = getHadoopConfiguration(desc.getHadoopConfig());
266+
org.apache.hadoop.conf.Configuration hadoopConfig =
267+
getHadoopConfiguration(desc.getHadoopConfig());
260268
Engine engine = DefaultEngine.create(hadoopConfig);
261269
Table table = Table.forPath(engine, desc.getTablePath());
262270

263271
Snapshot snapshot;
264-
if (desc.getVersion() != null) {
265-
snapshot = table.getSnapshotAsOfVersion(engine, desc.getVersion());
266-
} else if (desc.getTimestamp() != null) {
267-
long epochMillis = org.joda.time.Instant.parse(desc.getTimestamp()).getMillis();
272+
Long version = desc.getVersion();
273+
String timestamp = desc.getTimestamp();
274+
if (version != null) {
275+
snapshot = table.getSnapshotAsOfVersion(engine, version);
276+
} else if (timestamp != null) {
277+
long epochMillis = org.joda.time.Instant.parse(timestamp).getMillis();
268278
snapshot = table.getSnapshotAsOfTimestamp(engine, epochMillis);
269279
} else {
270280
snapshot = table.getLatestSnapshot(engine);
271281
}
272282

273-
Scan scan = snapshot.getScanBuilder(engine).build();
283+
Scan scan = snapshot.getScanBuilder().build();
274284
io.delta.kernel.data.Row scanState = scan.getScanState(engine);
275285

276286
try (CloseableIterator<FilteredColumnarBatch> scanFileIter = scan.getScanFiles(engine)) {
277287
while (scanFileIter.hasNext()) {
278288
FilteredColumnarBatch scanFilesBatch = scanFileIter.next();
279-
try (CloseableIterator<io.delta.kernel.data.Row> scanFileRows = scanFilesBatch.getRows()) {
289+
try (CloseableIterator<io.delta.kernel.data.Row> scanFileRows =
290+
scanFilesBatch.getRows()) {
280291
while (scanFileRows.hasNext()) {
281292
io.delta.kernel.data.Row scanFileRow = scanFileRows.next();
282293
FileStatus fileStatus = InternalScanFileUtils.getAddFileStatus(scanFileRow);
283294
if (fileStatus.getPath().equals(desc.getFilePath())) {
284295
StructType physicalReadSchema = ScanStateRow.getPhysicalDataReadSchema(scanState);
285296
CloseableIterator<ColumnarBatch> physicalDataIter =
286-
engine.getParquetHandler().readParquetFiles(
287-
singletonCloseableIterator(fileStatus),
288-
physicalReadSchema,
289-
Optional.empty()).map(FilteredColumnarBatch::getData);
290-
try (
291-
CloseableIterator<FilteredColumnarBatch> transformedData =
292-
Scan.transformPhysicalData(
293-
engine,
294-
scanState,
295-
scanFileRow,
296-
physicalDataIter)) {
297+
engine
298+
.getParquetHandler()
299+
.readParquetFiles(
300+
singletonCloseableIterator(fileStatus),
301+
physicalReadSchema,
302+
Optional.empty())
303+
.map(FileReadResult::getData);
304+
try (CloseableIterator<FilteredColumnarBatch> transformedData =
305+
Scan.transformPhysicalData(engine, scanState, scanFileRow, physicalDataIter)) {
297306
while (transformedData.hasNext()) {
298307
FilteredColumnarBatch filteredData = transformedData.next();
299-
try (CloseableIterator<io.delta.kernel.data.Row> rows = filteredData.getRows()) {
308+
try (CloseableIterator<io.delta.kernel.data.Row> rows =
309+
filteredData.getRows()) {
300310
while (rows.hasNext()) {
301311
io.delta.kernel.data.Row row = rows.next();
302312
c.output(convertKernelRowToBeamRow(row, beamSchema));
@@ -323,8 +333,9 @@ private static org.apache.hadoop.conf.Configuration getHadoopConfiguration(
323333
return config;
324334
}
325335

326-
private static org.apache.beam.sdk.schemas.Schema inferBeamSchema(StructType structType) {
327-
org.apache.beam.sdk.schemas.Schema.Builder builder = org.apache.beam.sdk.schemas.Schema.builder();
336+
static org.apache.beam.sdk.schemas.Schema inferBeamSchema(StructType structType) {
337+
org.apache.beam.sdk.schemas.Schema.Builder builder =
338+
org.apache.beam.sdk.schemas.Schema.builder();
328339
for (StructField field : structType.fields()) {
329340
builder.addField(field.getName(), toBeamFieldType(field.getDataType()));
330341
}
@@ -355,22 +366,23 @@ private static org.apache.beam.sdk.schemas.Schema.FieldType toBeamFieldType(Data
355366
} else if (dataType instanceof TimestampType || dataType instanceof DateType) {
356367
return org.apache.beam.sdk.schemas.Schema.FieldType.DATETIME;
357368
} else if (dataType instanceof StructType) {
358-
return org.apache.beam.sdk.schemas.Schema.FieldType.row(inferBeamSchema((StructType) dataType));
369+
return org.apache.beam.sdk.schemas.Schema.FieldType.row(
370+
inferBeamSchema((StructType) dataType));
359371
} else if (dataType instanceof ArrayType) {
360-
return org.apache.beam.sdk.schemas.Schema.FieldType.array(toBeamFieldType(((ArrayType) dataType).getElementType()));
372+
return org.apache.beam.sdk.schemas.Schema.FieldType.array(
373+
toBeamFieldType(((ArrayType) dataType).getElementType()));
361374
} else if (dataType instanceof MapType) {
362375
MapType mapType = (MapType) dataType;
363376
return org.apache.beam.sdk.schemas.Schema.FieldType.map(
364-
toBeamFieldType(mapType.getKeyType()),
365-
toBeamFieldType(mapType.getValueType()));
377+
toBeamFieldType(mapType.getKeyType()), toBeamFieldType(mapType.getValueType()));
366378
} else {
367379
throw new IllegalArgumentException("Unsupported Delta type: " + dataType);
368380
}
369381
}
370382

371383
private static Row convertKernelRowToBeamRow(
372384
io.delta.kernel.data.Row deltaRow, org.apache.beam.sdk.schemas.Schema beamSchema) {
373-
List<Object> values = new ArrayList<>();
385+
List<@Nullable Object> values = new ArrayList<>();
374386
StructType structType = deltaRow.getSchema();
375387
for (int i = 0; i < structType.length(); i++) {
376388
if (deltaRow.isNullAt(i)) {
@@ -383,7 +395,8 @@ private static Row convertKernelRowToBeamRow(
383395
return Row.withSchema(beamSchema).addValues(values).build();
384396
}
385397

386-
private static Object convertValue(io.delta.kernel.data.Row deltaRow, int ordinal, DataType dataType) {
398+
private static @Nullable Object convertValue(
399+
io.delta.kernel.data.Row deltaRow, int ordinal, DataType dataType) {
387400
if (deltaRow.isNullAt(ordinal)) {
388401
return null;
389402
}
@@ -419,7 +432,7 @@ private static Object convertValue(io.delta.kernel.data.Row deltaRow, int ordina
419432
} else if (dataType instanceof ArrayType) {
420433
ArrayValue arrayVal = deltaRow.getArray(ordinal);
421434
int size = arrayVal.getSize();
422-
List<Object> list = new ArrayList<>(size);
435+
List<@Nullable Object> list = new ArrayList<>(size);
423436
DataType elemType = ((ArrayType) dataType).getElementType();
424437
ColumnVector vec = arrayVal.getElements();
425438
for (int j = 0; j < size; j++) {
@@ -433,7 +446,7 @@ private static Object convertValue(io.delta.kernel.data.Row deltaRow, int ordina
433446
} else if (dataType instanceof MapType) {
434447
MapValue mapVal = deltaRow.getMap(ordinal);
435448
int size = mapVal.getSize();
436-
Map<Object, Object> map = new HashMap<>(size);
449+
Map<Object, @Nullable Object> map = new HashMap<>(size);
437450
DataType keyType = ((MapType) dataType).getKeyType();
438451
DataType valueType = ((MapType) dataType).getValueType();
439452
ColumnVector keysVec = mapVal.getKeys();

sdks/java/io/delta/src/main/java/org/apache/beam/sdk/io/delta/DeltaSourceDoFn.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public ProcessContinuation processElement(
127127
SerializableRow scanStateRow = task.getScanStateRow();
128128
StructType physicalSchema = ScanStateRow.getPhysicalDataReadSchema(scanStateRow);
129129
StructType logicalSchema = ScanStateRow.getLogicalSchema(scanStateRow);
130-
Schema beamSchema = DeltaIO.ReadRows.convertToBeamSchema(logicalSchema);
130+
Schema beamSchema = DeltaIO.inferBeamSchema(logicalSchema);
131131

132132
Engine currentEngine = engine;
133133
if (currentEngine == null) {
@@ -281,7 +281,7 @@ private static Row toBeamRow(io.delta.kernel.data.Row deltaRow, Schema beamSchem
281281
return map;
282282
} else if (type instanceof StructType) {
283283
io.delta.kernel.data.Row nestedRow = row.getStruct(index);
284-
Schema nestedBeamSchema = DeltaIO.ReadRows.convertToBeamSchema((StructType) type);
284+
Schema nestedBeamSchema = DeltaIO.inferBeamSchema((StructType) type);
285285
return toBeamRow(nestedRow, nestedBeamSchema);
286286
}
287287
throw new UnsupportedOperationException("Unsupported type: " + type.getClass());
@@ -350,7 +350,7 @@ private static Row toBeamRow(io.delta.kernel.data.Row deltaRow, Schema beamSchem
350350
childVectors[i] = vector.getChild(i);
351351
}
352352
io.delta.kernel.data.Row nestedRow = new VectorRow(structType, childVectors, index);
353-
Schema nestedBeamSchema = DeltaIO.ReadRows.convertToBeamSchema(structType);
353+
Schema nestedBeamSchema = DeltaIO.inferBeamSchema(structType);
354354
return toBeamRow(nestedRow, nestedBeamSchema);
355355
}
356356
throw new UnsupportedOperationException("Unsupported vector type: " + type.getClass());

0 commit comments

Comments
 (0)