diff --git serde/src/java/org/apache/hadoop/hive/serde2/avro/AvroLazyObjectInspector.java serde/src/java/org/apache/hadoop/hive/serde2/avro/AvroLazyObjectInspector.java index 9fc9873..7d6aedd 100644 --- serde/src/java/org/apache/hadoop/hive/serde2/avro/AvroLazyObjectInspector.java +++ serde/src/java/org/apache/hadoop/hive/serde2/avro/AvroLazyObjectInspector.java @@ -138,7 +138,7 @@ public Object getStructFieldData(Object data, StructField f) { if (rowField instanceof LazyStruct) { - if (LOG.isDebugEnabled()) { + if (LOG.isDebugEnabled() && rowField != null) { LOG.debug("Deserializing struct [" + rowField.getClass() + "]"); } @@ -166,7 +166,7 @@ public Object getStructFieldData(Object data, StructField f) { } else { if (LOG.isDebugEnabled()) { - LOG.debug("Returning [" + rowField.toString() + "] for field [" + f.getFieldName() + "]"); + LOG.debug("Returning [" + rowField + "] for field [" + f.getFieldName() + "]"); } // Just return the object. We need no further operation on it @@ -223,7 +223,7 @@ private Object deserializeStruct(Object struct, String fieldName) { byte[] data = ((LazyStruct) struct).getBytes(); AvroDeserializer deserializer = new AvroDeserializer(); - if (data == null) { + if (data == null || data.length == 0) { return null; } @@ -239,6 +239,13 @@ private Object deserializeStruct(Object struct, String fieldName) { AvroGenericRecordWritable avroWritable = new AvroGenericRecordWritable(); if (readerSchema == null) { + + offset = schemaRetriever.getOffset(); + + if (data.length < offset) { + throw new IllegalArgumentException("Data size cannot be less than [" + offset + + "]. Found [" + data.length + "]"); + } rs = schemaRetriever.retrieveReaderSchema(data); @@ -257,13 +264,6 @@ private Object deserializeStruct(Object struct, String fieldName) { } // adjust the data bytes according to any possible offset that was provided - offset = schemaRetriever.getOffset(); - - if (data.length < offset) { - throw new IllegalArgumentException("Data size cannot be less than [" + offset - + "]. Found [" + data.length + "]"); - } - if (LOG.isDebugEnabled()) { LOG.debug("Retrieved writer Schema: " + ws.toString()); LOG.debug("Retrieved reader Schema: " + rs.toString()); diff --git serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroLazyObjectInspector.java serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroLazyObjectInspector.java new file mode 100644 index 0000000..e6f8eb5 --- /dev/null +++ serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroLazyObjectInspector.java @@ -0,0 +1,59 @@ +package org.apache.hadoop.hive.serde2.avro; + +import static org.junit.Assert.assertNull; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.hadoop.hive.serde2.lazy.ByteArrayRef; +import org.apache.hadoop.hive.serde2.lazy.LazyStruct; +import org.apache.hadoop.hive.serde2.lazy.objectinspector.LazyObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.lazy.objectinspector.primitive.LazyPrimitiveObjectInspectorFactory; +import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector; +import org.apache.hadoop.hive.serde2.objectinspector.StructField; +import org.apache.hadoop.io.Text; +import org.junit.Test; + +public class TestAvroLazyObjectInspector { + + @Test + public void testEmptyData(){ + List fieldNames = new ArrayList(); + fieldNames.add("myField"); + + List ois = new ArrayList(); + ois.add(LazyPrimitiveObjectInspectorFactory.getLazyStringObjectInspector(false, new Byte((byte) 0))); + + AvroLazyObjectInspector aloi = new AvroLazyObjectInspector(fieldNames, ois, null, (byte)0, new Text(), false, false, (byte)0); + LazyStruct lazyStruct = new LazyStruct(LazyObjectInspectorFactory.getLazySimpleStructObjectInspector(fieldNames, ois, (byte)0, new Text(), false, false, (byte)0)); + + ByteArrayRef byteArrayRef = new ByteArrayRef(); + byteArrayRef.setData(new byte[0]); // set data to empty explicitly + lazyStruct.init(byteArrayRef, 0, 0); + + assertNull(aloi.getStructFieldData(lazyStruct, new TestStructField())); + } + + class TestStructField implements StructField { + + @Override + public String getFieldName() { + return "testfield"; + } + + @Override + public ObjectInspector getFieldObjectInspector() { + return LazyPrimitiveObjectInspectorFactory.getLazyStringObjectInspector(false, new Byte((byte) 0)); + } + + @Override + public int getFieldID() { + return 0; + } + + @Override + public String getFieldComment() { + return null; + } + } +}