You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@avro.apache.org by mg...@apache.org on 2022/01/20 07:47:46 UTC

[avro] branch master updated: AVRO-3302: Add support for recursive types using Fixed schema

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

mgrigorov 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 29197da  AVRO-3302: Add support for recursive types using Fixed schema
29197da is described below

commit 29197da2a94c889faa9101c92b7c60fed6a6db0b
Author: Martin Tzvetanov Grigorov <mg...@apache.org>
AuthorDate: Thu Jan 20 09:46:03 2022 +0200

    AVRO-3302: Add support for recursive types using Fixed schema
    
    Similar to
    https://github.com/apache/avro/commit/064cc6b4bd1c6dcf59da989e712a27f0a955f70d
    for Enum
    Reported at https://github.com/flavray/avro-rs/pull/99#issuecomment-1016948451
    
    Signed-off-by: Martin Tzvetanov Grigorov <mg...@apache.org>
---
 lang/rust/src/schema.rs | 65 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 58 insertions(+), 7 deletions(-)

diff --git a/lang/rust/src/schema.rs b/lang/rust/src/schema.rs
index 5415d35..a60e047 100644
--- a/lang/rust/src/schema.rs
+++ b/lang/rust/src/schema.rs
@@ -789,7 +789,7 @@ impl Parser {
                 "enum" => self.parse_enum(complex),
                 "array" => self.parse_array(complex),
                 "map" => self.parse_map(complex),
-                "fixed" => Self::parse_fixed(complex),
+                "fixed" => self.parse_fixed(complex),
                 other => self.parse_known_schema(other),
             },
             Some(&Value::Object(ref data)) => self.parse_complex(data),
@@ -914,7 +914,7 @@ impl Parser {
 
     /// Parse a `serde_json::Value` representing a Avro fixed type into a
     /// `Schema`.
-    fn parse_fixed(complex: &Map<String, Value>) -> AvroResult<Schema> {
+    fn parse_fixed(&mut self, complex: &Map<String, Value>) -> AvroResult<Schema> {
         let name = Name::parse(complex)?;
 
         let doc = complex.get("doc").and_then(|v| match &v {
@@ -927,11 +927,14 @@ impl Parser {
             .and_then(|v| v.as_i64())
             .ok_or(Error::GetFixedSizeField)?;
 
-        Ok(Schema::Fixed {
-            name,
+        let schema = Schema::Fixed {
+            name: name.clone(),
             doc,
             size: size as usize,
-        })
+        };
+        self.parsed_schemas
+            .insert(name.fullname(None), schema.clone());
+        Ok(schema)
     }
 }
 
@@ -1560,8 +1563,8 @@ mod tests {
               ]
             }
           ]
-}
-"#;
+        }
+        "#;
 
         let schema = Schema::parse_str(schema).unwrap();
         let schema_str = schema.canonical_form();
@@ -1570,6 +1573,54 @@ mod tests {
     }
 
     #[test]
+    fn test_parsing_of_recursive_type_fixed() {
+        let schema = r#"
+    {
+        "type": "record",
+        "name": "User",
+        "namespace": "office",
+        "fields": [
+            {
+              "name": "details",
+              "type": [
+                {
+                  "type": "record",
+                  "name": "Employee",
+                  "fields": [
+                    {
+                      "name": "id",
+                      "type": {
+                        "type": "fixed",
+                        "name": "EmployeeId",
+                        "size": 16
+                      },
+                      "default": "female"
+                    }
+                  ]
+                },
+                {
+                  "type": "record",
+                  "name": "Manager",
+                  "fields": [
+                    {
+                      "name": "id",
+                      "type": "EmployeeId"
+                    }
+                  ]
+                }
+              ]
+            }
+          ]
+        }
+        "#;
+
+        let schema = Schema::parse_str(schema).unwrap();
+        let schema_str = schema.canonical_form();
+        let expected = r#"{"name":"office.User","type":"record","fields":[{"name":"details","type":[{"name":"Employee","type":"record","fields":[{"name":"id","type":{"name":"EmployeeId","type":"fixed","size":16}}]},{"name":"Manager","type":"record","fields":[{"name":"id","type":{"name":"EmployeeId","type":"fixed","size":16}}]}]}]}"#;
+        assert_eq!(schema_str, expected);
+    }
+
+    #[test]
     fn test_enum_schema() {
         let schema = Schema::parse_str(
             r#"{"type": "enum", "name": "Suit", "symbols": ["diamonds", "spades", "clubs", "hearts"]}"#,