Merge branch '2.1' into 2.2

This commit is contained in:
Markus Mäkelä
2017-12-21 12:25:26 +02:00
6 changed files with 71 additions and 21 deletions

View File

@ -55,7 +55,7 @@ if [ $z_res -eq 127 ] && [ $y_res -eq 127 ] ; then
exit 1 exit 1
fi fi
gpg -abs -o dists/$dist_name/Release.gpg dists/$dist_name/Release gpg -abs --digest-algo sha256 -o dists/$dist_name/Release.gpg dists/$dist_name/Release
if [ $? != 0 ] ; then if [ $? != 0 ] ; then
echo "Package signing failed!" echo "Package signing failed!"
exit 1 exit 1
@ -70,8 +70,7 @@ else
sudo zypper -n install createrepo sudo zypper -n install createrepo
fi fi
echo "%_signature gpg" >> ~/.rpmmacros echo "%_signature gpg" >> ~/.rpmmacros
echo "%_gpg_name MariaDB Maxscale" >> ~/.rpmmacros echo "%_gpg_name MariaDB Maxscale <maxscale@googlegroups.com>" >> ~/.rpmmacros
# echo "%_gpg_name MariaDBManager" >> ~/.rpmmacros
echo "\r" | setsid rpm --resign $sourcedir/*.rpm echo "\r" | setsid rpm --resign $sourcedir/*.rpm
if [ $? != 0 ] ; then if [ $? != 0 ] ; then

View File

@ -17,7 +17,7 @@ ssh $sshopt "sudo rm -rf $work_dir"
echo "copying stuff to $image machine" echo "copying stuff to $image machine"
ssh $sshopt "mkdir -p $work_dir" ssh $sshopt "mkdir -p $work_dir"
rsync -avz --progress --delete -e "ssh $scpopt" ${script_dir}/../../* $sshuser@$IP:./$work_dir/ rsync -avz --delete -e "ssh $scpopt" ${script_dir}/../../ $sshuser@$IP:./$work_dir/
if [ $? -ne 0 ] ; then if [ $? -ne 0 ] ; then
echo "Error copying stuff to $box machine" echo "Error copying stuff to $box machine"
exit 2 exit 2

View File

@ -130,10 +130,11 @@ can be influenced with the server priority mechanic described in the
### Avrorouter limitations (avrorouter) ### Avrorouter limitations (avrorouter)
The avrorouter does not support the following data types and conversions: The avrorouter does not support the following data types, conversions or SQL statements:
* BIT * BIT
* Fields CAST from integer types to string types * Fields CAST from integer types to string types
* [CREATE TABLE ... AS SELECT statements](https://mariadb.com/kb/en/library/create-table/#create-select)
The avrorouter does not do any crash recovery. This means that the avro files The avrorouter does not do any crash recovery. This means that the avro files
need to be truncated to valid block lengths before starting the avrorouter. need to be truncated to valid block lengths before starting the avrorouter.

View File

@ -402,6 +402,32 @@ static void unpack_time(uint8_t *ptr, struct tm *dest)
dest->tm_sec = second; 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 * @brief Unpack a DATE value
* @param ptr Pointer to packed 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); unpack_time(ptr, tm);
break; break;
case TABLE_COL_TYPE_TIME2:
unpack_time2(ptr, *metadata, tm);
break;
case TABLE_COL_TYPE_DATE: case TABLE_COL_TYPE_DATE:
unpack_date(ptr, tm); unpack_date(ptr, tm);
break; break;

View File

@ -909,6 +909,27 @@ bool is_create_like_statement(const char* ptr, size_t len)
return strcasestr(sql, " like ") || strcasestr(sql, "(like "); return strcasestr(sql, " like ") || strcasestr(sql, "(like ");
} }
bool is_create_as_statement(const char* ptr, size_t len)
{
int err = 0;
char sql[len + 1];
memcpy(sql, ptr, len);
sql[len] = '\0';
const char* pattern =
// Case-insensitive mode
"(?i)"
// Main CREATE TABLE part (the \s is for any whitespace)
"create\\stable\\s"
// Optional IF NOT EXISTS
"(if\\snot\\sexists\\s)?"
// The table name with optional database name, both enclosed in optional backticks
"(`?\\S+`?.)`?\\S+`?\\s"
// And finally the AS keyword
"as";
return mxs_pcre2_simple_match(pattern, sql, 0, &err) == MXS_PCRE2_MATCH;
}
/** /**
* @brief Detection of table alteration statements * @brief Detection of table alteration statements
* @param router Avro router instance * @param router Avro router instance
@ -1025,6 +1046,15 @@ void handle_query_event(AVRO_INSTANCE *router, REP_HEADER *hdr, int *pending_tra
{ {
created = table_create_copy(router, sql, len, db); created = table_create_copy(router, sql, len, db);
} }
else if (is_create_as_statement(sql, len))
{
static bool warn_create_as = true;
if (warn_create_as)
{
MXS_WARNING("`CREATE TABLE AS` is not yet supported, ignoring events to this table: %.*s", len, sql);
warn_create_as = false;
}
}
else else
{ {
created = table_create_alloc(sql, len, db); created = table_create_alloc(sql, len, db);

View File

@ -544,16 +544,8 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value
{ {
uint8_t val[metadata[metadata_offset + 1]]; uint8_t val[metadata[metadata_offset + 1]];
uint64_t bytes = unpack_enum(ptr, &metadata[metadata_offset], val); uint64_t bytes = unpack_enum(ptr, &metadata[metadata_offset], val);
char strval[32]; char strval[bytes * 2 + 1];
gw_bin2hex(strval, val, bytes);
/** Right now only ENUMs/SETs with less than 256 values
* are printed correctly */
snprintf(strval, sizeof(strval), "%hhu", val[0]);
if (bytes > 1 && warn_large_enumset)
{
warn_large_enumset = true;
MXS_WARNING("ENUM/SET values larger than 255 values aren't supported.");
}
avro_value_set_string(&field, strval); avro_value_set_string(&field, strval);
MXS_INFO("[%ld] ENUM: %lu bytes", i, bytes); MXS_INFO("[%ld] ENUM: %lu bytes", i, bytes);
ptr += bytes; ptr += bytes;
@ -599,11 +591,9 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value
else if (column_is_bit(map->column_types[i])) else if (column_is_bit(map->column_types[i]))
{ {
uint64_t value = 0; uint64_t value = 0;
int width = metadata[metadata_offset] + metadata[metadata_offset + 1] * 8; uint8_t len = metadata[metadata_offset + 1];
int bits_in_nullmap = MXS_MIN(width, extra_bits); uint8_t bit_len = metadata[metadata_offset] > 0 ? 1 : 0;
extra_bits -= bits_in_nullmap; size_t bytes = len + bit_len;
width -= bits_in_nullmap;
size_t bytes = width / 8;
// TODO: extract the bytes // TODO: extract the bytes
if (!warn_bit) if (!warn_bit)
@ -675,7 +665,7 @@ uint8_t* process_row_event_data(TABLE_MAP *map, TABLE_CREATE *create, avro_value
create->column_lengths[i], &tm); create->column_lengths[i], &tm);
format_temporal_value(buf, sizeof(buf), map->column_types[i], &tm); format_temporal_value(buf, sizeof(buf), map->column_types[i], &tm);
avro_value_set_string(&field, buf); 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); ss_dassert(ptr < end);
} }
/** All numeric types (INT, LONG, FLOAT etc.) */ /** All numeric types (INT, LONG, FLOAT etc.) */