Class generated for schema with nested Maps is incorrect
nisargthakkar opened this issue · comments
Nisarg Thakkar commented
For a schema which contains nested maps, the class generated is incorrect.
{
"type": "record",
"name": "TestDecodeFailureValue",
"doc": "Value schema demonstrating failed decode with Map field",
"fields": [
{
"name": "mapField",
"type": {
"type": "map",
"values": {
"type": "record",
"name": "recordField",
"fields": [
{
"name": "internalMapField",
"type": { "type": "map", "values": "long" }
},
{
"name": "internalNullableLong1",
"type": ["null", "long"]
},
{
"name": "internalNullableLong2",
"type": ["null", "long"]
},
{
"name": "internalNullableLong3",
"type": ["null", "long"]
}
]
}
}
},
{
"name": "nullableLong1",
"type": ["null", "long"]
}
]
}
The generated code:
package com.linkedin.avro.fastserde.generated.deserialization.AVRO_1_10;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import com.linkedin.avro.fastserde.FastDeserializer;
import org.apache.avro.Schema;
import org.apache.avro.generic.IndexedRecord;
import org.apache.avro.io.Decoder;
import org.apache.avro.util.Utf8;
public class TestDecodeFailureValue_GenericDeserializer_4246086364814938096_4246086364814938096
implements FastDeserializer<IndexedRecord>
{
private final Schema readerSchema;
private final Schema mapField0;
private final Schema mapFieldMapValueSchema0;
private final Schema nullableLong10;
public TestDecodeFailureValue_GenericDeserializer_4246086364814938096_4246086364814938096(Schema readerSchema) {
this.readerSchema = readerSchema;
this.mapField0 = readerSchema.getField("mapField").schema();
this.mapFieldMapValueSchema0 = mapField0 .getValueType();
this.nullableLong10 = readerSchema.getField("nullableLong1").schema();
}
public IndexedRecord deserialize(IndexedRecord reuse, Decoder decoder)
throws IOException
{
return deserializeTestDecodeFailureValue0((reuse), (decoder));
}
public IndexedRecord deserializeTestDecodeFailureValue0(Object reuse, Decoder decoder)
throws IOException
{
IndexedRecord TestDecodeFailureValue;
if ((((reuse)!= null)&&((reuse) instanceof IndexedRecord))&&(((IndexedRecord)(reuse)).getSchema() == readerSchema)) {
TestDecodeFailureValue = ((IndexedRecord)(reuse));
} else {
TestDecodeFailureValue = new org.apache.avro.generic.GenericData.Record(readerSchema);
}
Map<Utf8, IndexedRecord> mapField1 = null;
long chunkLen0 = (decoder.readMapStart());
if (chunkLen0 > 0) {
Map<Utf8, IndexedRecord> mapFieldReuse0 = null;
Object oldMap0 = TestDecodeFailureValue.get(0);
if (oldMap0 instanceof Map) {
mapFieldReuse0 = ((Map) oldMap0);
}
if (mapFieldReuse0 != (null)) {
mapFieldReuse0 .clear();
mapField1 = mapFieldReuse0;
} else {
mapField1 = new HashMap<Utf8, IndexedRecord>(((int)(((chunkLen0 * 4)+ 2)/ 3)));
}
do {
for (int counter0 = 0; (counter0 <chunkLen0); counter0 ++) {
Utf8 key0 = (decoder.readString(null));
mapField1 .put(key0, deserializerecordField0(null, (decoder)));
}
chunkLen0 = (decoder.mapNext());
} while (chunkLen0 > 0);
} else {
mapField1 = new HashMap<Utf8, IndexedRecord>(0);
}
TestDecodeFailureValue.put(0, mapField1);
int unionIndex0 = (decoder.readIndex());
if (unionIndex0 == 0) {
decoder.readNull();
TestDecodeFailureValue.put(1, null);
} else {
if (unionIndex0 == 1) {
TestDecodeFailureValue.put(1, (decoder.readLong()));
} else {
throw new RuntimeException(("Illegal union index for 'nullableLong1': "+ unionIndex0));
}
}
return TestDecodeFailureValue;
}
public IndexedRecord deserializerecordField0(Object reuse, Decoder decoder)
throws IOException
{
IndexedRecord recordField;
if ((((reuse)!= null)&&((reuse) instanceof IndexedRecord))&&(((IndexedRecord)(reuse)).getSchema() == mapFieldMapValueSchema0)) {
recordField = ((IndexedRecord)(reuse));
} else {
recordField = new org.apache.avro.generic.GenericData.Record(mapFieldMapValueSchema0);
}
return recordField;
}
}
Here, deserializerecordField0
is incorrect since it doesn't consume from the decoder.
I am working on a fix, but created this issue for tracking purposes