Uploaded image for project: 'Apache Avro'
  1. Apache Avro
  2. AVRO-825

C++ code generation issues with records when member of the record is of type itself

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 1.5.1
    • 1.5.2
    • c++
    • None

    Description

      I am trying to generate C++ code for the following schema using new avrogencpp. This schema is one the of the example given in Avro specification

      {
      "type": "record",
      "name": "LongList",
      "aliases": ["LinkedLongs"], // old name for this
      "fields" : [

      {"name": "value", "type": "long"}

      , // each element has a long

      {"name": "next", "type": ["LongList", "null"]}

      // optional next element
      ]
      }

      It generated the following .hh file and when I tried to compile I am getting

      #ifndef _TEST_LINKEDLIST_HH_1817083040H
      #define _TEST_LINKEDLIST_HH_1817083040H

      #include "boost/any.hpp"
      #include "Specific.hh"
      #include "Encoder.hh"
      #include "Decoder.hh"
      struct imaginary_avr_Union0_ {
      private:
      size_t idx_;
      boost::any value_;
      public:
      size_t idx() const

      { return idx_; }

      LongList get_LongList() const {
      if (idx_ != 0)

      { throw avro::Exception("Invalid type for union"); }

      return boost::any_cast<LongList >(value_);
      }
      void set_LongList(const LongList& v)

      { idx_ = 0; value_ = v; }

      void set_null()

      { idx_ = 1; value_ = boost::any(); }

      imaginary_avr_Union0() : idx(0)

      { value_ = LongList(); }

      };

      struct LongList {
      int64_t value;
      imaginary_avr_Union0_ next;
      };

      namespace avro {
      template<> struct codec_traits<imaginary_avr_Union0_> {
      static void encode(Encoder& e, imaginary_avr_Union0_ v) {
      e.encodeUnionIndex(v.idx());
      switch (v.idx())

      { case 0: avro::encode(e, v.get_LongList()); break; case 1: e.encodeNull(); break; }

      }
      static void decode(Decoder& d, imaginary_avr_Union0_& v) {
      size_t n = d.decodeUnionIndex();
      if (n >= 2)

      { throw avro::Exception("Union index too big"); }

      switch {
      case 0:

      { LongList vv; avro::decode(d, vv); v.set_LongList(vv); }

      break;
      case 1:
      d.decodeNull();
      v.set_null();
      break;
      }
      }
      };

      template<> struct codec_traits<LongList> {
      static void encode(Encoder& e, const LongList& v)

      { avro::encode(e, v.value); avro::encode(e, v.next); }

      static void decode(Decoder& d, LongList& v)

      { avro::decode(d, v.value); avro::decode(d, v.next); }

      };

      }
      #endif

      When I tried to compile I am getting following errors due to incomplete type.

      Errors

      In file included from /home/rsuvarap/avro-src-1.5.1/lang/c++/test/AvrogencppTests.cc:24:
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:34: error: `LongList' does not name a type
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:40: error: expected `,' or `...' before '&' token
      /home/rsuvarap/avro-src-1.5.1/lang/c+/test/linkedlist.hh:40: error: ISO C+ forbids declaration of `LongList' with no type
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh: In member function `void imaginary_avr_Union0_::set_LongList(int)':
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:42: error: `v' was not declared in this scope
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh: In constructor `imaginary_avr_Union0::_imaginary_avr_Union0_()':
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:49: error: `LongList' was not declared in this scope
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh: In static member function `static void avro::codec_traits<imaginary_avr_Union0>::encode(avro::Encoder&, _imaginary_avr_Union0_)':
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:64: error: 'struct imaginary_avr_Union0_' has no member named 'get_LongList'
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh: In static member function `static void avro::codec_traits<imaginary_avr_Union0>::decode(avro::Decoder&, _imaginary_avr_Union0_&)':
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:79: error: no matching function for call to `imaginary_avr_Union0_::set_LongList(LongList&)'
      /home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:40: note: candidates are: void imaginary_avr_Union0_::set_LongList(int)
      make[2]: *** [CMakeFiles/AvrogencppTests.dir/test/AvrogencppTests.cc.o] Error 1
      make[1]: *** [CMakeFiles/AvrogencppTests.dir/all] Error 2
      make: *** [all] Error 2

      I think the issue is get_LongList of the union should return pointer to LongList instead of value. It's a same issue with c++ generation using python script.

      We use lot of similar schemas in our project and we use cross language messaging between Java and C++ applications and these errors are affecting C++ applications.
      Please let us know when this issue is going to be fixed?

      Thanks,
      Ramana

      Attachments

        1. AVRO-825.patch
          9 kB
          Thiruvalluvan M. G.
        2. AVRO-825-v2.patch
          11 kB
          Thiruvalluvan M. G.
        3. AVRO-825-v5.patch
          14 kB
          Thiruvalluvan M. G.

        Activity

          People

            thiru_mg Thiruvalluvan M. G.
            ramanasv Ramana Suvarapu
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: