This is an automated email from the ASF dual-hosted git repository.

dkulp pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/master by this push:
     new 0beb39d  AVRO-2131 Modified Schema.parse(JsonNode schema, Names names) 
to allow Unions with self references. (#278)
0beb39d is described below

commit 0beb39d78f6bdccb803b8c6eb58af02b2cc80429
Author: Jeff Maxwell <[email protected]>
AuthorDate: Thu Nov 29 13:42:19 2018 -0600

    AVRO-2131 Modified Schema.parse(JsonNode schema, Names names) to allow 
Unions with self references. (#278)
---
 .../avro/src/main/java/org/apache/avro/Schema.java |   7 +-
 .../org/apache/avro/TestUnionSelfReference.java    | 114 +++++++++++++++++++++
 2 files changed, 120 insertions(+), 1 deletion(-)

diff --git a/lang/java/avro/src/main/java/org/apache/avro/Schema.java 
b/lang/java/avro/src/main/java/org/apache/avro/Schema.java
index a87c7a2..f0d1f86 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/Schema.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/Schema.java
@@ -1404,8 +1404,13 @@ public abstract class Schema extends JsonProperties {
           throw new SchemaParseException("Invalid or no size: "+schema);
         result = new FixedSchema(name, doc, sizeNode.intValue());
         if (name != null) names.add(result);
-      } else
+      } else {  //For unions with self reference
+        Name nameFromType = new Name(type, names.space);
+        if (names.containsKey(nameFromType)) {
+          return names.get(nameFromType);
+        }
         throw new SchemaParseException("Type not supported: "+type);
+      }
       Iterator<String> i = schema.fieldNames();
 
       Set reserved = SCHEMA_RESERVED;
diff --git 
a/lang/java/avro/src/test/java/org/apache/avro/TestUnionSelfReference.java 
b/lang/java/avro/src/test/java/org/apache/avro/TestUnionSelfReference.java
new file mode 100644
index 0000000..fa3c23d
--- /dev/null
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestUnionSelfReference.java
@@ -0,0 +1,114 @@
+package org.apache.avro;
+
+import org.slf4j.LoggerFactory;
+
+import static org.junit.Assert.*;
+
+import org.apache.avro.Schema.Field;
+import org.apache.avro.Schema.Type;
+import org.junit.Test;
+import org.slf4j.Logger;
+
+public class TestUnionSelfReference {
+  /** The logger for TestUnionSelfReference */
+  @SuppressWarnings("unused")
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(TestUnionSelfReference.class);
+  
+  private static final String SIMPLE_BINARY_TREE =
+         "{"
+         +"    \"namespace\": \"tree\","
+         +"    \"type\": \"record\","
+         +"    \"name\": \"Node\","
+         +"    \"fields\": ["
+         +"      {"
+         +"        \"name\": \"left\","
+         +"        \"type\": ["
+         +"          \"null\","
+         +"          {"
+         +"            \"type\": \"Node\""
+         +"          }"
+         +"        ],"
+         +"        \"default\": null"
+         +"      },"
+         +"      {"
+         +"        \"name\": \"right\","
+         +"        \"type\": ["
+         +"          \"null\","
+         +"          {"
+         +"            \"type\": \"Node\""
+         +"          }"
+         +"        ],"
+         +"        \"default\": null"
+         +"      }"
+         +"    ]"
+         +"  }";
+  
+  private static final String THREE_TYPE_UNION =
+         "{"
+         +"    \"namespace\": \"tree\","
+         +"    \"type\": \"record\","
+         +"    \"name\": \"Node\","
+         +"    \"fields\": ["
+         +"      {"
+         +"        \"name\": \"left\","
+         +"        \"type\": ["
+         +"          \"null\","
+         +"          \"string\","
+         +"          {"
+         +"            \"type\": \"Node\""
+         +"          }"
+         +"        ],"
+         +"        \"default\": null"
+         +"      },"
+         +"      {"
+         +"        \"name\": \"right\","
+         +"        \"type\": ["
+         +"          \"null\","
+         +"          \"string\","
+         +"          {"
+         +"            \"type\": \"Node\""
+         +"          }"
+         +"        ],"
+         +"        \"default\": null"
+         +"      }"
+         +"    ]"
+         +"  }";
+  @Test
+  public void testSelfReferenceInUnion(){ 
+     Schema schema = new Schema.Parser().parse(SIMPLE_BINARY_TREE);
+     Field leftField = schema.getField("left");
+     assertEquals(JsonProperties.NULL_VALUE,leftField.defaultVal());
+     final Schema leftFieldSchema = leftField.schema();
+     assertEquals(Type.UNION,leftFieldSchema.getType());
+     assertEquals("null",leftFieldSchema.getTypes().get(0).getName());
+     assertEquals("Node",leftFieldSchema.getTypes().get(1).getName());
+     
+     Field rightField = schema.getField("right");
+     assertEquals(JsonProperties.NULL_VALUE,rightField.defaultVal());
+     final Schema rightFieldSchema = rightField.schema();
+     assertEquals(Type.UNION,rightFieldSchema.getType());
+     assertEquals("null",rightFieldSchema.getTypes().get(0).getName());
+     assertEquals("Node",rightFieldSchema.getTypes().get(1).getName());
+  }
+  
+  @Test
+  public void testSelfReferenceInThreeUnion(){ 
+     Schema schema = new Schema.Parser().parse(THREE_TYPE_UNION);
+     Field leftField = schema.getField("left");
+     assertEquals(JsonProperties.NULL_VALUE,leftField.defaultVal());
+     final Schema leftFieldSchema = leftField.schema();
+     assertEquals(Type.UNION,leftFieldSchema.getType());
+     assertEquals("null",leftFieldSchema.getTypes().get(0).getName());
+     assertEquals("string",leftFieldSchema.getTypes().get(1).getName());
+     assertEquals("Node",leftFieldSchema.getTypes().get(2).getName());
+     
+     Field rightField = schema.getField("right");
+     assertEquals(JsonProperties.NULL_VALUE,rightField.defaultVal());
+     final Schema rightFieldSchema = rightField.schema();
+     assertEquals(Type.UNION,rightFieldSchema.getType());
+     assertEquals("null",rightFieldSchema.getTypes().get(0).getName());
+     assertEquals("string",rightFieldSchema.getTypes().get(1).getName());
+     assertEquals("Node",rightFieldSchema.getTypes().get(2).getName());
+  }
+  
+}

Reply via email to