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

thiru 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 cffffe7e1 Fix for wrong behavior of Json codec when record schema has 
no fields (#2833)
cffffe7e1 is described below

commit cffffe7e1fa22bf37a508e443c807e4b12b53d40
Author: Thiruvalluvan M G <[email protected]>
AuthorDate: Sat Apr 6 08:37:29 2024 +0530

    Fix for wrong behavior of Json codec when record schema has no fields 
(#2833)
    
    Co-authored-by: Thiruvalluvan M G <[email protected]>
---
 lang/c++/impl/parsing/JsonCodec.cc |  1 +
 lang/c++/impl/parsing/Symbol.hh    | 14 ++++++++++++++
 lang/c++/test/CodecTests.cc        | 15 +++++++++++++++
 3 files changed, 30 insertions(+)

diff --git a/lang/c++/impl/parsing/JsonCodec.cc 
b/lang/c++/impl/parsing/JsonCodec.cc
index 4fd048160..a33fd39fd 100644
--- a/lang/c++/impl/parsing/JsonCodec.cc
+++ b/lang/c++/impl/parsing/JsonCodec.cc
@@ -496,6 +496,7 @@ public:
 template<typename P, typename F>
 void JsonEncoder<P, F>::init(OutputStream &os) {
     out_.init(os);
+    parser_.reset();
 }
 
 template<typename P, typename F>
diff --git a/lang/c++/impl/parsing/Symbol.hh b/lang/c++/impl/parsing/Symbol.hh
index 21e46a85a..c8760c34d 100644
--- a/lang/c++/impl/parsing/Symbol.hh
+++ b/lang/c++/impl/parsing/Symbol.hh
@@ -363,6 +363,10 @@ template<typename Handler>
 class SimpleParser {
     Decoder *decoder_;
     Handler &handler_;
+    /*
+     * parsingStack always has root at the bottom of it.
+     * So it is safe to call top() on it.
+     */
     std::stack<Symbol> parsingStack;
 
     static void throwMismatch(Symbol::Kind actual, Symbol::Kind expected) {
@@ -742,6 +746,14 @@ public:
             } else if (s.kind() == Symbol::Kind::SkipStart) {
                 parsingStack.pop();
                 skip(*decoder_);
+            } else if (s.kind() == Symbol::Kind::Indirect) {
+                ProductionPtr pp = s.extra<ProductionPtr>();
+                parsingStack.pop();
+                append(pp);
+            } else if (s.kind() == Symbol::Kind::Symbolic) {
+                ProductionPtr pp(s.extra<std::weak_ptr<Production>>());
+                parsingStack.pop();
+                append(pp);
             } else {
                 break;
             }
@@ -756,6 +768,8 @@ public:
         while (parsingStack.size() > 1) {
             parsingStack.pop();
         }
+        Symbol &s = parsingStack.top();
+        append(boost::tuples::get<0>(*s.extrap<RootInfo>()));
     }
 };
 
diff --git a/lang/c++/test/CodecTests.cc b/lang/c++/test/CodecTests.cc
index f24af3a97..9c281c52c 100644
--- a/lang/c++/test/CodecTests.cc
+++ b/lang/c++/test/CodecTests.cc
@@ -963,6 +963,11 @@ static const TestData data[] = {
     {R"({"type":"map", "values": "boolean"})",
      "{c1sK5Bc2sK5BsK5B}", 2},
 
+    // Record with no fields
+    {"{\"type\":\"record\",\"name\":\"empty\",\"fields\":[]}",
+     "", 1},
+
+    // Single-field records
     {"{\"type\":\"record\",\"name\":\"r\",\"fields\":["
      "{\"name\":\"f\", \"type\":\"boolean\"}]}",
      "B", 1},
@@ -1002,6 +1007,16 @@ static const TestData data[] = {
      "{\"name\":\"f7\", \"type\":\"bytes\"}]}",
      "NBILFDS10b25", 1},
     // record of records
+    {"{\"type\":\"record\",\"name\":\"r\",\"fields\":["
+     "{\"name\":\"f1\",\"type\":\"boolean\"},"
+     "{\"name\":\"f2\", \"type\":{\"type\":\"record\","
+     "\"name\":\"inner\",\"fields\":[]}}]}",
+     "B", 1},
+    {"{\"type\":\"record\",\"name\":\"r\",\"fields\":["
+     "{\"name\":\"f1\",\"type\":\"boolean\"},"
+     "{\"name\":\"f2\", \"type\":{\"type\":\"array\","
+     "\"items\":\"r\"}}]}",
+     "B[]", 1},
     {"{\"type\":\"record\",\"name\":\"outer\",\"fields\":["
      "{\"name\":\"f1\", \"type\":{\"type\":\"record\", "
      "\"name\":\"inner\", \"fields\":["

Reply via email to