问题
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