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 ed2dbd4d8 AVRO-2764: explain union
ed2dbd4d8 is described below
commit ed2dbd4d871e9ab1992c39e38d9d56f33ce55127
Author: Christophe Le Saec <[email protected]>
AuthorDate: Thu Jul 27 14:38:11 2023 +0200
AVRO-2764: explain union
---
.../avro/src/main/java/org/apache/avro/Schema.java | 8 +++
.../test/java/org/apache/avro/TestUnionError.java | 84 ++++++++++++++++++++++
2 files changed, 92 insertions(+)
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 97513f52f..14924c184 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
@@ -48,6 +48,8 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
+
import org.apache.avro.util.internal.Accessor;
import org.apache.avro.util.internal.Accessor.FieldAccessor;
import org.apache.avro.util.internal.JacksonUtils;
@@ -1280,6 +1282,12 @@ public abstract class Schema extends JsonProperties
implements Serializable {
type.toJson(names, gen);
gen.writeEndArray();
}
+
+ @Override
+ public String getName() {
+ return super.getName()
+ +
this.getTypes().stream().map(Schema::getName).collect(Collectors.joining(", ",
"[", "]"));
+ }
}
private static class FixedSchema extends NamedSchema {
diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
new file mode 100644
index 000000000..7f5e48fb9
--- /dev/null
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestUnionError.java
@@ -0,0 +1,84 @@
+/*
+ * 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
+ *
+ * https://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.avro;
+
+import org.apache.avro.generic.GenericData;
+import org.apache.avro.generic.GenericDatumReader;
+import org.apache.avro.generic.GenericDatumWriter;
+import org.apache.avro.generic.GenericRecord;
+import org.apache.avro.io.BinaryDecoder;
+import org.apache.avro.io.BinaryEncoder;
+import org.apache.avro.io.DecoderFactory;
+import org.apache.avro.io.EncoderFactory;
+
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class TestUnionError {
+
+ @Test
+ void unionErrorMessage() throws IOException {
+ String writerSchemaJson = " {\n" + " \"type\" :
\"record\",\n"
+ + " \"name\" : \"C\",\n" + " \"fields\" : [
{\n"
+ + " \"name\" : \"c\",\n" + " \"type\" :
[ {\n"
+ + " \"type\" : \"record\",\n" + "
\"name\" : \"A\",\n"
+ + " \"fields\" : [ {\n" + "
\"name\" : \"amount\",\n"
+ + " \"type\" : \"int\"\n" + " }
]\n" + " }, {\n"
+ + " \"type\" : \"record\",\n" + "
\"name\" : \"B\",\n"
+ + " \"fields\" : [ {\n" + "
\"name\" : \"amount1\",\n"
+ + " \"type\" : \"int\"\n" + " }
]\n" + " } ]\n"
+ + " } ]\n" + " }";
+ Schema writerSchema = new Schema.Parser().parse(writerSchemaJson);
+
+ String readerSchemaJson = " {\n" + " \"type\" :
\"record\",\n" + " \"name\" : \"C1\",\n"
+ + " \"fields\" : [ {\n" + " \"name\" :
\"c\",\n"
+ + " \"type\" : [ {\n" + " \"type\" :
\"record\",\n"
+ + " \"name\" : \"A\",\n" + "
\"fields\" : [ {\n"
+ + " \"name\" : \"amount\",\n" + "
\"type\" : \"int\"\n"
+ + " } ]\n" + " }, \"float\" ]\n" + "
} ]\n" + " }";
+ Schema readerSchema = new Schema.Parser().parse(readerSchemaJson);
+
+ List<Schema> unionSchemas = writerSchema.getField("c").schema().getTypes();
+
+ GenericRecord r = new GenericData.Record(writerSchema);
+ GenericRecord b = new GenericData.Record(unionSchemas.get(1));
+ b.put("amount1", 12);
+ r.put("c", b);
+
+ ByteArrayOutputStream outs = new ByteArrayOutputStream();
+ GenericDatumWriter<GenericRecord> datumWriter = new
GenericDatumWriter<>(writerSchema);
+ BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(outs, null);
+ datumWriter.write(r, encoder);
+ encoder.flush();
+
+ InputStream ins = new ByteArrayInputStream(outs.toByteArray());
+ BinaryDecoder decoder = DecoderFactory.get().binaryDecoder(ins, null);
+
+ GenericDatumReader<GenericRecord> datumReader = new
GenericDatumReader<>(writerSchema, readerSchema);
+ AvroTypeException avroException = assertThrows(AvroTypeException.class, ()
-> datumReader.read(null, decoder));
+ assertEquals("Found B, expecting union[A, float]",
avroException.getMessage());
+ }
+}