From 8ecb576f4100b902ef225808a482e217093551f0 Mon Sep 17 00:00:00 2001 From: Pascal Ginter <47352129+pascalginter@users.noreply.github.com> Date: Tue, 24 Sep 2024 15:00:53 +0200 Subject: [PATCH] [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 --- 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 f3c2397da24..797e8b3813d 100644 --- a/lang/c++/impl/Compiler.cc +++ b/lang/c++/impl/Compiler.cc @@ -267,7 +267,7 @@ static const std::unordered_set &getKnownFields() { // return known fields static const std::unordered_set 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 e3073aaaef2..a17732bcc51 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 3e5546c94ea..b4759f70e27 100644 --- a/lang/c++/include/avro/NodeImpl.hh +++ b/lang/c++/include/avro/NodeImpl.hh @@ -234,7 +234,7 @@ using NodeImplSymbolic = NodeImpl; using NodeImplEnum = NodeImpl; -using NodeImplArray = NodeImpl; +using NodeImplArray = NodeImpl; using NodeImplMap = NodeImpl; using NodeImplUnion = NodeImpl; using NodeImplFixed = NodeImpl; @@ -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 6f9c93d6d56..477e36046eb 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() {