diff --git a/pom.xml b/pom.xml index 8c2257f..bb2130d 100644 --- a/pom.xml +++ b/pom.xml @@ -254,6 +254,12 @@ com.google.code.tempus-fugit tempus-fugit ${tempus-fugit.version} + + + org.hamcrest + hamcrest-core + + com.googlecode.javaewah diff --git a/serde/src/java/org/apache/hadoop/hive/serde2/avro/SchemaToTypeInfo.java b/serde/src/java/org/apache/hadoop/hive/serde2/avro/SchemaToTypeInfo.java index e60168c..35d83bd 100644 --- a/serde/src/java/org/apache/hadoop/hive/serde2/avro/SchemaToTypeInfo.java +++ b/serde/src/java/org/apache/hadoop/hive/serde2/avro/SchemaToTypeInfo.java @@ -217,7 +217,9 @@ private static TypeInfo generateRecordTypeInfo(Schema schema, if (seenSchemas == null) { seenSchemas = Collections.newSetFromMap(new IdentityHashMap()); } else if (seenSchemas.contains(schema)) { - return primitiveTypeToTypeInfo.get(Schema.Type.NULL); + throw new AvroSerdeException( + "Recursive schemas are not supported. Recursive schema was " + schema + .getFullName()); } seenSchemas.add(schema); diff --git a/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java b/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java index 0b94dc5..45be2dd 100644 --- a/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java +++ b/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestAvroSerializer.java @@ -491,48 +491,4 @@ public void canSerializeFixed() throws SerDeException, IOException { assertArrayEquals(fixed.bytes(), ((GenericData.Fixed) r.get("fixed1")).bytes()); } - - @Test - public void canSerializeCyclesInSchema() throws SerDeException, IOException { - // Create parent-child avro-record and avro-schema - AvroCycleParent parent = new AvroCycleParent(); - AvroCycleChild child = new AvroCycleChild(); - parent.setChild (child); - Schema parentS = ReflectData.AllowNull.get().getSchema(AvroCycleParent.class); - GenericData.Record parentRec = new GenericData.Record(parentS); - Schema childS = ReflectData.AllowNull.get().getSchema(AvroCycleChild.class); - GenericData.Record childRec = new GenericData.Record(childS); - parentRec.put("child", childRec); - - // Initialize Avro SerDe - AvroSerializer as = new AvroSerializer(); - AvroDeserializer ad = new AvroDeserializer(); - AvroObjectInspectorGenerator aoig = new AvroObjectInspectorGenerator(parentS); - ObjectInspector oi = aoig.getObjectInspector(); - List columnNames = aoig.getColumnNames(); - List columnTypes = aoig.getColumnTypes(); - - // Check serialization and deserialization - AvroGenericRecordWritable agrw = Utils.serializeAndDeserializeRecord(parentRec); - Object obj = ad.deserialize(columnNames, columnTypes, agrw, parentS); - - Writable result = as.serialize(obj, oi, columnNames, columnTypes, parentS); - assertTrue(result instanceof AvroGenericRecordWritable); - GenericRecord r2 = ((AvroGenericRecordWritable) result).getRecord(); - assertEquals(parentS, r2.getSchema()); - } - - private static class AvroCycleParent { - AvroCycleChild child; - public AvroCycleChild getChild () {return child;} - public void setChild (AvroCycleChild child) {this.child = child;} - } - - private static class AvroCycleChild { - AvroCycleParent parent; - AvroCycleChild next; - Map map; - public AvroCycleParent getParent () {return parent;} - public void setParent (AvroCycleParent parent) {this.parent = parent;} - } } diff --git a/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestSchemaToTypeInfo.java b/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestSchemaToTypeInfo.java new file mode 100644 index 0000000..691ca75 --- /dev/null +++ b/serde/src/test/org/apache/hadoop/hive/serde2/avro/TestSchemaToTypeInfo.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hadoop.hive.serde2.avro; + +import org.apache.avro.Schema; +import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; +import java.util.List; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + + +public class TestSchemaToTypeInfo { + + @Rule + public ExpectedException expect = ExpectedException.none(); + + @Test + public void testDisallowRecursiveSchema() + throws AvroSerdeException { + + expect.expect(AvroSerdeException.class); + expect.expectMessage("Recursive schemas are not supported"); + + final String schemaString = "{\n" + + " \"type\" : \"record\",\n" + + " \"name\" : \"Cycle\",\n" + + " \"namespace\" : \"org.apache.hadoop.hive.serde2.avro\",\n" + + " \"fields\" : [ {\n" + + " \"name\" : \"child\",\n" + + " \"type\" : [ \"null\", \"Cycle\"],\n" + + " \"default\" : null\n" + + " } ]\n" + + "}"; + + List types = SchemaToTypeInfo.generateColumnTypes(new Schema.Parser().parse(schemaString)); + } +} \ No newline at end of file