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

mgrigorov pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/avro.git


The following commit(s) were added to refs/heads/main by this push:
     new 8ecb576f4 [C++] AVRO-4058: Allow custom attributes in arrays (#3168)
8ecb576f4 is described below

commit 8ecb576f4100b902ef225808a482e217093551f0
Author: Pascal Ginter <[email protected]>
AuthorDate: Tue Sep 24 15:00:53 2024 +0200

    [C++] AVRO-4058: Allow custom attributes in arrays (#3168)
    
    * Allow custom attributes on array values
    
    * Fix merge error of undoing conversion of custom attribute to string
    
    ---------
    
    Co-authored-by: Pascal Ginter <[email protected]~>
---
 lang/c++/impl/Compiler.cc         | 5 ++++-
 lang/c++/impl/NodeImpl.cc         | 3 +++
 lang/c++/include/avro/NodeImpl.hh | 4 ++--
 lang/c++/test/SchemaTests.cc      | 9 +++++----
 4 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/lang/c++/impl/Compiler.cc b/lang/c++/impl/Compiler.cc
index f3c2397da..797e8b381 100644
--- a/lang/c++/impl/Compiler.cc
+++ b/lang/c++/impl/Compiler.cc
@@ -267,7 +267,7 @@ static const std::unordered_set<std::string> 
&getKnownFields() {
     // return known fields
     static const std::unordered_set<std::string> kKnownFields =
         {"name", "type", "aliases", "default", "doc", "size", "logicalType",
-         "values", "precision", "scale", "namespace"};
+         "values", "precision", "scale", "namespace", "items"};
     return kKnownFields;
 }
 
@@ -424,6 +424,9 @@ static NodePtr makeArrayNode(const Entity &e, const Object 
&m,
     if (containsField(m, "doc")) {
         node->setDoc(getDocField(e, m));
     }
+    CustomAttributes customAttributes;
+    getCustomAttributes(m, customAttributes);
+    node->addCustomAttributesForField(customAttributes);
     return node;
 }
 
diff --git a/lang/c++/impl/NodeImpl.cc b/lang/c++/impl/NodeImpl.cc
index e3073aaae..a17732bcc 100644
--- a/lang/c++/impl/NodeImpl.cc
+++ b/lang/c++/impl/NodeImpl.cc
@@ -554,6 +554,9 @@ void NodeArray::printJson(std::ostream &os, size_t depth) 
const {
     os << indent(depth + 1) << "\"items\": ";
     leafAttributes_.get()->printJson(os, depth + 1);
     os << '\n';
+    for (size_t i = 0; i != customAttributes_.size(); i++){
+        printCustomAttributes(customAttributes_.get(i), depth + 1, os);
+    }
     os << indent(depth) << '}';
 }
 
diff --git a/lang/c++/include/avro/NodeImpl.hh 
b/lang/c++/include/avro/NodeImpl.hh
index 3e5546c94..b4759f70e 100644
--- a/lang/c++/include/avro/NodeImpl.hh
+++ b/lang/c++/include/avro/NodeImpl.hh
@@ -234,7 +234,7 @@ using NodeImplSymbolic = NodeImpl<HasName, NoLeaves, 
NoLeafNames, NoAttributes,
 
 using NodeImplRecord = NodeImpl<HasName, MultiLeaves, LeafNames, 
MultiAttributes, NoSize>;
 using NodeImplEnum = NodeImpl<HasName, NoLeaves, LeafNames, NoAttributes, 
NoSize>;
-using NodeImplArray = NodeImpl<NoName, SingleLeaf, NoLeafNames, NoAttributes, 
NoSize>;
+using NodeImplArray = NodeImpl<NoName, SingleLeaf, NoLeafNames, 
MultiAttributes, NoSize>;
 using NodeImplMap = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoAttributes, 
NoSize>;
 using NodeImplUnion = NodeImpl<NoName, MultiLeaves, NoLeafNames, NoAttributes, 
NoSize>;
 using NodeImplFixed = NodeImpl<HasName, NoLeaves, NoLeafNames, NoAttributes, 
HasSize>;
@@ -363,7 +363,7 @@ class AVRO_DECL NodeArray : public NodeImplArray {
 public:
     NodeArray() : NodeImplArray(AVRO_ARRAY) {}
 
-    explicit NodeArray(const SingleLeaf &items) : NodeImplArray(AVRO_ARRAY, 
NoName(), items, NoLeafNames(), NoAttributes(), NoSize()) {}
+    explicit NodeArray(const SingleLeaf &items) : NodeImplArray(AVRO_ARRAY, 
NoName(), items, NoLeafNames(), {}, NoSize()) {}
 
     SchemaResolution resolve(const Node &reader) const override;
 
diff --git a/lang/c++/test/SchemaTests.cc b/lang/c++/test/SchemaTests.cc
index 6f9c93d6d..477e36046 100644
--- a/lang/c++/test/SchemaTests.cc
+++ b/lang/c++/test/SchemaTests.cc
@@ -143,7 +143,7 @@ const char *basicSchemas[] = {
         "extra attribute": 1
     })",
     R"({"type": "enum", "name": "Test", "symbols": ["A", "B"],"extra 
attribute": 1})",
-    R"({"type": "array", "items": "long", "extra attribute": 1})",
+    R"({"type": "array", "items": "long", "extra attribute": "1"})",
     R"({"type": "map", "values": "long", "extra attribute": 1})",
     R"({"type": "fixed", "name": "Test", "size": 1, "extra attribute": 1})",
 
@@ -355,7 +355,8 @@ const char *roundTripSchemas[] = {
             {"name":"f1","type":"long","extra_field":"1"},
             {"name":"f2","type":"int","extra_field1":"21","extra_field2":"22"}
         ]
-    })"
+    })",
+    R"({"type":"array","items":"long","extra":"1"})"
 };
 
 const char *malformedLogicalTypes[] = {
@@ -448,11 +449,11 @@ static void testRoundTrip(const char *schema) {
     compiledSchema.toJson(os);
     std::string result = removeWhitespaceFromSchema(os.str());
     std::string trimmedSchema = removeWhitespaceFromSchema(schema);
-    BOOST_CHECK(result == trimmedSchema);
+    BOOST_CHECK_EQUAL(result, trimmedSchema);
     // Verify that the compact schema from toJson has the same content as the
     // schema.
     std::string result2 = compiledSchema.toJson(false);
-    BOOST_CHECK(result2 == trimmedSchema);
+    BOOST_CHECK_EQUAL(result2, trimmedSchema);
 }
 
 static void testCompactSchemas() {

Reply via email to