You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by rs...@apache.org on 2022/02/05 10:55:36 UTC

[avro] branch master updated: AVRO-3133: Fix enum resolution to be consistent with Apache Avro specification and the schema compatibility checks (#1381)

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

rskraba 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 c35add7  AVRO-3133: Fix enum resolution to be consistent with Apache Avro specification and the schema compatibility checks (#1381)
c35add7 is described below

commit c35add7b29b5fab9229d79927a74f327bd56fa70
Author: Adam McDevitt <ad...@gmail.com>
AuthorDate: Sat Feb 5 10:55:25 2022 +0000

    AVRO-3133: Fix enum resolution to be consistent with Apache Avro specification and the schema compatibility checks (#1381)
    
    * AVRO-3133: add schema compat test
    
    add schema compatibility test to demonstrate that schema compatibility checks are consistent with the avro specification
    
    * AVRO-3133: fix ENUM and FIXED resolvers
    
    fix resolvers for ENUM and FIXED by having then compare unqualified name rather than qualified name
    
    * remove duplicate test
    
    * add missing test cases
    
    * add test for writer with extra enum symbol and reader with default value
    
    * reuse schemas from TestSchemas in TestResolvingGrammarGenerator
    
    this required a change in visibility to two of the static members
    
    * fix formatting
---
 .../avro/src/main/java/org/apache/avro/Resolver.java     |  4 ++--
 .../java/org/apache/avro/TestSchemaCompatibility.java    |  7 +++++++
 .../avro/src/test/java/org/apache/avro/TestSchemas.java  | 10 +++++++++-
 .../avro/io/parsing/TestResolvingGrammarGenerator.java   | 16 ++++++++++++++++
 4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/lang/java/avro/src/main/java/org/apache/avro/Resolver.java b/lang/java/avro/src/main/java/org/apache/avro/Resolver.java
index 182a91b..9db847c 100644
--- a/lang/java/avro/src/main/java/org/apache/avro/Resolver.java
+++ b/lang/java/avro/src/main/java/org/apache/avro/Resolver.java
@@ -90,7 +90,7 @@ public class Resolver {
         return new DoNothing(w, r, d);
 
       case FIXED:
-        if (w.getFullName() != null && !w.getFullName().equals(r.getFullName())) {
+        if (w.getName() != null && !w.getName().equals(r.getName())) {
           return new ErrorAction(w, r, d, ErrorType.NAMES_DONT_MATCH);
         } else if (w.getFixedSize() != r.getFixedSize()) {
           return new ErrorAction(w, r, d, ErrorType.SIZES_DONT_MATCH);
@@ -388,7 +388,7 @@ public class Resolver {
      * appropriate {@link EnumAdjust} is.
      */
     public static Action resolve(Schema w, Schema r, GenericData d) {
-      if (w.getFullName() != null && !w.getFullName().equals(r.getFullName()))
+      if (w.getName() != null && !w.getName().equals(r.getName()))
         return new ErrorAction(w, r, d, ErrorType.NAMES_DONT_MATCH);
 
       final List<String> wsymbols = w.getEnumSymbols();
diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
index 27d47d2..5f7b628 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchemaCompatibility.java
@@ -39,6 +39,9 @@ import static org.apache.avro.TestSchemas.EMPTY_RECORD1;
 import static org.apache.avro.TestSchemas.EMPTY_UNION_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM1_ABC_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA;
+import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA_DEFAULT;
+import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA_NAMESPACE_1;
+import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA_NAMESPACE_2;
 import static org.apache.avro.TestSchemas.ENUM1_BC_SCHEMA;
 import static org.apache.avro.TestSchemas.ENUM_ABC_ENUM_DEFAULT_A_RECORD;
 import static org.apache.avro.TestSchemas.ENUM_ABC_ENUM_DEFAULT_A_SCHEMA;
@@ -259,6 +262,10 @@ public class TestSchemaCompatibility {
       new ReaderWriter(INT_MAP_SCHEMA, INT_MAP_SCHEMA), new ReaderWriter(LONG_MAP_SCHEMA, INT_MAP_SCHEMA),
 
       new ReaderWriter(ENUM1_AB_SCHEMA, ENUM1_AB_SCHEMA), new ReaderWriter(ENUM1_ABC_SCHEMA, ENUM1_AB_SCHEMA),
+      new ReaderWriter(ENUM1_AB_SCHEMA_DEFAULT, ENUM1_ABC_SCHEMA),
+      new ReaderWriter(ENUM1_AB_SCHEMA, ENUM1_AB_SCHEMA_NAMESPACE_1),
+      new ReaderWriter(ENUM1_AB_SCHEMA_NAMESPACE_1, ENUM1_AB_SCHEMA),
+      new ReaderWriter(ENUM1_AB_SCHEMA_NAMESPACE_1, ENUM1_AB_SCHEMA_NAMESPACE_2),
 
       // String-to/from-bytes, introduced in Avro 1.7.7
       new ReaderWriter(STRING_SCHEMA, BYTES_SCHEMA), new ReaderWriter(BYTES_SCHEMA, STRING_SCHEMA),
diff --git a/lang/java/avro/src/test/java/org/apache/avro/TestSchemas.java b/lang/java/avro/src/test/java/org/apache/avro/TestSchemas.java
index 30cabad..5005bca 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/TestSchemas.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/TestSchemas.java
@@ -24,7 +24,10 @@ import java.util.Collections;
 
 import org.apache.avro.Schema.Field;
 
-/** Schemas used by other tests in this package. Therefore package protected. */
+/**
+ * Schemas used by other tests in this package. Therefore mostly package
+ * protected.
+ */
 public class TestSchemas {
 
   static final Schema NULL_SCHEMA = Schema.create(Schema.Type.NULL);
@@ -45,6 +48,11 @@ public class TestSchemas {
   static final Schema STRING_MAP_SCHEMA = Schema.createMap(STRING_SCHEMA);
 
   static final Schema ENUM1_AB_SCHEMA = Schema.createEnum("Enum1", null, null, list("A", "B"));
+  static final Schema ENUM1_AB_SCHEMA_DEFAULT = Schema.createEnum("Enum1", null, null, list("A", "B"), "A");
+  public static final Schema ENUM1_AB_SCHEMA_NAMESPACE_1 = Schema.createEnum("Enum1", null, "namespace1",
+      list("A", "B"));
+  public static final Schema ENUM1_AB_SCHEMA_NAMESPACE_2 = Schema.createEnum("Enum1", null, "namespace2",
+      list("A", "B"));
   static final Schema ENUM1_ABC_SCHEMA = Schema.createEnum("Enum1", null, null, list("A", "B", "C"));
   static final Schema ENUM1_BC_SCHEMA = Schema.createEnum("Enum1", null, null, list("B", "C"));
   static final Schema ENUM2_AB_SCHEMA = Schema.createEnum("Enum2", null, null, list("A", "B"));
diff --git a/lang/java/avro/src/test/java/org/apache/avro/io/parsing/TestResolvingGrammarGenerator.java b/lang/java/avro/src/test/java/org/apache/avro/io/parsing/TestResolvingGrammarGenerator.java
index 3587055..4eac760 100644
--- a/lang/java/avro/src/test/java/org/apache/avro/io/parsing/TestResolvingGrammarGenerator.java
+++ b/lang/java/avro/src/test/java/org/apache/avro/io/parsing/TestResolvingGrammarGenerator.java
@@ -43,6 +43,9 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
+import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA_NAMESPACE_1;
+import static org.apache.avro.TestSchemas.ENUM1_AB_SCHEMA_NAMESPACE_2;
+
 @RunWith(Parameterized.class)
 public class TestResolvingGrammarGenerator {
   private final Schema schema;
@@ -83,6 +86,19 @@ public class TestResolvingGrammarGenerator {
     }
   }
 
+  @Test
+  public void testDifferingEnumNamespaces() throws Exception {
+    Schema schema1 = SchemaBuilder.record("MyRecord").fields().name("field").type(ENUM1_AB_SCHEMA_NAMESPACE_1)
+        .noDefault().endRecord();
+    Schema schema2 = SchemaBuilder.record("MyRecord").fields().name("field").type(ENUM1_AB_SCHEMA_NAMESPACE_2)
+        .noDefault().endRecord();
+    GenericData.EnumSymbol genericEnumSymbol = new GenericData.EnumSymbol(ENUM1_AB_SCHEMA_NAMESPACE_1, "A");
+    GenericData.Record record = new GenericRecordBuilder(schema1).set("field", genericEnumSymbol).build();
+    byte[] data = writeRecord(schema1, record);
+    Assert.assertEquals(genericEnumSymbol, readRecord(schema1, data).get("field"));
+    Assert.assertEquals(genericEnumSymbol, readRecord(schema2, data).get("field"));
+  }
+
   @Parameterized.Parameters
   public static Collection<Object[]> data() {
     Collection<Object[]> ret = Arrays.asList(new Object[][] {