diff --git a/mysql-test/lib/My/Handles.pm b/mysql-test/lib/My/Handles.pm index 3c9513fec8f..c07e2edb09e 100644 --- a/mysql-test/lib/My/Handles.pm +++ b/mysql-test/lib/My/Handles.pm @@ -32,8 +32,8 @@ if (IS_WINDOWS){ my $list= `handle.exe -? -accepteula 2>&1`; foreach my $line (split('\n', $list)) { - $handle_exe= "$1.$2" - if ($line =~ /Handle v([0-9]*)\.([0-9]*)/); + $handle_exe= "$2.$3" + if ($line =~ /(Nth|H)andle v([0-9]*)\.([0-9]*)/); } if ($handle_exe){ print "Found handle.exe version $handle_exe\n"; diff --git a/mysql-test/suite/innodb/r/innodb-read-view.result b/mysql-test/suite/innodb/r/innodb-read-view.result new file mode 100644 index 00000000000..eb48a5ab661 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-read-view.result @@ -0,0 +1,227 @@ +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); +CREATE TABLE t2 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t2 VALUES(0, "a"); +INSERT INTO t2 VALUES(1, "b"); +INSERT INTO t2 VALUES(2, "c"); +INSERT INTO t2 VALUES(3, "d"); +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connection con1; +'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; +c1 c2 +0 a +1 b +2 c +3 d +connection default; +'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; +c1 c2 +0 0 +1 1 +2 2 +3 3 +connection con2; +'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +c1 c2 +0 0 +1 1 +2 2 +3 3 +SELECT * FROM t2; +c1 c2 +0 a +1 b +2 c +3 d +connection con1; +'T1' +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +c1 c2 +100 a +101 b +102 c +103 d +COMMIT; +connection default; +'T2' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +c1 c2 +100 0 +101 1 +102 2 +103 3 +COMMIT; +connection con2; +'T3' +SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; +SELECT * FROM t1;; +connection default; +'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +'Signalled T3' +connection con2; +'T3' +c1 c2 +0 0 +1 1 +2 2 +3 3 +connection con2; +'T3' +SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; +SELECT * FROM t2;; +connection default; +'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +'Signalled T3' +connection con2; +'T3' +c1 c2 +0 a +1 b +2 c +3 d +connection default; +disconnect con1; +disconnect con2; +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connection con1; +'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; +c1 c2 +100 0 +101 1 +102 2 +103 3 +connection default; +'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; +c1 c2 +100 a +101 b +102 c +103 d +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +c1 c2 +200 a +201 b +202 c +203 d +COMMIT; +connection con2; +'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +c1 c2 +100 0 +101 1 +102 2 +103 3 +SELECT * FROM t2; +c1 c2 +200 a +201 b +202 c +203 d +connection con1; +'T1' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +c1 c2 +200 0 +201 1 +202 2 +203 3 +COMMIT; +connection con2; +'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +SELECT * FROM t1;; +connection con1; +'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +'Signalled T3' +connection con2; +'T3' +c1 c2 +100 0 +101 1 +102 2 +103 3 +connection con2; +'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +SELECT * FROM t2;; +connection default; +'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +'Signalled T3' +connection con2; +'T3' +c1 c2 +200 a +201 b +202 c +203 d +connection default; +disconnect con1; +disconnect con2; +DROP TABLE t1; +DROP TABLE t2; +# +# Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION +# +connect con1,localhost,root,,; +# connection con1 +CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; +INSERT INTO t1 values (1, 0), (2, 0); +SELECT * FROM t1 ORDER BY col1; +col1 col2 +1 0 +2 0 +START TRANSACTION; +UPDATE t1 SET col2 = 100; +SET DEBUG_SYNC = 'after_trx_committed_in_memory SIGNAL s1 WAIT_FOR s2'; +COMMIT;; +connection default; +# connection default +SET DEBUG_SYNC = 'now WAIT_FOR s1'; +UPDATE t1 SET col2 = col2 + 10 where col1 = 1; +COMMIT; +SELECT * FROM t1 ORDER BY col1; +col1 col2 +1 110 +2 100 +SET DEBUG_SYNC = 'now SIGNAL s2'; +connection con1; +# connection con1 +# reap COMMIT for con1 +connection default; +# connection default +disconnect con1; +DROP TABLE t1; +SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/suite/innodb/t/innodb-read-view.test b/mysql-test/suite/innodb/t/innodb-read-view.test new file mode 100644 index 00000000000..ec4026d10c6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-read-view.test @@ -0,0 +1,214 @@ +# DEBUG_SYNC must be compiled in. +--source include/have_debug_sync.inc + +# We need to test the use case: +# a. Create a transaction T1 that will be promoted to RW. +# b. Create a transaction T2 that will be promoted to RW. +# a. Create a RO transaction T3 +# d. T3 does a select - creates a read view that doesn't include T1 and T2 +# e. T1 & T2 do some updates - this promotes T1 & T2 to RW transactions +# f. T1 & T2 Commit +# g. T3 Does a select - it should not see the changes of T1 & T2 + +--source include/have_innodb.inc +--source include/count_sessions.inc + +CREATE TABLE t1 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t1 VALUES(0, "0"); +INSERT INTO t1 VALUES(1, "1"); +INSERT INTO t1 VALUES(2, "2"); +INSERT INTO t1 VALUES(3, "3"); + +CREATE TABLE t2 (c1 INT , c2 CHAR(10), PRIMARY KEY (c1)) ENGINE = InnoDB; +INSERT INTO t2 VALUES(0, "a"); +INSERT INTO t2 VALUES(1, "b"); +INSERT INTO t2 VALUES(2, "c"); +INSERT INTO t2 VALUES(3, "d"); + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) + +connection con1; +--echo 'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; + +connection default; +--echo 'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; + +connection con2; +--echo 'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +SELECT * FROM t2; + +connection con1; +--echo 'T1' +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +COMMIT; + +connection default; +--echo 'T2' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +COMMIT; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; +--send SELECT * FROM t1; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_search_for_mysql_before_return WAIT_FOR waiting1'; +--send SELECT * FROM t2; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection default; +disconnect con1; +disconnect con2; + +# We need to test the use case: +# a. Create a transaction T1 that will be promoted to RW. +# b. Create a transaction T2 that will be promoted to RW. +# c. T2 does some updates - this promotes T2 to RW transactions +# d. T2 Commits +# e. Create a RO transaction T3 +# f. T3 does a select - creates a read view that doesn't include T1 +# g. T1 does some updates - this promotes T1 to RW transactions +# h. T1 Commits +# i. T3 Does a select - it should not see the changes made by T1 but should +# see the changes by T2 + +--connect (con1,localhost,root,,) +--connect (con2,localhost,root,,) + +connection con1; +--echo 'T1' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t1; + +connection default; +--echo 'T2' +SET AUTOCOMMIT=0; +BEGIN; +SELECT * FROM t2; +UPDATE t2 SET c1 = c1 + 100; +SELECT * FROM t2; +COMMIT; + +connection con2; +--echo 'T3' +SET AUTOCOMMIT=0; +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +SELECT * FROM t1; +SELECT * FROM t2; + +connection con1; +--echo 'T1' +UPDATE t1 SET c1 = c1 + 100; +SELECT * FROM t1; +COMMIT; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t1; + +connection con1; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection con2; +--echo 'T3' +SET DEBUG_SYNC='row_select_wait WAIT_FOR waiting1'; +--send SELECT * FROM t2; + +connection default; +--echo 'T2' +SET DEBUG_SYNC='now SIGNAL waiting1'; +--echo 'Signalled T3' + +connection con2; +--echo 'T3' +reap; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t1; +DROP TABLE t2; + +--echo # +--echo # Bug 21433768: NON-REPEATABLE READ WITH REPEATABLE READ ISOLATION +--echo # + +--connect (con1,localhost,root,,) +--echo # connection con1 + +CREATE TABLE t1(col1 INT PRIMARY KEY, col2 INT) ENGINE = InnoDB; +INSERT INTO t1 values (1, 0), (2, 0); +SELECT * FROM t1 ORDER BY col1; + +START TRANSACTION; +UPDATE t1 SET col2 = 100; +SET DEBUG_SYNC = 'after_trx_committed_in_memory SIGNAL s1 WAIT_FOR s2'; +--send COMMIT; + +connection default; +--echo # connection default +SET DEBUG_SYNC = 'now WAIT_FOR s1'; +UPDATE t1 SET col2 = col2 + 10 where col1 = 1; +COMMIT; + +SELECT * FROM t1 ORDER BY col1; +SET DEBUG_SYNC = 'now SIGNAL s2'; + +connection con1; +--echo # connection con1 +--echo # reap COMMIT for con1 +reap; + +connection default; +--echo # connection default +disconnect con1; + +DROP TABLE t1; + +# Clean up resources used in this test case. +--disable_warnings +SET DEBUG_SYNC= 'RESET'; +--enable_warnings +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/mariabackup/disabled.def b/mysql-test/suite/mariabackup/disabled.def new file mode 100644 index 00000000000..88a66df052d --- /dev/null +++ b/mysql-test/suite/mariabackup/disabled.def @@ -0,0 +1,12 @@ +############################################################################## +# +# List the test cases that are to be disabled temporarily. +# +# Separate the test case name and the comment with ':'. +# +# : BUG# +# +# Do not use any TAB characters for whitespace. +# +############################################################################## +big_innodb_log : MDEV-20421 2019-08-26 wlad Always fails on Windows buildbot \ No newline at end of file diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result index 3aa7c07a845..5865b75550f 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_innodb.result @@ -468,7 +468,7 @@ INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5 octets) character set latin1'' *** Drop t10 *** connection master; @@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254 octets) character set latin1'' *** Drop t11 *** connection master; diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result index 0918364b28e..f47d79b5b86 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_master_myisam.result @@ -468,7 +468,7 @@ INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5 octets) character set latin1'' *** Drop t10 *** connection master; @@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254 octets) character set latin1'' *** Drop t11 *** connection master; diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result b/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result index 456c1c24f8f..a9cbbd9fafe 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_slave_innodb.result @@ -64,7 +64,7 @@ a b c connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10 octets)' to type 'char(5 octets) character set latin1'' STOP SLAVE; RESET SLAVE; SELECT * FROM t2 ORDER BY a; @@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'' +Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)'' *** Drop t3 *** connection master; DROP TABLE t3; @@ -160,7 +160,7 @@ INSERT INTO t5 () VALUES(1,'Kyle',200.23,1,'b1b1',23.00098), ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t5 *** connection master; DROP TABLE t5; @@ -188,7 +188,7 @@ INSERT INTO t6 () VALUES(1,'Kyle',200.23,1), ******************************************** connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t6 *** include/rpl_reset.inc connection master; @@ -310,7 +310,7 @@ INSERT INTO t10 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5 octets)' to type 'double'' *** Drop t10 *** connection master; DROP TABLE t10; @@ -338,7 +338,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254 octets)' to type 'int(11)'' *** Drop t11 *** connection master; DROP TABLE t11; diff --git a/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result b/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result index 7178a2a78b8..11a716f22b6 100644 --- a/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result +++ b/mysql-test/suite/rpl/r/rpl_extra_col_slave_myisam.result @@ -64,7 +64,7 @@ a b c connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10 octets)' to type 'char(5 octets) character set latin1'' STOP SLAVE; RESET SLAVE; SELECT * FROM t2 ORDER BY a; @@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'' +Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)'' *** Drop t3 *** connection master; DROP TABLE t3; @@ -160,7 +160,7 @@ INSERT INTO t5 () VALUES(1,'Kyle',200.23,1,'b1b1',23.00098), ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t5 *** connection master; DROP TABLE t5; @@ -188,7 +188,7 @@ INSERT INTO t6 () VALUES(1,'Kyle',200.23,1), ******************************************** connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t6 *** include/rpl_reset.inc connection master; @@ -310,7 +310,7 @@ INSERT INTO t10 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5 octets)' to type 'double'' *** Drop t10 *** connection master; DROP TABLE t10; @@ -338,7 +338,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254 octets)' to type 'int(11)'' *** Drop t11 *** connection master; DROP TABLE t11; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result index 1d4b31a4a87..98e95e8cc77 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_2myisam.result @@ -560,7 +560,7 @@ INSERT INTO t5 VALUES (1, "", 1); INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(255)' to type 'char(16)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(765 octets)' to type 'char(48 octets) character set utf8'' include/rpl_reset.inc [expecting slave to stop] connection master; @@ -568,7 +568,7 @@ INSERT INTO t6 VALUES (1, "", 1); INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(255)' to type 'char(128)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(765 octets)' to type 'char(384 octets) character set utf8'' include/rpl_reset.inc [expecting slave to replicate correctly] connection master; diff --git a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result index 1e3ddd4f289..3203d5394df 100644 --- a/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result +++ b/mysql-test/suite/rpl/r/rpl_row_basic_3innodb.result @@ -565,7 +565,7 @@ INSERT INTO t5 VALUES (1, "", 1); INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(255)' to type 'char(16)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(765 octets)' to type 'char(48 octets) character set utf8'' include/rpl_reset.inc [expecting slave to stop] connection master; @@ -573,7 +573,7 @@ INSERT INTO t6 VALUES (1, "", 1); INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(255)' to type 'char(128)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(765 octets)' to type 'char(384 octets) character set utf8'' include/rpl_reset.inc [expecting slave to replicate correctly] connection master; diff --git a/mysql-test/suite/rpl/r/rpl_row_colSize.result b/mysql-test/suite/rpl/r/rpl_row_colSize.result index dd324ef7807..748d83a7f8e 100644 --- a/mysql-test/suite/rpl/r/rpl_row_colSize.result +++ b/mysql-test/suite/rpl/r/rpl_row_colSize.result @@ -185,7 +185,7 @@ INSERT INTO t1 VALUES ('This is a test.'); connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'char(20)' to type 'char(10)'' +Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'char(20 octets)' to type 'char(10 octets) character set latin1'' SELECT COUNT(*) FROM t1; COUNT(*) 0 @@ -264,7 +264,7 @@ INSERT INTO t1 VALUES ('This is a test.'); connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(100)'' +Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000 octets)' to type 'varchar(100 octets) character set latin1'' SELECT COUNT(*) FROM t1; COUNT(*) 0 @@ -287,7 +287,7 @@ INSERT INTO t1 VALUES ('This is a test.'); connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(200)' to type 'varchar(10)'' +Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(200 octets)' to type 'varchar(10 octets) character set latin1'' SELECT COUNT(*) FROM t1; COUNT(*) 0 @@ -310,7 +310,7 @@ INSERT INTO t1 VALUES ('This is a test.'); connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000)' to type 'varchar(1000)'' +Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'varchar(2000 octets)' to type 'varchar(1000 octets) character set latin1'' SELECT COUNT(*) FROM t1; COUNT(*) 0 @@ -334,7 +334,7 @@ INSERT INTO t1 VALUES ('This is a test.'); connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'tinyblob' to type 'tinyblob'' +Last_SQL_Error = 'Column 0 of table 'test.t1' cannot be converted from type 'longblob' to type 'tinyblob'' SELECT COUNT(*) FROM t1; COUNT(*) 0 diff --git a/mysql-test/suite/rpl/r/rpl_row_type_conv_err_msg.result b/mysql-test/suite/rpl/r/rpl_row_type_conv_err_msg.result new file mode 100644 index 00000000000..4b348425877 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_type_conv_err_msg.result @@ -0,0 +1,164 @@ +include/master-slave.inc +[connection master] +#################################################################### +# Test Case1: Improved error message with charset information +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 VARCHAR(1) CHARACTER SET 'utf8mb3'); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 VARCHAR(1) CHARACTER SET 'utf8mb4'); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'varchar\(3 octets\)\' to type \'varchar\(4 octets\) character set utf8mb4\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case2: Improved error message with charset information for CHAR +# type +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET 'utf8mb3'); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET 'utf8mb4'); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'char\(3 octets\)\' to type \'char\(4 octets\) character set utf8mb4\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case3: For BLOB type fileds, when type conversion failed on +# slave, the errormessage had incorrect type names. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 LONGBLOB); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 TINYBLOB); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'longblob\' to type \'tinyblob\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case4: Verifies varbinary to binary type conversion failure +# specific error message. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 VARBINARY(10)); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 BINARY(10)); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'varbinary\(10\)\' to type \'binary\(10\)\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case5: Verifies binary to varbinary type conversion failure +# specific error message. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 BINARY(10)); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 VARBINARY(10)); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'binary\(10\)\' to type \'varbinary\(10\)\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case6: Verifies binary to binary type conversion failure +# specific error message. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 BINARY(1)); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 BINARY(10)); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'binary\(1\)\' to type \'binary\(10\)\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case7: Verifies char to blob type conversion failure +# specific error message. BLOB field on slave has no +# associated character set hence the master side field +# is also considered as binary. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1)); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 BLOB); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'binary\(1\)\' to type \'blob\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +#################################################################### +# Test Case8: Verifies char to text type conversion failure +# specific error message. +#################################################################### +connection master; +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1)); +SET SQL_LOG_BIN=1; +connection slave; +CREATE TABLE t1 (c1 TEXT); +connection master; +INSERT INTO t1 VALUES ('a'); +connection slave; +include/wait_for_slave_sql_error.inc [errno=1677] +FOUND 1 /\'char\(1 octets\)\' to type \'text\'/ in mysqld.2.err +connection master; +DROP TABLE t1; +connection slave; +DROP TABLE t1; +include/rpl_reset.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_type_conv_err_msg.test b/mysql-test/suite/rpl/t/rpl_row_type_conv_err_msg.test new file mode 100644 index 00000000000..2442f869abc --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_type_conv_err_msg.test @@ -0,0 +1,356 @@ +# ==== Purpose ==== +# +# Test verifies that when slave side type conversion fails in row based +# replication, more informative error message is displayed. It also verifies +# that in the case of blob fields appropriate type name is displayed in error +# message. +# +# ==== Implementation ==== +# +# Steps: +# Test case1: +# 1. Create a table on master with VARCHAR filed and charset +# 'utf8mb3'. +# 2. Create a table on slave with VARCHAR field and charset +# 'utf8mb4'. +# 3. Insert a tuple on master. +# 4. Verify that slave provides more informative error message with +# respect to difference in charsets. +# Test case2: Repeat same steps as above for CHAR field +# Test case3: +# 1. Create a table on master with LONGBLOB field. +# 2. Create a table on slave with TINYBLOB field. +# 3. Insert a tuple on master. +# 4. Verify that error message displayed on slave clearly states type +# conversion failure from 'longblob' to 'tinyblob'. +# 5. Also verify that error message doesn't show additional details +# of charset when not required. +# Test Case4: Verifies varbinary to binary type conversion failure specific +# error message. +# Test Case5: Verifies binary to varbinary type conversion failure specific +# error message. +# Test Case6: Verifies binary to binary type conversion failure specific +# error message. +# Test Case7: Verifies char to blob type conversion failure specific +# error message. +# Test Case8: Verifies char to text type conversion failure specific +# error message. +# ==== References ==== +# +# MDEV-19925: Column ... cannot be converted from type 'varchar(20)' to type +# 'varchar(20)' +# + +--source include/have_binlog_format_row.inc +# Inorder to grep a specific error pattern in error log a fresh error log +# needs to be generated. +--source include/force_restart.inc +--source include/master-slave.inc + +--echo #################################################################### +--echo # Test Case1: Improved error message with charset information +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 VARCHAR(1) CHARACTER SET 'utf8mb3'); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 VARCHAR(1) CHARACTER SET 'utf8mb4'); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Error msg before: Column 0 of table 'test.t1' cannot be converted from type 'varchar(3)' to type 'varchar(1)' +# Error msg after : Column 0 of table 'test.t1' cannot be converted from type 'varchar(3 octets)' to type 'varchar(4 octets) character set utf8mb4' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'varchar\(3 octets\)\' to type \'varchar\(4 octets\) character set utf8mb4\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case2: Improved error message with charset information for CHAR +--echo # type +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET 'utf8mb3'); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 CHAR(1) CHARACTER SET 'utf8mb4'); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Error msg before: Column 0 of table 'test.t1' cannot be converted from type 'char(0)' to type 'char(1)' +# Error msg after : Column 0 of table 'test.t1' cannot be converted from type 'char(3 octets)' to type 'char(4 octets) character set utf8mb4)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'char\(3 octets\)\' to type \'char\(4 octets\) character set utf8mb4\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case3: For BLOB type fileds, when type conversion failed on +--echo # slave, the errormessage had incorrect type names. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 LONGBLOB); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 TINYBLOB); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Error msg before: Column 0 of table 'test.t1' cannot be converted from type 'tinyblob' to type 'tinyblob' +# Error msg after : Column 0 of table 'test.t1' cannot be converted from type 'longblob' to type 'tinyblob' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'longblob\' to type \'tinyblob\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case4: Verifies varbinary to binary type conversion failure +--echo # specific error message. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 VARBINARY(10)); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 BINARY(10)); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Expected Error : Column 0 of table 'test.t1' cannot be converted from type 'varbinary(10)' to type 'binary(10)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'varbinary\(10\)\' to type \'binary\(10\)\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case5: Verifies binary to varbinary type conversion failure +--echo # specific error message. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 BINARY(10)); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 VARBINARY(10)); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Expected Error : Column 0 of table 'test.t1' cannot be converted from type 'binary(10)' to type 'varbinary(10)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'binary\(10\)\' to type \'varbinary\(10\)\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case6: Verifies binary to binary type conversion failure +--echo # specific error message. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 BINARY(1)); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 BINARY(10)); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Expected Error : Column 0 of table 'test.t1' cannot be converted from type 'binary(1)' to type 'binary(10)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'binary\(1\)\' to type \'binary\(10\)\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case7: Verifies char to blob type conversion failure +--echo # specific error message. BLOB field on slave has no +--echo # associated character set hence the master side field +--echo # is also considered as binary. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1)); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 BLOB); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Expected Error : Column 0 of table 'test.t1' cannot be converted from type 'binary(1)' to type 'binary(10)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'binary\(1\)\' to type \'blob\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--echo #################################################################### +--echo # Test Case8: Verifies char to text type conversion failure +--echo # specific error message. +--echo #################################################################### +--connection master +SET SQL_LOG_BIN=0; +CREATE TABLE t1 (c1 CHAR(1)); +SET SQL_LOG_BIN=1; + +--connection slave +CREATE TABLE t1 (c1 TEXT); + +--connection master +INSERT INTO t1 VALUES ('a'); + +--connection slave +--let $slave_sql_errno= 1677 +--source include/wait_for_slave_sql_error.inc + +# Check error log for correct messages. +let $log_error_= `SELECT @@GLOBAL.log_error`; +if(!$log_error_) +{ + # MySQL Server on windows is started with --console and thus + # does not know the location of its .err log, use default location + let $log_error_ = $MYSQLTEST_VARDIR/log/mysqld.2.err; +} + +# Expected Error : Column 0 of table 'test.t1' cannot be converted from type 'binary(1)' to type 'binary(10)' +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=\'char\(1 octets\)\' to type \'text\' +--source include/search_pattern_in_file.inc + +--connection master +DROP TABLE t1; +--connection slave +DROP TABLE t1; +--let $rpl_only_running_threads= 1 +--source include/rpl_reset.inc + +--source include/rpl_end.inc diff --git a/sql/field.cc b/sql/field.cc index fc5ca7675ac..29446b9378b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -7310,6 +7310,28 @@ void Field_string::sql_type(String &res) const res.append(STRING_WITH_LEN(" binary")); } +/** + For fields which are associated with character sets their length is provided + in octets and their character set information is also provided as part of + type information. + + @param res String which contains filed type and length. +*/ +void Field_string::sql_rpl_type(String *res) const +{ + CHARSET_INFO *cs=charset(); + if (Field_string::has_charset()) + { + size_t length= cs->cset->snprintf(cs, (char*) res->ptr(), + res->alloced_length(), + "char(%u octets) character set %s", + field_length, + charset()->csname); + res->length(length); + } + else + Field_string::sql_type(*res); + } uchar *Field_string::pack(uchar *to, const uchar *from, uint max_length) { @@ -7730,6 +7752,29 @@ void Field_varstring::sql_type(String &res) const res.append(STRING_WITH_LEN(" binary")); } +/** + For fields which are associated with character sets their length is provided + in octets and their character set information is also provided as part of + type information. + + @param res String which contains filed type and length. +*/ +void Field_varstring::sql_rpl_type(String *res) const +{ + CHARSET_INFO *cs=charset(); + if (Field_varstring::has_charset()) + { + size_t length= cs->cset->snprintf(cs, (char*) res->ptr(), + res->alloced_length(), + "varchar(%u octets) character set %s", + field_length, + charset()->csname); + res->length(length); + } + else + Field_varstring::sql_type(*res); +} + uint32 Field_varstring::data_length() { diff --git a/sql/field.h b/sql/field.h index 330523f5864..39bd10af525 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1140,6 +1140,7 @@ public: in str and restore it with set() if needed */ virtual void sql_type(String &str) const =0; + virtual void sql_rpl_type(String *str) const { sql_type(*str); } virtual uint size_of() const =0; // For new field inline bool is_null(my_ptrdiff_t row_offset= 0) const { @@ -3362,6 +3363,7 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); void sql_type(String &str) const; + void sql_rpl_type(String*) const; virtual uchar *pack(uchar *to, const uchar *from, uint max_length); virtual const uchar *unpack(uchar* to, const uchar *from, @@ -3472,6 +3474,7 @@ public: uint get_key_image(uchar *buff,uint length, imagetype type); void set_key_image(const uchar *buff,uint length); void sql_type(String &str) const; + void sql_rpl_type(String*) const; virtual uchar *pack(uchar *to, const uchar *from, uint max_length); virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data); diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index b36838b9b22..437d58d772f 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -352,7 +352,8 @@ uint32 table_def::calc_field_size(uint col, uchar *master_data) const #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) /** */ -void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_INFO *field_cs) +void show_sql_type(enum_field_types type, uint16 metadata, String *str, + bool char_with_octets) { DBUG_ENTER("show_sql_type"); DBUG_PRINT("enter", ("type: %d, metadata: 0x%x", type, metadata)); @@ -420,11 +421,13 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_ case MYSQL_TYPE_VARCHAR_COMPRESSED: { CHARSET_INFO *cs= str->charset(); - size_t length= - cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), - "varchar(%u)%s", metadata, - type == MYSQL_TYPE_VARCHAR_COMPRESSED ? " compressed" - : ""); + size_t length=0; + if (char_with_octets) + length= cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), + "varchar(%u octets)", metadata); + else + length= cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), + "varbinary(%u)", metadata); str->length(length); } break; @@ -475,24 +478,24 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_ it is necessary to check the pack length to figure out what kind of blob it really is. */ - switch (get_blob_type_from_length(metadata)) + switch (metadata) { - case MYSQL_TYPE_TINY_BLOB: + case 1: str->set_ascii(STRING_WITH_LEN("tinyblob")); break; - case MYSQL_TYPE_MEDIUM_BLOB: + case 2: + str->set_ascii(STRING_WITH_LEN("blob")); + break; + + case 3: str->set_ascii(STRING_WITH_LEN("mediumblob")); break; - case MYSQL_TYPE_LONG_BLOB: + case 4: str->set_ascii(STRING_WITH_LEN("longblob")); break; - case MYSQL_TYPE_BLOB: - str->set_ascii(STRING_WITH_LEN("blob")); - break; - default: DBUG_ASSERT(0); break; @@ -509,9 +512,13 @@ void show_sql_type(enum_field_types type, uint16 metadata, String *str, CHARSET_ */ CHARSET_INFO *cs= str->charset(); uint bytes= (((metadata >> 4) & 0x300) ^ 0x300) + (metadata & 0x00ff); - size_t length= - cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), - "char(%d)", bytes / field_cs->mbmaxlen); + size_t length=0; + if (char_with_octets) + length= cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), + "char(%u octets)", bytes); + else + length= cs->cset->snprintf(cs, (char*) str->ptr(), str->alloced_length(), + "binary(%u)", bytes); str->length(length); } break; @@ -948,9 +955,13 @@ table_def::compatible_with(THD *thd, rpl_group_info *rgi, String source_type(source_buf, sizeof(source_buf), &my_charset_latin1); String target_type(target_buf, sizeof(target_buf), &my_charset_latin1); THD *thd= table->in_use; + bool char_with_octets= field->cmp_type() == STRING_RESULT ? + field->has_charset() : true; + + show_sql_type(type(col), field_metadata(col), &source_type, + char_with_octets); + field->sql_rpl_type(&target_type); - show_sql_type(type(col), field_metadata(col), &source_type, field->charset()); - field->sql_type(target_type); rli->report(ERROR_LEVEL, ER_SLAVE_CONVERSION_FAILED, rgi->gtid_info(), ER_THD(thd, ER_SLAVE_CONVERSION_FAILED), col, db_name, tbl_name, diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 99af1c60287..b6cd8e6487d 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -6461,7 +6461,7 @@ ER_MESSAGE_AND_STATEMENT eng "%s Statement: %s" ER_SLAVE_CONVERSION_FAILED - eng "Column %d of table '%-.192s.%-.192s' cannot be converted from type '%-.32s' to type '%-.32s'" + eng "Column %d of table '%-.192s.%-.192s' cannot be converted from type '%-.50s' to type '%-.50s'" ER_SLAVE_CANT_CREATE_CONVERSION eng "Can't create conversion table for table '%-.192s.%-.192s'" ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 0f71f372323..cfc8acbfb2f 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -6291,9 +6291,6 @@ lock_trx_release_locks( /*--------------------------------------*/ trx_mutex_enter(trx); trx->state = TRX_STATE_COMMITTED_IN_MEMORY; - /* Ensure that rw_trx_hash_t::find() will no longer find - this transaction. */ - trx->id = 0; trx_mutex_exit(trx); /*--------------------------------------*/ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 723e8458c6d..2eb3161f3b7 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -492,6 +492,7 @@ trx_free_at_shutdown(trx_t *trx) transaction was never committed and therefore lock_trx_release() was not called. */ trx->lock.table_locks.clear(); + trx->id = 0; trx_free(trx); } @@ -1333,10 +1334,8 @@ trx_commit_in_memory( trx_sys.deregister_rw(trx); } - /* trx->id will be cleared in lock_trx_release_locks(trx). */ - ut_ad(trx->read_only || !trx->rsegs.m_redo.rseg || trx->id); lock_trx_release_locks(trx); - ut_ad(trx->id == 0); + ut_ad(trx->read_only || !trx->rsegs.m_redo.rseg || trx->id); /* Remove the transaction from the list of active transactions now that it no longer holds any user locks. */ @@ -1350,6 +1349,8 @@ trx_commit_in_memory( trx_update_mod_tables_timestamp(trx); MONITOR_INC(MONITOR_TRX_RW_COMMIT); } + + trx->id = 0; } ut_ad(!trx->rsegs.m_redo.undo); diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_master_tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_master_tokudb.result index cca18c7c1ab..6982078d2b8 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_master_tokudb.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_master_tokudb.result @@ -468,7 +468,7 @@ INSERT INTO t10 () VALUES(1,@b1,DEFAULT,'Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'double' to type 'char(5 octets) character set latin1'' *** Drop t10 *** connection master; @@ -510,7 +510,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Testing is fun','Kyle',DEFAULT), connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'tinyblob' to type 'varchar(254)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'blob' to type 'varchar(254 octets) character set latin1'' *** Drop t11 *** connection master; diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_slave_tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_slave_tokudb.result index 8906cf31d74..318d5496255 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_slave_tokudb.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_extra_col_slave_tokudb.result @@ -64,7 +64,7 @@ a b c connection slave; START SLAVE; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10)' to type 'char(5)'' +Last_SQL_Error = 'Column 2 of table 'test.t2' cannot be converted from type 'char(10 octets)' to type 'char(5 octets) character set latin1'' STOP SLAVE; RESET SLAVE; SELECT * FROM t2 ORDER BY a; @@ -102,7 +102,7 @@ INSERT INTO t3 () VALUES(@b1,2,'Kyle, TEX'),(@b1,1,'JOE AUSTIN'),(@b1,4,'QA TEST ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'tinyblob' to type 'int(11)'' +Last_SQL_Error = 'Column 0 of table 'test.t3' cannot be converted from type 'blob' to type 'int(11)'' *** Drop t3 *** connection master; DROP TABLE t3; @@ -160,7 +160,7 @@ INSERT INTO t5 () VALUES(1,'Kyle',200.23,1,'b1b1',23.00098), ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t5 *** connection master; DROP TABLE t5; @@ -188,7 +188,7 @@ INSERT INTO t6 () VALUES(1,'Kyle',200.23,1), ******************************************** connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6)' to type 'char(5)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'varchar(6 octets)' to type 'char(5 octets) character set latin1'' *** Drop t6 *** include/rpl_reset.inc connection master; @@ -310,7 +310,7 @@ INSERT INTO t10 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5)' to type 'double'' +Last_SQL_Error = 'Column 2 of table 'test.t10' cannot be converted from type 'char(5 octets)' to type 'double'' *** Drop t10 *** connection master; DROP TABLE t10; @@ -338,7 +338,7 @@ INSERT INTO t11 () VALUES(1,@b1,'Kyle'),(2,@b1,'JOE'),(3,@b1,'QA'); ******************************************** connection slave; include/wait_for_slave_sql_error_and_skip.inc [errno=1677] -Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254)' to type 'int(11)'' +Last_SQL_Error = 'Column 2 of table 'test.t11' cannot be converted from type 'varchar(254 octets)' to type 'int(11)'' *** Drop t11 *** connection master; DROP TABLE t11; diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_row_basic_3tokudb.result b/storage/tokudb/mysql-test/rpl/r/rpl_row_basic_3tokudb.result index 32a42143180..e638a1aab12 100644 --- a/storage/tokudb/mysql-test/rpl/r/rpl_row_basic_3tokudb.result +++ b/storage/tokudb/mysql-test/rpl/r/rpl_row_basic_3tokudb.result @@ -565,7 +565,7 @@ INSERT INTO t5 VALUES (1, "", 1); INSERT INTO t5 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(255)' to type 'char(16)'' +Last_SQL_Error = 'Column 1 of table 'test.t5' cannot be converted from type 'char(765 octets)' to type 'char(48 octets) character set utf8'' include/rpl_reset.inc [expecting slave to stop] connection master; @@ -573,7 +573,7 @@ INSERT INTO t6 VALUES (1, "", 1); INSERT INTO t6 VALUES (2, repeat(_utf8'a', 255), 2); connection slave; include/wait_for_slave_sql_error.inc [errno=1677] -Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(255)' to type 'char(128)'' +Last_SQL_Error = 'Column 1 of table 'test.t6' cannot be converted from type 'char(765 octets)' to type 'char(384 octets) character set utf8'' include/rpl_reset.inc [expecting slave to replicate correctly] connection master;