Skip to content

Commit be61a20

Browse files
Add test for nullable struct type
1 parent aa83655 commit be61a20

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

adapter/avro/src/test/java/org/apache/arrow/adapter/avro/ArrowToAvroDataTest.java

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2589,4 +2589,116 @@ record = datumReader.read(record, decoder);
25892589
}
25902590
}
25912591
}
2592+
2593+
@Test
2594+
public void testWriteNullableStructs() throws Exception {
2595+
2596+
// Field definitions
2597+
FieldType structFieldType = new FieldType(false, new ArrowType.Struct(), null);
2598+
FieldType nullableStructFieldType = new FieldType(true, new ArrowType.Struct(), null);
2599+
Field intField = new Field("intField", FieldType.notNullable(new ArrowType.Int(32, true)), null);
2600+
Field nullableIntField = new Field("nullableIntField", FieldType.nullable(new ArrowType.Int(32, true)), null);
2601+
Field structField = new Field("struct", structFieldType, Arrays.asList(intField, nullableIntField));
2602+
Field nullableStructField = new Field("nullableStruct", nullableStructFieldType, Arrays.asList(intField, nullableIntField));
2603+
2604+
// Create empty vectors
2605+
BufferAllocator allocator = new RootAllocator();
2606+
StructVector structVector = new StructVector("struct", allocator, structFieldType, null);
2607+
StructVector nullableStructVector = new StructVector("nullableStruct", allocator, nullableStructFieldType, null);
2608+
structVector.initializeChildrenFromFields(Arrays.asList(intField, nullableIntField));
2609+
nullableStructVector.initializeChildrenFromFields(Arrays.asList(intField, nullableIntField));
2610+
structVector.allocateNew();
2611+
nullableStructVector.allocateNew();
2612+
2613+
// Set up VSR
2614+
List<FieldVector> vectors = Arrays.asList(structVector, nullableStructVector);
2615+
int rowCount = 4;
2616+
2617+
try (VectorSchemaRoot root = new VectorSchemaRoot(vectors)) {
2618+
2619+
root.setRowCount(rowCount);
2620+
root.allocateNew();
2621+
2622+
// Set test data for structVector
2623+
IntVector intVector = (IntVector) structVector.getChild("intField");
2624+
IntVector nullableIntVector = (IntVector) structVector.getChild("nullableIntField");
2625+
for (int i = 0; i < rowCount; i++) {
2626+
structVector.setIndexDefined(i);
2627+
intVector.setSafe(i, i);
2628+
if (i % 2 == 0) {
2629+
nullableIntVector.setSafe(i, i * 10);
2630+
} else {
2631+
nullableIntVector.setNull(i);
2632+
}
2633+
}
2634+
2635+
// Set test data for nullableStructVector
2636+
IntVector nullableStructIntVector = (IntVector) nullableStructVector.getChild("intField");
2637+
IntVector nullableStructNullableIntVector = (IntVector) nullableStructVector.getChild("nullableIntField");
2638+
for (int i = 0; i < rowCount; i++) {
2639+
if (i >= 2) {
2640+
nullableStructVector.setIndexDefined(i);
2641+
nullableStructIntVector.setSafe(i, i);
2642+
if (i % 2 == 0) {
2643+
nullableStructNullableIntVector.setSafe(i, i * 10);
2644+
} else {
2645+
nullableStructNullableIntVector.setNull(i);
2646+
}
2647+
}else {
2648+
nullableStructVector.setNull(i);
2649+
}
2650+
}
2651+
2652+
File dataFile = new File(TMP, "testWriteNullableStructs.avro");
2653+
2654+
// Write an AVRO block using the producer classes
2655+
try (FileOutputStream fos = new FileOutputStream(dataFile)) {
2656+
BinaryEncoder encoder = new EncoderFactory().directBinaryEncoder(fos, null);
2657+
CompositeAvroProducer producer = ArrowToAvroUtils.createCompositeProducer(vectors);
2658+
for (int row = 0; row < rowCount; row++) {
2659+
producer.produce(encoder);
2660+
}
2661+
encoder.flush();
2662+
}
2663+
2664+
// Set up reading the AVRO block as a GenericRecord
2665+
Schema schema = ArrowToAvroUtils.createAvroSchema(root.getSchema().getFields());
2666+
GenericDatumReader<GenericRecord> datumReader = new GenericDatumReader<>(schema);
2667+
2668+
try (InputStream inputStream = new FileInputStream(dataFile)) {
2669+
2670+
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(inputStream, null);
2671+
GenericRecord record = null;
2672+
2673+
// Read and check values
2674+
for (int row = 0; row < rowCount; row++) {
2675+
record = datumReader.read(record, decoder);
2676+
if (row % 2 == 0) {
2677+
assertNotNull(record.get("struct"));
2678+
GenericRecord structRecord = (GenericRecord) record.get("struct");
2679+
assertEquals(row, structRecord.get("intField"));
2680+
assertEquals(row * 10, structRecord.get("nullableIntField"));
2681+
} else {
2682+
assertNotNull(record.get("struct"));
2683+
GenericRecord structRecord = (GenericRecord) record.get("struct");
2684+
assertEquals(row, structRecord.get("intField"));
2685+
assertNull(structRecord.get("nullableIntField"));
2686+
2687+
}
2688+
if (row >= 2) {
2689+
assertNotNull(record.get("nullableStruct"));
2690+
GenericRecord nullableStructRecord = (GenericRecord) record.get("nullableStruct");
2691+
assertEquals(row, nullableStructRecord.get("intField"));
2692+
if (row % 2 == 0) {
2693+
assertEquals(row * 10, nullableStructRecord.get("nullableIntField"));
2694+
} else {
2695+
assertNull(nullableStructRecord.get("nullableIntField"));
2696+
}
2697+
} else {
2698+
assertNull(record.get("nullableStruct"));
2699+
}
2700+
}
2701+
}
2702+
}
2703+
}
25922704
}

0 commit comments

Comments
 (0)