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());
+ }
+
+}