Skip to content

Commit abaea59

Browse files
Test for nullable map types
1 parent af3e0f1 commit abaea59

File tree

1 file changed

+139
-10
lines changed

1 file changed

+139
-10
lines changed

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

Lines changed: 139 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2061,7 +2061,7 @@ record = datumReader.read(record, decoder);
20612061
}
20622062

20632063
@Test
2064-
public void testWriteNonNullableMap() throws Exception {
2064+
public void testWriteMap() throws Exception {
20652065

20662066
// Field definitions
20672067
FieldType intMapField = new FieldType(false, new ArrowType.Map(false), null);
@@ -2135,7 +2135,7 @@ public void testWriteNonNullableMap() throws Exception {
21352135
dateWriter.endMap();
21362136
}
21372137

2138-
File dataFile = new File(TMP, "testWriteNonNullableMap.avro");
2138+
File dataFile = new File(TMP, "testWriteMap.avro");
21392139

21402140
// Write an AVRO block using the producer classes
21412141
try (FileOutputStream fos = new FileOutputStream(dataFile)) {
@@ -2170,8 +2170,132 @@ record = datumReader.read(record, decoder);
21702170
}
21712171
}
21722172

2173+
@Test
2174+
public void testWriteNullableMap() throws Exception {
2175+
2176+
// Field definitions
2177+
FieldType nullMapType = new FieldType(true, new ArrowType.Map(false), null);
2178+
FieldType nonNullMapType = new FieldType(false, new ArrowType.Map(false), null);
2179+
2180+
Field keyField = new Field("key", FieldType.notNullable(new ArrowType.Utf8()), null);
2181+
Field nullFieldType = new Field("value", FieldType.nullable(new ArrowType.Int(32, true)), null);
2182+
Field nonNullFieldType = new Field("value", FieldType.notNullable(new ArrowType.Int(32, true)), null);
2183+
Field nullEntryField = new Field("entries", FieldType.notNullable(new ArrowType.Struct()), Arrays.asList(keyField, nullFieldType));
2184+
Field nonNullEntryField = new Field("entries", FieldType.notNullable(new ArrowType.Struct()), Arrays.asList(keyField, nonNullFieldType));
2185+
2186+
// Create empty vectors
2187+
BufferAllocator allocator = new RootAllocator();
2188+
MapVector nullEntriesVector = new MapVector("nullEntriesVector", allocator, nonNullMapType, null);
2189+
MapVector nullMapVector = new MapVector("nullMapVector", allocator, nullMapType, null);
2190+
MapVector nullBothVector = new MapVector("nullBothVector", allocator, nullMapType, null);
2191+
2192+
nullEntriesVector.initializeChildrenFromFields(Arrays.asList(nullEntryField));
2193+
nullMapVector.initializeChildrenFromFields(Arrays.asList(nonNullEntryField));
2194+
nullBothVector.initializeChildrenFromFields(Arrays.asList(nullEntryField));
2195+
2196+
// Set up VSR
2197+
List<FieldVector> vectors = Arrays.asList(nullEntriesVector, nullMapVector, nullBothVector);
2198+
int rowCount = 3;
2199+
2200+
try (VectorSchemaRoot root = new VectorSchemaRoot(vectors)) {
2201+
2202+
root.setRowCount(rowCount);
2203+
root.allocateNew();
2204+
2205+
// Set test data for intList
2206+
BaseWriter.MapWriter writer = nullEntriesVector.getWriter();
2207+
writer.startMap();
2208+
writer.startEntry();
2209+
writer.key().varChar().writeVarChar("key0");
2210+
writer.value().integer().writeNull();
2211+
writer.endEntry();
2212+
writer.endMap();
2213+
writer.startMap();
2214+
writer.startEntry();
2215+
writer.key().varChar().writeVarChar("key1");
2216+
writer.value().integer().writeInt(0);
2217+
writer.endEntry();
2218+
writer.endMap();
2219+
writer.startMap();
2220+
writer.startEntry();
2221+
writer.key().varChar().writeVarChar("key2");
2222+
writer.value().integer().writeInt(1);
2223+
writer.endEntry();
2224+
writer.endMap();
2225+
2226+
// Set test data for stringList
2227+
BaseWriter.MapWriter nullMapWriter = nullMapVector.getWriter();
2228+
nullMapWriter.writeNull();
2229+
nullMapWriter.startMap();
2230+
nullMapWriter.startEntry();
2231+
nullMapWriter.key().varChar().writeVarChar("key1");
2232+
nullMapWriter.value().integer().writeInt(0);
2233+
nullMapWriter.endEntry();
2234+
nullMapWriter.endMap();
2235+
nullMapWriter.startMap();
2236+
nullMapWriter.startEntry();
2237+
nullMapWriter.key().varChar().writeVarChar("key2");
2238+
nullMapWriter.value().integer().writeInt(1);
2239+
nullMapWriter.endEntry();
2240+
nullMapWriter.endMap();
2241+
2242+
// Set test data for dateList
2243+
BaseWriter.MapWriter nullBothWriter = nullBothVector.getWriter();
2244+
nullBothWriter.writeNull();
2245+
nullBothWriter.startMap();
2246+
nullBothWriter.startEntry();
2247+
nullBothWriter.key().varChar().writeVarChar("key1");
2248+
nullBothWriter.value().integer().writeNull();
2249+
nullBothWriter.endEntry();
2250+
nullBothWriter.endMap();
2251+
nullBothWriter.startMap();
2252+
nullBothWriter.startEntry();
2253+
nullBothWriter.key().varChar().writeVarChar("key2");
2254+
nullBothWriter.value().integer().writeInt(0);
2255+
nullBothWriter.endEntry();
2256+
nullBothWriter.endMap();
2257+
2258+
File dataFile = new File(TMP, "testWriteNullableMap.avro");
2259+
2260+
// Write an AVRO block using the producer classes
2261+
try (FileOutputStream fos = new FileOutputStream(dataFile)) {
2262+
BinaryEncoder encoder = new EncoderFactory().directBinaryEncoder(fos, null);
2263+
CompositeAvroProducer producer = ArrowToAvroUtils.createCompositeProducer(vectors);
2264+
for (int row = 0; row < rowCount; row++) {
2265+
producer.produce(encoder);
2266+
}
2267+
encoder.flush();
2268+
}
2269+
2270+
// Set up reading the AVRO block as a GenericRecord
2271+
Schema schema = ArrowToAvroUtils.createAvroSchema(root.getSchema().getFields());
2272+
GenericDatumReader<GenericRecord> datumReader = new GenericDatumReader<>(schema);
2273+
2274+
try (InputStream inputStream = new FileInputStream(dataFile)) {
2275+
2276+
BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(inputStream, null);
2277+
GenericRecord record = null;
2278+
2279+
// Read and check values
2280+
for (int row = 0; row < rowCount; row++) {
2281+
record = datumReader.read(record, decoder);
2282+
Map<String, Object> intMap = convertMap(nullEntriesVector.getObject(row));
2283+
Map<String, Object> stringMap = convertMap(nullMapVector.getObject(row));
2284+
Map<String, Object> dateMap = convertMap(nullBothVector.getObject(row));
2285+
compareMaps(intMap, (Map) record.get("nullEntriesVector"));
2286+
compareMaps(stringMap, (Map) record.get("nullMapVector"));
2287+
compareMaps(dateMap, (Map) record.get("nullBothVector"));
2288+
}
2289+
}
2290+
}
2291+
}
2292+
21732293
private Map<String, Object> convertMap(List<?> entryList) {
21742294

2295+
if (entryList == null) {
2296+
return null;
2297+
}
2298+
21752299
Map<String, Object> map = new HashMap<>();
21762300
JsonStringArrayList<?> structList = (JsonStringArrayList<?>) entryList;
21772301
for (Object entry : structList) {
@@ -2184,14 +2308,19 @@ private Map<String, Object> convertMap(List<?> entryList) {
21842308
}
21852309

21862310
private void compareMaps(Map<String, ?> expected, Map<?, ?> actual) {
2187-
assertEquals(expected.size(), actual.size());
2188-
for (Object key : actual.keySet()) {
2189-
assertTrue(expected.containsKey(key.toString()));
2190-
Object actualValue = actual.get(key);
2191-
if (actualValue instanceof Utf8) {
2192-
assertEquals(expected.get(key.toString()).toString(), actualValue.toString());
2193-
} else {
2194-
assertEquals(expected.get(key.toString()), actual.get(key));
2311+
if (expected == null) {
2312+
assertNull(actual);
2313+
}
2314+
else {
2315+
assertEquals(expected.size(), actual.size());
2316+
for (Object key : actual.keySet()) {
2317+
assertTrue(expected.containsKey(key.toString()));
2318+
Object actualValue = actual.get(key);
2319+
if (actualValue instanceof Utf8) {
2320+
assertEquals(expected.get(key.toString()).toString(), actualValue.toString());
2321+
} else {
2322+
assertEquals(expected.get(key.toString()), actual.get(key));
2323+
}
21952324
}
21962325
}
21972326
}

0 commit comments

Comments
 (0)