You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avro.apache.org by "Hua Zhang (JIRA)" <ji...@apache.org> on 2016/08/16 22:02:23 UTC

[jira] [Updated] (AVRO-1898) C++ library cannot parse unions with default values

     [ https://issues.apache.org/jira/browse/AVRO-1898?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Hua Zhang updated AVRO-1898:
----------------------------
    Description: 
I have a Avro file generated by the Java library, and when I tried to read it using the C++ library, I got:

Unexpected type for default value: Expected 6, but found 1

Which basically says the default value should be of type Object, but got type Boolean. After some investigation, I found the exception is thrown when parsing the default value of a union. Looks like the C++ library requires the default value of a union to be an object. This is different from what the Avro specification says, that the default value of a union should be of the first type in the union.

This field is causing the problem:
{
        "name" : "fake_name",
        "type" : [ "boolean", "null" ],
        "default" : false
}
From the code the C++ library is expecting:
{
        "name" : "is_track_mau30",
        "type" : [ "boolean", "null" ],
        "default" : {"boolean": false}
}

The related code is in impl/Compiler.cc, line 284. If I change it to the following, the Avro file can be parsed:

{code}
        GenericUnion result(n);
        result.selectBranch(0);
        result.datum() = makeGenericDatum(n->leafAt(0), e, st);
        return GenericDatum(n, result);
{code}
Why is the C++ library behaves different than the specification? Can/should it be changed to follow the specification? It will be a breaking change though.

Thanks and I'll be happy to contribute this change if it's deemed appropriate.

  was:
I have a Avro file generated by the Java library, and when I tried to read it using the C++ library, I got:

Unexpected type for default value: Expected 6, but found 1

Which basically says the default value should be of type Object, but got type Boolean. After some investigation, I found the exception is thrown when parsing the default value of a union. Looks like the C++ library requires the default value of a union to be an object. This is different from what the Avro specification says, that the default value of a union should be of the first type in the union.

This field is causing the problem:
{
        "name" : "fake_name",
        "type" : [ "boolean", "null" ],
        "default" : false
}
From the code the C++ library is expecting:
{
        "name" : "is_track_mau30",
        "type" : [ "boolean", "null" ],
        "default" : {"boolean": false}
}

The related code is in impl/Compiler.cc, line 284. If I change it to the following, the Avro file can be parsed:

        GenericUnion result(n);
        result.selectBranch(0);
        result.datum() = makeGenericDatum(n->leafAt(0), e, st);
        return GenericDatum(n, result);

Why is the C++ library behaves different than the specification? Can/should it be changed to follow the specification? It will be a breaking change though.

Thanks and I'll be happy to contribute this change if it's deemed appropriate.


> C++ library cannot parse unions with default values
> ---------------------------------------------------
>
>                 Key: AVRO-1898
>                 URL: https://issues.apache.org/jira/browse/AVRO-1898
>             Project: Avro
>          Issue Type: Bug
>          Components: c++
>    Affects Versions: 1.8.1
>            Reporter: Hua Zhang
>
> I have a Avro file generated by the Java library, and when I tried to read it using the C++ library, I got:
> Unexpected type for default value: Expected 6, but found 1
> Which basically says the default value should be of type Object, but got type Boolean. After some investigation, I found the exception is thrown when parsing the default value of a union. Looks like the C++ library requires the default value of a union to be an object. This is different from what the Avro specification says, that the default value of a union should be of the first type in the union.
> This field is causing the problem:
> {
>         "name" : "fake_name",
>         "type" : [ "boolean", "null" ],
>         "default" : false
> }
> From the code the C++ library is expecting:
> {
>         "name" : "is_track_mau30",
>         "type" : [ "boolean", "null" ],
>         "default" : {"boolean": false}
> }
> The related code is in impl/Compiler.cc, line 284. If I change it to the following, the Avro file can be parsed:
> {code}
>         GenericUnion result(n);
>         result.selectBranch(0);
>         result.datum() = makeGenericDatum(n->leafAt(0), e, st);
>         return GenericDatum(n, result);
> {code}
> Why is the C++ library behaves different than the specification? Can/should it be changed to follow the specification? It will be a breaking change though.
> Thanks and I'll be happy to contribute this change if it's deemed appropriate.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)