C++ code generation issues with records when member of the record is of type
itself
-----------------------------------------------------------------------------------
Key: AVRO-825
URL: https://issues.apache.org/jira/browse/AVRO-825
Project: Avro
Issue Type: Bug
Components: c++
Affects Versions: 1.5.1
Reporter: Ramana Suvarapu
Priority: Blocker
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_1817083040__H_
#define __TEST_LINKEDLIST_HH_1817083040__H_
#include "boost/any.hpp"
#include "Specific.hh"
#include "Encoder.hh"
#include "Decoder.hh"
struct _imaginary_avr_Union__0__ {
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_Union__0__() : idx_(0) {
value_ = LongList();
}
};
struct LongList {
int64_t value;
_imaginary_avr_Union__0__ next;
};
namespace avro {
template<> struct codec_traits<_imaginary_avr_Union__0__> {
static void encode(Encoder& e, _imaginary_avr_Union__0__ 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_Union__0__& v) {
size_t n = d.decodeUnionIndex();
if (n >= 2) { throw avro::Exception("Union index too big"); }
switch (n) {
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_Union__0__::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_Union__0__::_imaginary_avr_Union__0__()':
/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_Union__0__>::encode(avro::Encoder&,
_imaginary_avr_Union__0__)':
/home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:64: error: 'struct
_imaginary_avr_Union__0__' 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_Union__0__>::decode(avro::Decoder&,
_imaginary_avr_Union__0__&)':
/home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:79: error: no
matching function for call to
`_imaginary_avr_Union__0__::set_LongList(LongList&)'
/home/rsuvarap/avro-src-1.5.1/lang/c++/test/linkedlist.hh:40: note: candidates
are: void _imaginary_avr_Union__0__::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
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira