MXS-2106: Fix NULL value handling

The NULL values were not stored as NULL Avro values due to the fact that
the file format has no native NULL-ness for the basic types. To solve
this, all values must be stored as a union that contains the actual type
as well as the null type.

Unions were not implemented in the maxavro library but implementing means
simply recursing one level down.
This commit is contained in:
Markus Mäkelä
2018-10-31 21:50:30 +02:00
parent 7f36ec83da
commit 562c7be8fe
6 changed files with 43 additions and 21 deletions

View File

@ -561,7 +561,7 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value
uint8_t *ptr, uint8_t *columns_present, uint8_t *end)
{
int npresent = 0;
avro_value_t field;
avro_value_t union_value;
long ncolumns = map->columns;
uint8_t *metadata = map->column_metadata;
size_t metadata_offset = 0;
@ -580,24 +580,20 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value
for (long i = 0; i < ncolumns && npresent < ncolumns; i++)
{
ss_debug(int rc = )avro_value_get_by_name(record, create->column_names[i], &field, NULL);
ss_debug(int rc = )avro_value_get_by_name(record, create->column_names[i], &union_value, NULL);
ss_dassert(rc == 0);
if (bit_is_set(columns_present, ncolumns, i))
{
avro_value_t field;
avro_value_set_branch(&union_value, 1, &field);
npresent++;
if (bit_is_set(null_bitmap, ncolumns, i))
{
sprintf(trace[i], "[%ld] NULL", i);
if (column_is_blob(map->column_types[i]))
{
uint8_t nullvalue = 0;
avro_value_set_bytes(&field, &nullvalue, 1);
}
else
{
avro_value_set_null(&field);
}
avro_value_set_branch(&union_value, 0, &field);
avro_value_set_null(&field);
}
else if (column_is_fixed_string(map->column_types[i]))
{

View File

@ -130,9 +130,9 @@ char* json_new_schema_from_table(TABLE_MAP *map)
ss_info_dassert(create->column_types[i] && *create->column_types[i],
"Column type should not be empty or NULL");
json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:s, s:s, s:i}",
json_array_append_new(array, json_pack_ex(&err, 0, "{s:s, s:[s, s], s:s, s:i}",
"name", create->column_names[i],
"type", column_type_to_avro_type(map->column_types[i]),
"type", "null", column_type_to_avro_type(map->column_types[i]),
"real_type", create->column_types[i],
"length", create->column_lengths[i]));
}