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 2a46a61b6 AVRO-3219: Add nullable enum type field support in 
Avro.Reflect (#1348)
2a46a61b6 is described below

commit 2a46a61b65697706e2277921c3bf5ccb819c311f
Author: Zike Yang <[email protected]>
AuthorDate: Thu Jul 7 07:18:25 2022 +0800

    AVRO-3219: Add nullable enum type field support in Avro.Reflect (#1348)
    
    * AVRO-3219: Add nullable enum type field support.
    
    Signed-off-by: Zike Yang <[email protected]>
    
    * Apply comments.
    
    Signed-off-by: Zike Yang <[email protected]>
    
    * Fix mistakenly removed the enum type check.
    
    Signed-off-by: Zike Yang <[email protected]>
---
 lang/csharp/src/apache/main/Reflect/ClassCache.cs  | 16 +++++++++--
 lang/csharp/src/apache/test/Reflect/TestReflect.cs | 33 ++++++++++++++++++++--
 2 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/lang/csharp/src/apache/main/Reflect/ClassCache.cs 
b/lang/csharp/src/apache/main/Reflect/ClassCache.cs
index d01d11b49..a64e06d26 100644
--- a/lang/csharp/src/apache/main/Reflect/ClassCache.cs
+++ b/lang/csharp/src/apache/main/Reflect/ClassCache.cs
@@ -263,17 +263,27 @@ namespace Avro.Reflect
                     EnumCache.AddEnumNameMapItem(ns, objType);
                     break;
                 case UnionSchema us:
-                    if (us.Schemas.Count == 2 && (us.Schemas[0].Tag == 
Schema.Type.Null || us.Schemas[1].Tag == Schema.Type.Null) && objType.IsClass)
+                    if (us.Schemas.Count == 2 && (us.Schemas[0].Tag == 
Schema.Type.Null || us.Schemas[1].Tag == Schema.Type.Null))
                     {
                         // in this case objType will match the non null type 
in the union
                         foreach (var o in us.Schemas)
                         {
-                            if (o.Tag != Schema.Type.Null)
+                            if (o.Tag == Schema.Type.Null)
+                            {
+                                continue;
+                            }
+
+                            if (objType.IsClass)
                             {
                                 LoadClassCache(objType, o);
                             }
-                        }
 
+                            var innerType = 
Nullable.GetUnderlyingType(objType);
+                            if (innerType != null && innerType.IsEnum)
+                            {
+                                LoadClassCache(innerType, o);
+                            }
+                        }
                     }
                     else
                     {
diff --git a/lang/csharp/src/apache/test/Reflect/TestReflect.cs 
b/lang/csharp/src/apache/test/Reflect/TestReflect.cs
index bea5ef23f..5cf572539 100644
--- a/lang/csharp/src/apache/test/Reflect/TestReflect.cs
+++ b/lang/csharp/src/apache/test/Reflect/TestReflect.cs
@@ -40,17 +40,22 @@ namespace Avro.Test
             public EnumResolutionEnum enumType { get; set; }
         }
 
+        class NullableEnumResolutionRecord
+        {
+            public EnumResolutionEnum? enumType { get; set; }
+        }
+
         [TestCase]
         public void TestEnumResolution()
         {
             Schema writerSchema = 
Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\","
 +
-                                        
"\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\": 
\"EnumType\", \"symbols\": [\"FIRST\", \"SECOND\"]} }]}");
+                                               
"\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\": 
\"EnumType\", \"symbols\": [\"FIRST\", \"SECOND\"]} }]}");
 
             var testRecord = new EnumResolutionRecord();
 
             Schema readerSchema = 
Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\","
 +
-                                        
"\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\":" +
-                                        " \"EnumType\", \"symbols\": 
[\"THIRD\", \"FIRST\", \"SECOND\"]} }]}");;
+                                               
"\"fields\":[{\"name\":\"enumType\",\"type\": { \"type\": \"enum\", \"name\":" +
+                                               " \"EnumType\", \"symbols\": 
[\"THIRD\", \"FIRST\", \"SECOND\"]} }]}");;
             testRecord.enumType = EnumResolutionEnum.SECOND;
 
             // serialize
@@ -61,6 +66,28 @@ namespace Avro.Test
             Assert.AreEqual( EnumResolutionEnum.SECOND, rec2.enumType );
         }
 
+        [TestCase]
+        public void TestNullableEnumResolution()
+        {
+            Schema writerSchema = 
Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\","
 +
+                                        
"\"fields\":[{\"name\":\"enumType\",\"type\":[\"null\", { \"type\": \"enum\", 
\"name\": " +
+                                        "\"EnumType\",\"symbols\": [\"THIRD\", 
\"FIRST\", \"SECOND\"]}] }]}");
+
+            var testRecord = new NullableEnumResolutionRecord();
+
+            Schema readerSchema = 
Schema.Parse("{\"type\":\"record\",\"name\":\"EnumRecord\",\"namespace\":\"Avro.Test\","
 +
+                                               
"\"fields\":[{\"name\":\"enumType\",\"type\":[\"null\", { \"type\": \"enum\", 
\"name\": " +
+                                               "\"EnumType\", \"symbols\": 
[\"THIRD\", \"FIRST\", \"SECOND\"]}] }]}");
+            testRecord.enumType = EnumResolutionEnum.SECOND;
+
+            // serialize
+            var stream = serialize(writerSchema, testRecord);
+
+            // deserialize
+            var rec2 = deserialize<NullableEnumResolutionRecord>(stream, 
writerSchema, readerSchema);
+            Assert.AreEqual( EnumResolutionEnum.SECOND, rec2.enumType );
+        }
+
         private static S deserialize<S>(Stream ms, Schema ws, Schema rs) where 
S : class
         {
             long initialPos = ms.Position;

Reply via email to