mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
BUG#49562: SBR out of sync when using numeric data types + user
variable The User_var_log_event was not serializing the unsigned flag. This would cause the slave to always assume signed values. We fix this by extending the User_var_log_event to also contain information on the unsigned_flag, meaning that it gets into the binlog as well, therefore the slave will get this information as well. Events without information on unsigned flag (old events) are treated as they were before (always signed: unsigned_flag= FALSE). The information on the unsigned_flag, is shipped in an extra byte appended to the end of the User_var_log_event and added by this patch. This extra byte holds values for general purpose User_var_log_event flags which are now packed in the binlog as well. One of these flags contains information about whether the value is signed or unsigned (currently this extra byte is only used to hold data on the unsigned flag, in the future we can use it to pack extra flags if there is the need to).
This commit is contained in:
@ -118,7 +118,7 @@ Master_User root
|
|||||||
Master_Port MASTER_PORT
|
Master_Port MASTER_PORT
|
||||||
Connect_Retry 1
|
Connect_Retry 1
|
||||||
Master_Log_File master-bin.000001
|
Master_Log_File master-bin.000001
|
||||||
Read_Master_Log_Pos 386
|
Read_Master_Log_Pos 387
|
||||||
Relay_Log_File #
|
Relay_Log_File #
|
||||||
Relay_Log_Pos #
|
Relay_Log_Pos #
|
||||||
Relay_Master_Log_File master-bin.000001
|
Relay_Master_Log_File master-bin.000001
|
||||||
@ -133,7 +133,7 @@ Replicate_Wild_Ignore_Table
|
|||||||
Last_Errno 0
|
Last_Errno 0
|
||||||
Last_Error
|
Last_Error
|
||||||
Skip_Counter 0
|
Skip_Counter 0
|
||||||
Exec_Master_Log_Pos 386
|
Exec_Master_Log_Pos 387
|
||||||
Relay_Log_Space #
|
Relay_Log_Space #
|
||||||
Until_Condition None
|
Until_Condition None
|
||||||
Until_Log_File
|
Until_Log_File
|
||||||
|
271
mysql-test/suite/rpl/r/rpl_stm_user_variables.result
Normal file
271
mysql-test/suite/rpl/r/rpl_stm_user_variables.result
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
stop slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
reset master;
|
||||||
|
reset slave;
|
||||||
|
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||||
|
start slave;
|
||||||
|
SET @positive= 18446744073709551615;
|
||||||
|
SET @negative= -9223372036854775808;
|
||||||
|
CREATE TABLE t1 (`tinyint` TINYINT,
|
||||||
|
`smallint` SMALLINT,
|
||||||
|
`mediumint` MEDIUMINT,
|
||||||
|
`integer` INTEGER,
|
||||||
|
`bigint` BIGINT,
|
||||||
|
`utinyint` TINYINT UNSIGNED,
|
||||||
|
`usmallint` SMALLINT UNSIGNED,
|
||||||
|
`umediumint` MEDIUMINT UNSIGNED,
|
||||||
|
`uinteger` INTEGER UNSIGNED,
|
||||||
|
`ubigint` BIGINT UNSIGNED,
|
||||||
|
`double` DOUBLE,
|
||||||
|
`float` FLOAT,
|
||||||
|
`real` REAL(30,2),
|
||||||
|
`decimal` DECIMAL(30,2)) ENGINE = MyISAM;
|
||||||
|
### insert max unsigned
|
||||||
|
### a) declarative
|
||||||
|
INSERT INTO t1 VALUES (18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615,18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615);;
|
||||||
|
#########################################
|
||||||
|
#### [ on master ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint 127
|
||||||
|
smallint 32767
|
||||||
|
mediumint 8388607
|
||||||
|
integer 2147483647
|
||||||
|
bigint 9223372036854775807
|
||||||
|
utinyint 255
|
||||||
|
usmallint 65535
|
||||||
|
umediumint 16777215
|
||||||
|
uinteger 4294967295
|
||||||
|
ubigint 18446744073709551615
|
||||||
|
double 1.84467440737096e+19
|
||||||
|
float 1.84467e+19
|
||||||
|
real 18446744073709551616.00
|
||||||
|
decimal 18446744073709551615.00
|
||||||
|
#### [ on slave ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint 127
|
||||||
|
smallint 32767
|
||||||
|
mediumint 8388607
|
||||||
|
integer 2147483647
|
||||||
|
bigint 9223372036854775807
|
||||||
|
utinyint 255
|
||||||
|
usmallint 65535
|
||||||
|
umediumint 16777215
|
||||||
|
uinteger 4294967295
|
||||||
|
ubigint 18446744073709551615
|
||||||
|
double 1.84467440737096e+19
|
||||||
|
float 1.84467e+19
|
||||||
|
real 18446744073709551616.00
|
||||||
|
decimal 18446744073709551615.00
|
||||||
|
#########################################
|
||||||
|
## assertion: master and slave tables are in sync
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
TRUNCATE t1;
|
||||||
|
### b) user var
|
||||||
|
INSERT INTO t1 VALUES (@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive);
|
||||||
|
#########################################
|
||||||
|
#### [ on master ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint 127
|
||||||
|
smallint 32767
|
||||||
|
mediumint 8388607
|
||||||
|
integer 2147483647
|
||||||
|
bigint 9223372036854775807
|
||||||
|
utinyint 255
|
||||||
|
usmallint 65535
|
||||||
|
umediumint 16777215
|
||||||
|
uinteger 4294967295
|
||||||
|
ubigint 18446744073709551615
|
||||||
|
double 1.84467440737096e+19
|
||||||
|
float 1.84467e+19
|
||||||
|
real 18446744073709551616.00
|
||||||
|
decimal 18446744073709551615.00
|
||||||
|
#### [ on slave ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint 127
|
||||||
|
smallint 32767
|
||||||
|
mediumint 8388607
|
||||||
|
integer 2147483647
|
||||||
|
bigint 9223372036854775807
|
||||||
|
utinyint 255
|
||||||
|
usmallint 65535
|
||||||
|
umediumint 16777215
|
||||||
|
uinteger 4294967295
|
||||||
|
ubigint 18446744073709551615
|
||||||
|
double 1.84467440737096e+19
|
||||||
|
float 1.84467e+19
|
||||||
|
real 18446744073709551616.00
|
||||||
|
decimal 18446744073709551615.00
|
||||||
|
#########################################
|
||||||
|
## assertion: master and slave tables are in sync
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
TRUNCATE t1;
|
||||||
|
### insert min signed
|
||||||
|
### a) declarative
|
||||||
|
INSERT INTO t1 VALUES (-9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808,-9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808);;
|
||||||
|
#########################################
|
||||||
|
#### [ on master ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint -128
|
||||||
|
smallint -32768
|
||||||
|
mediumint -8388608
|
||||||
|
integer -2147483648
|
||||||
|
bigint -9223372036854775808
|
||||||
|
utinyint 0
|
||||||
|
usmallint 0
|
||||||
|
umediumint 0
|
||||||
|
uinteger 0
|
||||||
|
ubigint 0
|
||||||
|
double -9.22337203685478e+18
|
||||||
|
float -9.22337e+18
|
||||||
|
real -9223372036854775808.00
|
||||||
|
decimal -9223372036854775808.00
|
||||||
|
#### [ on slave ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint -128
|
||||||
|
smallint -32768
|
||||||
|
mediumint -8388608
|
||||||
|
integer -2147483648
|
||||||
|
bigint -9223372036854775808
|
||||||
|
utinyint 0
|
||||||
|
usmallint 0
|
||||||
|
umediumint 0
|
||||||
|
uinteger 0
|
||||||
|
ubigint 0
|
||||||
|
double -9.22337203685478e+18
|
||||||
|
float -9.22337e+18
|
||||||
|
real -9223372036854775808.00
|
||||||
|
decimal -9223372036854775808.00
|
||||||
|
#########################################
|
||||||
|
## assertion: master and slave tables are in sync
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
TRUNCATE t1;
|
||||||
|
### b) user var
|
||||||
|
INSERT INTO t1 VALUES (@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative);
|
||||||
|
#########################################
|
||||||
|
#### [ on master ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint -128
|
||||||
|
smallint -32768
|
||||||
|
mediumint -8388608
|
||||||
|
integer -2147483648
|
||||||
|
bigint -9223372036854775808
|
||||||
|
utinyint 0
|
||||||
|
usmallint 0
|
||||||
|
umediumint 0
|
||||||
|
uinteger 0
|
||||||
|
ubigint 0
|
||||||
|
double -9.22337203685478e+18
|
||||||
|
float -9.22337e+18
|
||||||
|
real -9223372036854775808.00
|
||||||
|
decimal -9223372036854775808.00
|
||||||
|
#### [ on slave ]
|
||||||
|
SELECT * FROM t1;
|
||||||
|
tinyint -128
|
||||||
|
smallint -32768
|
||||||
|
mediumint -8388608
|
||||||
|
integer -2147483648
|
||||||
|
bigint -9223372036854775808
|
||||||
|
utinyint 0
|
||||||
|
usmallint 0
|
||||||
|
umediumint 0
|
||||||
|
uinteger 0
|
||||||
|
ubigint 0
|
||||||
|
double -9.22337203685478e+18
|
||||||
|
float -9.22337e+18
|
||||||
|
real -9223372036854775808.00
|
||||||
|
decimal -9223372036854775808.00
|
||||||
|
#########################################
|
||||||
|
## assertion: master and slave tables are in sync
|
||||||
|
Comparing tables master:test.t1 and slave:test.t1
|
||||||
|
TRUNCATE t1;
|
||||||
|
## check: contents of both tables master's and slave's
|
||||||
|
## assertion: checks that User_var_log_event::pack_info correctly
|
||||||
|
## displays the binlog content by taking into account the
|
||||||
|
## unsigned_flag
|
||||||
|
show binlog events from <binlog_start>;
|
||||||
|
Log_name Pos Event_type Server_id End_log_pos Info
|
||||||
|
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (`tinyint` TINYINT,
|
||||||
|
`smallint` SMALLINT,
|
||||||
|
`mediumint` MEDIUMINT,
|
||||||
|
`integer` INTEGER,
|
||||||
|
`bigint` BIGINT,
|
||||||
|
`utinyint` TINYINT UNSIGNED,
|
||||||
|
`usmallint` SMALLINT UNSIGNED,
|
||||||
|
`umediumint` MEDIUMINT UNSIGNED,
|
||||||
|
`uinteger` INTEGER UNSIGNED,
|
||||||
|
`ubigint` BIGINT UNSIGNED,
|
||||||
|
`double` DOUBLE,
|
||||||
|
`float` FLOAT,
|
||||||
|
`real` REAL(30,2),
|
||||||
|
`decimal` DECIMAL(30,2)) ENGINE = MyISAM
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615,18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615, 18446744073709551615)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE t1
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # User var # # @`positive`=18446744073709551615
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE t1
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (-9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808,-9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808, -9223372036854775808)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE t1
|
||||||
|
master-bin.000001 # Query # # BEGIN
|
||||||
|
master-bin.000001 # User var # # @`negative`=-9223372036854775808
|
||||||
|
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative)
|
||||||
|
master-bin.000001 # Query # # COMMIT
|
||||||
|
master-bin.000001 # Query # # use `test`; TRUNCATE t1
|
||||||
|
DROP TABLE t1;
|
146
mysql-test/suite/rpl/t/rpl_stm_user_variables.test
Normal file
146
mysql-test/suite/rpl/t/rpl_stm_user_variables.test
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
#
|
||||||
|
# BUG#49562: SBR out of sync when using numeric data types + user variable
|
||||||
|
#
|
||||||
|
|
||||||
|
-- source include/master-slave.inc
|
||||||
|
-- source include/have_binlog_format_statement.inc
|
||||||
|
|
||||||
|
## Setup user variables for several numeric types, so that we get
|
||||||
|
## coverage on the User_var_log_event different val types
|
||||||
|
|
||||||
|
-- let $max_unsigned_long= 18446744073709551615
|
||||||
|
-- let $min_signed_long= -9223372036854775808
|
||||||
|
-- eval SET @positive= $max_unsigned_long
|
||||||
|
-- eval SET @negative= $min_signed_long
|
||||||
|
|
||||||
|
CREATE TABLE t1 (`tinyint` TINYINT,
|
||||||
|
`smallint` SMALLINT,
|
||||||
|
`mediumint` MEDIUMINT,
|
||||||
|
`integer` INTEGER,
|
||||||
|
`bigint` BIGINT,
|
||||||
|
`utinyint` TINYINT UNSIGNED,
|
||||||
|
`usmallint` SMALLINT UNSIGNED,
|
||||||
|
`umediumint` MEDIUMINT UNSIGNED,
|
||||||
|
`uinteger` INTEGER UNSIGNED,
|
||||||
|
`ubigint` BIGINT UNSIGNED,
|
||||||
|
`double` DOUBLE,
|
||||||
|
`float` FLOAT,
|
||||||
|
`real` REAL(30,2),
|
||||||
|
`decimal` DECIMAL(30,2)) ENGINE = MyISAM;
|
||||||
|
|
||||||
|
-- disable_warnings
|
||||||
|
|
||||||
|
-- echo ### insert max unsigned
|
||||||
|
-- echo ### a) declarative
|
||||||
|
-- eval INSERT INTO t1 VALUES ($max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long,$max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long, $max_unsigned_long);
|
||||||
|
|
||||||
|
-- echo #########################################
|
||||||
|
-- echo #### [ on master ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- sync_slave_with_master
|
||||||
|
-- echo #### [ on slave ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- echo #########################################
|
||||||
|
-- connection master
|
||||||
|
-- echo ## assertion: master and slave tables are in sync
|
||||||
|
-- let $diff_table_1=master:test.t1
|
||||||
|
-- let $diff_table_2=slave:test.t1
|
||||||
|
-- source include/diff_tables.inc
|
||||||
|
-- connection master
|
||||||
|
TRUNCATE t1;
|
||||||
|
|
||||||
|
-- echo ### b) user var
|
||||||
|
INSERT INTO t1 VALUES (@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive,
|
||||||
|
@positive);
|
||||||
|
|
||||||
|
-- echo #########################################
|
||||||
|
-- echo #### [ on master ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- sync_slave_with_master
|
||||||
|
-- echo #### [ on slave ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- echo #########################################
|
||||||
|
-- connection master
|
||||||
|
-- echo ## assertion: master and slave tables are in sync
|
||||||
|
-- let $diff_table_1=master:test.t1
|
||||||
|
-- let $diff_table_2=slave:test.t1
|
||||||
|
-- source include/diff_tables.inc
|
||||||
|
-- connection master
|
||||||
|
TRUNCATE t1;
|
||||||
|
|
||||||
|
|
||||||
|
-- echo ### insert min signed
|
||||||
|
-- echo ### a) declarative
|
||||||
|
-- eval INSERT INTO t1 VALUES ($min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long,$min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long, $min_signed_long);
|
||||||
|
|
||||||
|
-- echo #########################################
|
||||||
|
-- echo #### [ on master ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- sync_slave_with_master
|
||||||
|
-- echo #### [ on slave ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- echo #########################################
|
||||||
|
-- connection master
|
||||||
|
-- echo ## assertion: master and slave tables are in sync
|
||||||
|
-- let $diff_table_1=master:test.t1
|
||||||
|
-- let $diff_table_2=slave:test.t1
|
||||||
|
-- source include/diff_tables.inc
|
||||||
|
-- connection master
|
||||||
|
TRUNCATE t1;
|
||||||
|
|
||||||
|
-- echo ### b) user var
|
||||||
|
INSERT INTO t1 VALUES (@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative,
|
||||||
|
@negative);
|
||||||
|
|
||||||
|
-- echo #########################################
|
||||||
|
-- echo #### [ on master ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- sync_slave_with_master
|
||||||
|
-- echo #### [ on slave ]
|
||||||
|
-- query_vertical SELECT * FROM t1
|
||||||
|
-- echo #########################################
|
||||||
|
-- connection master
|
||||||
|
|
||||||
|
-- echo ## assertion: master and slave tables are in sync
|
||||||
|
-- let $diff_table_1=master:test.t1
|
||||||
|
-- let $diff_table_2=slave:test.t1
|
||||||
|
-- source include/diff_tables.inc
|
||||||
|
-- connection master
|
||||||
|
TRUNCATE t1;
|
||||||
|
|
||||||
|
-- echo ## check: contents of both tables master's and slave's
|
||||||
|
-- enable_warnings
|
||||||
|
|
||||||
|
-- echo ## assertion: checks that User_var_log_event::pack_info correctly
|
||||||
|
-- echo ## displays the binlog content by taking into account the
|
||||||
|
-- echo ## unsigned_flag
|
||||||
|
-- source include/show_binlog_events.inc
|
||||||
|
|
||||||
|
## cleanup
|
||||||
|
-- connection master
|
||||||
|
DROP TABLE t1;
|
||||||
|
-- sync_slave_with_master
|
@ -4455,12 +4455,19 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info)
|
|||||||
{
|
{
|
||||||
BINLOG_USER_VAR_EVENT *user_var_event;
|
BINLOG_USER_VAR_EVENT *user_var_event;
|
||||||
get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
|
get_dynamic(&thd->user_var_events,(uchar*) &user_var_event, i);
|
||||||
|
|
||||||
|
/* setting flags for user var log event */
|
||||||
|
uchar flags= User_var_log_event::UNDEF_F;
|
||||||
|
if (user_var_event->user_var_event->unsigned_flag)
|
||||||
|
flags|= User_var_log_event::UNSIGNED_F;
|
||||||
|
|
||||||
User_var_log_event e(thd, user_var_event->user_var_event->name.str,
|
User_var_log_event e(thd, user_var_event->user_var_event->name.str,
|
||||||
user_var_event->user_var_event->name.length,
|
user_var_event->user_var_event->name.length,
|
||||||
user_var_event->value,
|
user_var_event->value,
|
||||||
user_var_event->length,
|
user_var_event->length,
|
||||||
user_var_event->type,
|
user_var_event->type,
|
||||||
user_var_event->charset_number);
|
user_var_event->charset_number,
|
||||||
|
flags);
|
||||||
if (e.write(file))
|
if (e.write(file))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -5460,7 +5460,9 @@ void User_var_log_event::pack_info(Protocol* protocol)
|
|||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
|
if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
|
||||||
return;
|
return;
|
||||||
event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
|
event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
|
||||||
|
((flags & User_var_log_event::UNSIGNED_F) ?
|
||||||
|
10 : -10))-buf;
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
{
|
||||||
@ -5518,12 +5520,14 @@ User_var_log_event(const char* buf,
|
|||||||
:Log_event(buf, description_event)
|
:Log_event(buf, description_event)
|
||||||
{
|
{
|
||||||
/* The Post-Header is empty. The Variable Data part begins immediately. */
|
/* The Post-Header is empty. The Variable Data part begins immediately. */
|
||||||
|
const char *start= buf;
|
||||||
buf+= description_event->common_header_len +
|
buf+= description_event->common_header_len +
|
||||||
description_event->post_header_len[USER_VAR_EVENT-1];
|
description_event->post_header_len[USER_VAR_EVENT-1];
|
||||||
name_len= uint4korr(buf);
|
name_len= uint4korr(buf);
|
||||||
name= (char *) buf + UV_NAME_LEN_SIZE;
|
name= (char *) buf + UV_NAME_LEN_SIZE;
|
||||||
buf+= UV_NAME_LEN_SIZE + name_len;
|
buf+= UV_NAME_LEN_SIZE + name_len;
|
||||||
is_null= (bool) *buf;
|
is_null= (bool) *buf;
|
||||||
|
flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
|
||||||
if (is_null)
|
if (is_null)
|
||||||
{
|
{
|
||||||
type= STRING_RESULT;
|
type= STRING_RESULT;
|
||||||
@ -5539,6 +5543,27 @@ User_var_log_event(const char* buf,
|
|||||||
UV_CHARSET_NUMBER_SIZE);
|
UV_CHARSET_NUMBER_SIZE);
|
||||||
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||||
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
|
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
|
||||||
|
|
||||||
|
/**
|
||||||
|
We need to check if this is from an old server
|
||||||
|
that did not pack information for flags.
|
||||||
|
We do this by checking if there are extra bytes
|
||||||
|
after the packed value. If there are we take the
|
||||||
|
extra byte and it's value is assumed to contain
|
||||||
|
the flags value.
|
||||||
|
|
||||||
|
Old events will not have this extra byte, thence,
|
||||||
|
we keep the flags set to UNDEF_F.
|
||||||
|
*/
|
||||||
|
uint bytes_read= ((val + val_len) - start);
|
||||||
|
DBUG_ASSERT(bytes_read==data_written ||
|
||||||
|
bytes_read==(data_written-1));
|
||||||
|
if ((data_written - bytes_read) > 0)
|
||||||
|
{
|
||||||
|
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||||
|
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
|
||||||
|
val_len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5550,6 +5575,7 @@ bool User_var_log_event::write(IO_CACHE* file)
|
|||||||
char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
|
||||||
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
|
UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
|
||||||
uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
|
uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
|
||||||
|
uint unsigned_len= 0;
|
||||||
uint buf1_length;
|
uint buf1_length;
|
||||||
ulong event_length;
|
ulong event_length;
|
||||||
|
|
||||||
@ -5571,6 +5597,7 @@ bool User_var_log_event::write(IO_CACHE* file)
|
|||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
int8store(buf2, *(longlong*) val);
|
int8store(buf2, *(longlong*) val);
|
||||||
|
unsigned_len= 1;
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
{
|
||||||
@ -5595,13 +5622,14 @@ bool User_var_log_event::write(IO_CACHE* file)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Length of the whole event */
|
/* Length of the whole event */
|
||||||
event_length= sizeof(buf)+ name_len + buf1_length + val_len;
|
event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
|
||||||
|
|
||||||
return (write_header(file, event_length) ||
|
return (write_header(file, event_length) ||
|
||||||
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
|
my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
|
||||||
my_b_safe_write(file, (uchar*) name, name_len) ||
|
my_b_safe_write(file, (uchar*) name, name_len) ||
|
||||||
my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
|
my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
|
||||||
my_b_safe_write(file, pos, val_len));
|
my_b_safe_write(file, pos, val_len) ||
|
||||||
|
my_b_safe_write(file, (uchar*) &flags, unsigned_len));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -5642,7 +5670,8 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
|
|||||||
break;
|
break;
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
char int_buf[22];
|
char int_buf[22];
|
||||||
longlong10_to_str(uint8korr(val), int_buf, -10);
|
longlong10_to_str(uint8korr(val), int_buf,
|
||||||
|
((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
|
||||||
my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
|
my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
|
||||||
break;
|
break;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
@ -5789,7 +5818,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli)
|
|||||||
a single record and with a single column. Thus, like
|
a single record and with a single column. Thus, like
|
||||||
a column value, it could always have IMPLICIT derivation.
|
a column value, it could always have IMPLICIT derivation.
|
||||||
*/
|
*/
|
||||||
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
|
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
|
||||||
|
(flags & User_var_log_event::UNSIGNED_F));
|
||||||
free_root(thd->mem_root,0);
|
free_root(thd->mem_root,0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2483,6 +2483,10 @@ private:
|
|||||||
class User_var_log_event: public Log_event
|
class User_var_log_event: public Log_event
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum {
|
||||||
|
UNDEF_F= 0,
|
||||||
|
UNSIGNED_F= 1
|
||||||
|
};
|
||||||
char *name;
|
char *name;
|
||||||
uint name_len;
|
uint name_len;
|
||||||
char *val;
|
char *val;
|
||||||
@ -2490,12 +2494,14 @@ public:
|
|||||||
Item_result type;
|
Item_result type;
|
||||||
uint charset_number;
|
uint charset_number;
|
||||||
bool is_null;
|
bool is_null;
|
||||||
|
uchar flags;
|
||||||
#ifndef MYSQL_CLIENT
|
#ifndef MYSQL_CLIENT
|
||||||
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg,
|
||||||
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
char *val_arg, ulong val_len_arg, Item_result type_arg,
|
||||||
uint charset_number_arg)
|
uint charset_number_arg, uchar flags_arg)
|
||||||
:Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
|
:Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
|
||||||
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
|
val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg),
|
||||||
|
flags(flags_arg)
|
||||||
{ is_null= !val; }
|
{ is_null= !val; }
|
||||||
void pack_info(Protocol* protocol);
|
void pack_info(Protocol* protocol);
|
||||||
#else
|
#else
|
||||||
|
Reference in New Issue
Block a user