linkedin / avro-util

Collection of utilities to allow writing java code that operates across a wide range of avro versions.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Class generated for schema with nested Maps is incorrect

nisargthakkar opened this issue · comments

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