Write nullable item to avro record in Avro C

江枫思渺然 提交于 2021-01-28 22:52:43

问题


Schema:

const char schema[] = 
    "{ \"type\":\"record\", \"name\":\"foo\","
    "\"fields\": ["
        "{ \"name\": \"nullableint\", \"type\":[\"int\",\"null\"]}"
    "]}";

Setting the schema:

avro_datum_t foo_record = avro_record(schema);

Setting the nullable datum up:

avro_datum_t nullableint = avro_int32(1);

Set the item:

int err = avro_record_set(foo_record,"nullableint",nullableint);

Write the item:

int err2 = avro_file_writer_append(avro_writer, foo_record);

And there is an error. Somehow, I must set the branch of my nullable entry, yet I see no functions that will do this.

How do I set this value to either null or an int?


回答1:


See the following code which sets the union branch and the int branch:

Note: For union, you need to set the relevant branch before you set the data. The union branch index starts from 0 and is called discriminant. For the int field at this example the discriminant is 0 (as it is the first field). For the null branch the discriminant is 1 (as it is the second field). It is more common having the null as the first branch, however, I followed your question example.

#include "avro.h"
void main()
{
    const char schema_json[] =
        "{ \"type\":\"record\", \"name\":\"foo\","
        "\"fields\": ["
        "{ \"name\": \"nullableint\", \"type\":[\"int\",\"null\"]}"
        "]}";
    avro_schema_t my_schema;
    avro_schema_from_json( schema_json, 0, &my_schema, NULL );
    avro_datum_t  my_record = avro_datum_from_schema( my_schema );
    avro_datum_t  my_int_field = NULL;
    avro_datum_t  branch = NULL;
    char  *json = NULL;

    //get the int field
    avro_record_get( my_record, "nullableint", &my_int_field );

    //set the int branch on this field
    avro_union_set_discriminant( my_int_field, 0, &branch );
    //set value of 100 at this int branch
    avro_int32_set( branch, 100 );
    //convert the datum record data to json
    avro_datum_to_json( my_record, 1, &json );
    printf( "got json for int branch: %s\n", json );

    //get the int field
    avro_record_get( my_record, "nullableint", &my_int_field );
    //set the null branch on this field
    avro_union_set_discriminant( my_int_field, 1, &branch );
    //convert the datum record data to json
    avro_datum_to_json( my_record, 1, &json );
    printf( "got json for null branch: %s\n", json );

}

I printed the data as json for better examination of the results. output of this program is

got json for int branch: {"nullableint": {"int": 100}}
got json for null branch: {"nullableint": null}

BTW, the convention is to have the null branch as the first branch, having

"{ \"name\": \"nullableint\", \"type\":[\"null\",\"int\"]}"

and not

"{ \"name\": \"nullableint\", \"type\":[\"int\",\"null\"]}"

see this cite from avro specification: https://avro.apache.org/docs/1.8.2/spec.html

(Note that when a default value is specified for a record field whose type is a union, the type of the default value must match the first element of the union. Thus, for unions containing "null", the "null" is usually listed first, since the default value of such unions is typically null.)



来源:https://stackoverflow.com/questions/52188432/write-nullable-item-to-avro-record-in-avro-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!