From bdcda0f235736af5ce4b8a8632f8257e0bc261a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20M=C3=A4kel=C3=A4?= Date: Wed, 13 Dec 2017 11:25:47 +0200 Subject: [PATCH] Fix empty TIME2 values The values for TIME2 were always empty as they weren't processed. --- server/core/mysql_binlog.c | 30 ++++++++++++++++++++ server/modules/routing/avrorouter/avro_rbr.c | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/server/core/mysql_binlog.c b/server/core/mysql_binlog.c index 951e6eace..ae9b6b844 100644 --- a/server/core/mysql_binlog.c +++ b/server/core/mysql_binlog.c @@ -402,6 +402,32 @@ static void unpack_time(uint8_t *ptr, struct tm *dest) dest->tm_sec = second; } +/** + * @brief Unpack a TIME2 + * + * The TIME2 is stored as a 3 byte value containing the integer parts plus + * the additional fractional parts as a trailing value. The + * integer parts of the time are extracted with the following algorithm: + * + * hours = (value >> 12) % (1 << 10) + * minutes = (value >> 6) % (1 << 6) + * seconds = value % (1 << 6) + * + * As the `struct tm` doesn't support fractional seconds, the fractional part + * is ignored. + * + * @param val Value read from the binary log + * @param dest Pointer where the unpacked value is stored + */ +static void unpack_time2(uint8_t *ptr, uint8_t decimals, struct tm *dest) +{ + uint64_t val = unpack3(ptr) - DATETIME2_OFFSET; + memset(dest, 0, sizeof(struct tm)); + dest->tm_hour = (val >> 12) % (1 << 10); + dest->tm_min = (val >> 6) % (1 << 6); + dest->tm_sec = val % (1 << 6); +} + /** * @brief Unpack a DATE value * @param ptr Pointer to packed value @@ -524,6 +550,10 @@ size_t unpack_temporal_value(uint8_t type, uint8_t *ptr, uint8_t *metadata, int unpack_time(ptr, tm); break; + case TABLE_COL_TYPE_TIME2: + unpack_time2(ptr, *metadata, tm); + break; + case TABLE_COL_TYPE_DATE: unpack_date(ptr, tm); break; diff --git a/server/modules/routing/avrorouter/avro_rbr.c b/server/modules/routing/avrorouter/avro_rbr.c index 61aef24a0..a4e8f0c97 100644 --- a/server/modules/routing/avrorouter/avro_rbr.c +++ b/server/modules/routing/avrorouter/avro_rbr.c @@ -655,7 +655,7 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value create->column_lengths[i], &tm); format_temporal_value(buf, sizeof(buf), map->column_types[i], &tm); avro_value_set_string(&field, buf); - MXS_INFO("[%ld] TEMPORAL: %s", i, buf); + MXS_INFO("[%ld] %s: %s", i, column_type_to_string(map->column_types[i]), buf); ss_dassert(ptr < end); } /** All numeric types (INT, LONG, FLOAT etc.) */