You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@avro.apache.org by Shafquat Rahman <Sh...@mathworks.com> on 2014/05/21 20:20:22 UTC

C++ JsonDecoder expects json object to be ordered

This is my first time posting to this group. I have been experimenting with avro in C++ (version 1.7.5) and ran into an issue with the json decoder which expects ordered json objects. The problem I am seeing appears similar to this post I found for an older avro java library:

http://search-hadoop.com/m/7WG37aVaBd/v=plain

I have a simple record:

{
    "name" : "SimpleRecord",
    "type" : "record",
    "fields" :[
        { "name" : "A", "type" : "int"},
        { "name" : "B", "type" : "int"}
    ]
}

I generate the C++ header using avrogencpp. The generated  code has codec_traits specialization for SimpleRecord that fixes the order for the JsonEncoder and JsonDecoder.

...snip...
namespace avro {
template<> struct codec_traits<SimpleRecord> {
    static void encode(Encoder& e, const SimpleRecord& v) {
        avro::encode(e, v.A);
        avro::encode(e, v.B);
    }
    static void decode(Decoder& d, SimpleRecord& v) {
        avro::decode(d, v.A);
        avro::decode(d, v.B);
    }
};
...snip...

The JsonDecoder successfully decodes json objects of the form{"A" : 1, "B" : 2} into SimpleRecord. But if I try to decode {"B" : 2, "A" : 1} it throws 'avro::Exception' with "Incorrect field" from impl/parsing/JsonCodec.cc:182 in the following method:

JsonDecoderHandler(JsonParser& p) : in_(p) { }
    size_t handle(const Symbol& s) {
        switch (s.kind()) {
        case Symbol::sRecordStart:
            expectToken(in_, JsonParser::tkObjectStart);
            break;
        case Symbol::sRecordEnd:
            expectToken(in_, JsonParser::tkObjectEnd);
            break;
        case Symbol::sField:
            expectToken(in_, JsonParser::tkString);
            if (s.extra<string>() != in_.stringValue()) {
                throw Exception("Incorrect field");
            }
            break;
        default:
            break;
        }
        return 0;
    }

The stack shows that avro::decode(d, v.A) is  the call the eventually causes the exception.

According to the json spec the fields in a json object are unordered. Is this a bug?

I would appreciate some advice on how to handle this use case.

Thanks,
Shaf