Index: serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java =================================================================== --- serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java (revision 1394121) +++ serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java (working copy) @@ -207,6 +207,21 @@ } @Test + public void canSerializeNullableEnums() throws SerDeException, IOException { + final String field = "{ \"name\":\"nullableEnum\", \"type\": [\"null\", " + + "{\"type\":\"enum\", \"name\":\"enum1_values\", " + + "\"symbols\":[\"BLUE\",\"RED\", \"GREEN\"]}] }"; + for(enum1 e : enum1.values()) { + GenericRecord r = serializeAndDeserialize(field, "nullableEnum", e); + + assertEquals(e, enum1.valueOf(r.get("nullableEnum").toString())); + } + + GenericRecord r = serializeAndDeserialize(field, "nullableEnum", null); + assertNull(r.get("nullableEnum")); + } + + @Test public void canSerializeBytes() throws SerDeException, IOException { String field = "{ \"name\":\"bytes1\", \"type\":\"bytes\" }"; ByteBuffer bb = ByteBuffer.wrap("easy as one two three".getBytes()); Index: serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroDeserializer.java =================================================================== --- serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroDeserializer.java (revision 1394121) +++ serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroDeserializer.java (working copy) @@ -397,14 +397,27 @@ GenericData.Record record = new GenericData.Record(s); record.put("nullableString", "this is a string"); - verifyNullableType(record, s, "this is a string"); + verifyNullableType(record, s, "nullableString", "this is a string"); record = new GenericData.Record(s); record.put("nullableString", null); - verifyNullableType(record, s, null); + verifyNullableType(record, s, "nullableString", null); } - private void verifyNullableType(GenericData.Record record, Schema s, + @Test + public void canDeserializeNullableEnums() throws IOException, SerDeException { + Schema s = Schema.parse(TestAvroObjectInspectorGenerator.NULLABLE_ENUM_SCHEMA); + GenericData.Record record = new GenericData.Record(s); + record.put("nullableEnum", "CYBERMEN"); + + verifyNullableType(record, s, "nullableEnum", "CYBERMEN"); + + record = new GenericData.Record(s); + record.put("nullableEnum", null); + verifyNullableType(record, s, "nullableEnum", null); + } + + private void verifyNullableType(GenericData.Record record, Schema s, String fieldName, String expected) throws SerDeException, IOException { assertTrue(GENERIC_DATA.validate(s, record)); @@ -420,13 +433,13 @@ StandardStructObjectInspector oi = (StandardStructObjectInspector)aoig.getObjectInspector(); List fieldsDataAsList = oi.getStructFieldsDataAsList(row); assertEquals(1, fieldsDataAsList.size()); - StructField fieldRef = oi.getStructFieldRef("nullablestring"); + StructField fieldRef = oi.getStructFieldRef(fieldName); ObjectInspector fieldObjectInspector = fieldRef.getFieldObjectInspector(); StringObjectInspector soi = (StringObjectInspector)fieldObjectInspector; if(expected == null) assertNull(soi.getPrimitiveJavaObject(rowElement)); else - assertEquals("this is a string", soi.getPrimitiveJavaObject(rowElement)); + assertEquals(expected, soi.getPrimitiveJavaObject(rowElement)); } } Index: serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroObjectInspectorGenerator.java =================================================================== --- serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroObjectInspectorGenerator.java (revision 1394121) +++ serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroObjectInspectorGenerator.java (working copy) @@ -142,6 +142,20 @@ " {\"name\":\"nullableString\", \"type\":[\"null\", \"string\"]}\n" + " ]\n" + "}"; + public static final String NULLABLE_ENUM_SCHEMA = "{\n" + + " \"namespace\": \"clever.namespace.name.in.space\",\n" + + " \"name\": \"nullableUnionTest\",\n" + + " \"type\": \"record\",\n" + + " \"fields\": [\n" + + " {\n" + + " \"name\":\"nullableEnum\",\n" + + " \"type\": [\"null\", {\"type\":\"enum\",\"name\":\"villians\", \"symbols\": " + + "[\"DALEKS\", \"CYBERMEN\", \"SLITHEEN\", \"JAGRAFESS\"]}]\n" + + " \n" + + " \n" + + " }\n" + + " ]\n" + + "}"; public static final String BYTES_SCHEMA = "{\n" + " \"type\": \"record\", \n" + " \"name\": \"bytesTest\",\n" + @@ -483,6 +497,23 @@ assertEquals(PrimitiveObjectInspector.PrimitiveCategory.STRING, pti.getPrimitiveCategory()); } + @Test // That Union[T, NULL] is converted to just T. + public void convertsNullableEnum() throws SerDeException { + Schema s = Schema.parse(NULLABLE_ENUM_SCHEMA); + + AvroObjectInspectorGenerator aoig = new AvroObjectInspectorGenerator(s); + assertEquals(1, aoig.getColumnNames().size()); + assertEquals("nullableEnum", aoig.getColumnNames().get(0)); + + // Column types + assertEquals(1, aoig.getColumnTypes().size()); + TypeInfo typeInfo = aoig.getColumnTypes().get(0); + assertTrue(typeInfo instanceof PrimitiveTypeInfo); + PrimitiveTypeInfo pti = (PrimitiveTypeInfo) typeInfo; + // Verify the union has been hidden and just the main type has been returned. + assertEquals(PrimitiveObjectInspector.PrimitiveCategory.STRING, pti.getPrimitiveCategory()); + } + @Test public void objectInspectorsAreCached() throws SerDeException { // Verify that Hive is caching the object inspectors for us.