Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-23 12:26:20+01:00, mats@stripped +3 -0
BUG#32580 (mysqlbinlog cannot read binlog event generated by user variable usage):
The client program 'mysqlbinlog' crashed when trying to print a User_var_log_event holding
a floating-point value since the format specifier for my_b_printf() does not support
floating-point format specifiers.
This patch prints the floating-point number to an internal buffer, and then writes
that buffer to the output instead.
mysql-test/r/mysqlbinlog.result@stripped, 2007-11-23 12:26:10+01:00, mats@stripped +25 -0
Result file change.
mysql-test/t/mysqlbinlog.test@stripped, 2007-11-23 12:26:10+01:00, mats@stripped +27 -0
Adding test that mysqlbinlog can write and read back User_var_log_event
for real, decimal, integer, and string. These are the only types supported
for user variables.
sql/log_event.cc@stripped, 2007-11-23 12:26:11+01:00, mats@stripped +13 -1
Using my_sprintf() to print floating-point value of User_var_log_event value to a
character buffer and then to the real output, since my_b_printf() does not
support floating-point format. Also adding macro to give buffer size needed
for printing floating-point numbers in %g format.
diff -Nrup a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
--- a/mysql-test/r/mysqlbinlog.result 2007-11-12 11:29:48 +01:00
+++ b/mysql-test/r/mysqlbinlog.result 2007-11-23 12:26:10 +01:00
@@ -351,4 +351,29 @@ a b
1 root@localhost
DROP DATABASE mysqltest1;
DROP USER untrusted@localhost;
+BUG#32580: mysqlbinlog cannot read binlog event with user variables
+USE test;
+SET BINLOG_FORMAT = STATEMENT;
+FLUSH LOGS;
+CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32));
+SET @a_real = rand(20) * 1000;
+SET @an_int = 1000;
+SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2));
+SET @a_string = 'Just a test';
+INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string);
+FLUSH LOGS;
+SELECT * FROM t1;
+a_real 158.883
+an_int 1000
+a_decimal 907.79
+a_string Just a test
+DROP TABLE t1;
+>> mysqlbinlog var/log/master-bin.000019 > var/tmp/bug32580.sql
+>> mysql test < var/tmp/bug32580.sql
+SELECT * FROM t1;
+a_real 158.883
+an_int 1000
+a_decimal 907.79
+a_string Just a test
+DROP TABLE t1;
End of 5.1 tests
diff -Nrup a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
--- a/mysql-test/t/mysqlbinlog.test 2007-11-12 11:29:48 +01:00
+++ b/mysql-test/t/mysqlbinlog.test 2007-11-23 12:26:10 +01:00
@@ -278,4 +278,31 @@ connection default;
DROP DATABASE mysqltest1;
DROP USER untrusted@localhost;
+--echo BUG#32580: mysqlbinlog cannot read binlog event with user variables
+
+# Testing that various kinds of events can be read and restored properly.
+
+connection default;
+USE test;
+SET BINLOG_FORMAT = STATEMENT;
+FLUSH LOGS;
+CREATE TABLE t1 (a_real FLOAT, an_int INT, a_decimal DECIMAL(5,2), a_string CHAR(32));
+SET @a_real = rand(20) * 1000;
+SET @an_int = 1000;
+SET @a_decimal = CAST(rand(19) * 999 AS DECIMAL(5,2));
+SET @a_string = 'Just a test';
+INSERT INTO t1 VALUES (@a_real, @an_int, @a_decimal, @a_string);
+FLUSH LOGS;
+query_vertical SELECT * FROM t1;
+DROP TABLE t1;
+
+echo >> mysqlbinlog var/log/master-bin.000019 > var/tmp/bug32580.sql;
+exec $MYSQL_BINLOG $MYSQLTEST_VARDIR/log/master-bin.000019 > $MYSQLTEST_VARDIR/tmp/bug32580.sql;
+echo >> mysql test < var/tmp/bug32580.sql;
+exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug32580.sql;
+remove_file $MYSQLTEST_VARDIR/tmp/bug32580.sql;
+
+query_vertical SELECT * FROM t1;
+DROP TABLE t1;
+
--echo End of 5.1 tests
diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc 2007-11-14 11:01:43 +01:00
+++ b/sql/log_event.cc 2007-11-23 12:26:11 +01:00
@@ -36,6 +36,16 @@
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
+
+/*
+ Size of buffer for printing a double in format %.<MANT>g
+
+ optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
+ exponent digits + '\0'
+*/
+#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
+
+
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) && !defined(DBUG_OFF) && !defined(_lint)
static const char *HA_ERR(int i)
{
@@ -4404,8 +4414,10 @@ void User_var_log_event::print(FILE* fil
switch (type) {
case REAL_RESULT:
double real_val;
+ char real_buf[FMT_G_BUFSIZE(14)];
float8get(real_val, val);
- my_b_printf(&cache, ":=%.14g%s\n", real_val, print_event_info->delimiter);
+ my_sprintf(real_buf, (real_buf, "%.14g", real_val));
+ my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
break;
case INT_RESULT:
char int_buf[22];