From: Date: August 10 2007 3:09am Subject: bk commit into 5.1 tree (cbell:1.2548) BUG#22086 List-Archive: http://lists.mysql.com/commits/32342 Message-Id: <200708100109.l7A19BKq027289@mail.mysql.com> Below is the list of changes that have just been committed into a local 5.1 repository of cbell. When cbell 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-08-09 21:08:58-04:00, cbell@mysql_cab_desk. +11 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash This patch adds functionality to row-based replication to ensure the slave's column sizes are >= to that of the master. It also includes some refactoring for the code from WL#3228. mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test@stripped, 2007-08-09 21:08:14-04:00, Chuck@mysql_cab_desk. +41 -32 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash Removed commented out portion of test referenced in bug report. This test supports the original request of the bug report. mysql-test/include/test_fieldsize.inc@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +40 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash Sub unit file to test each variable type that relies on field metadata from the master. mysql-test/include/test_fieldsize.inc@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +0 -0 mysql-test/suite/rpl/r/rpl_extraCol_innodb.result@stripped, 2007-08-09 21:08:14-04:00, Chuck@mysql_cab_desk. +67 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash New result file for additional test. mysql-test/suite/rpl/r/rpl_extraCol_myisam.result@stripped, 2007-08-09 21:08:15-04:00, Chuck@mysql_cab_desk. +67 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash New result file for additional test. mysql-test/suite/rpl/r/rpl_row_colSize.result@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +646 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash New result file for additional test. mysql-test/suite/rpl/r/rpl_row_colSize.result@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +0 -0 mysql-test/suite/rpl/t/rpl_row_colSize.test@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +158 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash Added a test file to test each variable type that relies on field metadata from the master. mysql-test/suite/rpl/t/rpl_row_colSize.test@stripped, 2007-08-09 21:08:18-04:00, Chuck@mysql_cab_desk. +0 -0 mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result@stripped, 2007-08-09 21:08:15-04:00, Chuck@mysql_cab_desk. +67 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash New result file for additional test. sql/field.cc@stripped, 2007-08-09 21:08:16-04:00, Chuck@mysql_cab_desk. +220 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash This patch refactors the additions made by this bug patch and those made by WL#3228. The effort consolidates the large switches on type() into functions within the field classes. sql/field.h@stripped, 2007-08-09 21:08:16-04:00, Chuck@mysql_cab_desk. +39 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash This patch refactors the additions made by this bug patch and those made by WL#3228. The effort consolidates the large switches on type() into functions within the field classes. sql/log_event.cc@stripped, 2007-08-09 21:08:17-04:00, Chuck@mysql_cab_desk. +12 -91 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash This patch refactors the calc_field_size() method to use the new methods implemented in the field classes. It also corrects comments concerning how replication of field metadata works. sql/rpl_utility.cc@stripped, 2007-08-09 21:08:17-04:00, Chuck@mysql_cab_desk. +19 -0 BUG#22086 : Extra Slave Col: Char(5) on slave and Char(10) on master cause mysqld crash This patch adds a method to check the size of the field on the master using the field metadata from WL#3228. Each column is checked to ensure the slave's column is >= to the master's column in size. diff -Nrup a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test --- a/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test 2007-06-12 23:50:32 -04:00 +++ b/mysql-test/extra/rpl_tests/rpl_extraSlave_Col.test 2007-08-09 21:08:14 -04:00 @@ -71,38 +71,47 @@ sync_slave_with_master; ############################################ ## BUG22086 -#--echo *** Create t2 on slave *** -#STOP SLAVE; -#RESET SLAVE; -#eval CREATE TABLE t2 (a INT, b INT PRIMARY KEY, c CHAR(5), -# d FLOAT DEFAULT '2.00', -# e CHAR(5) DEFAULT 'TEST2') -# ENGINE=$engine_type; -# -#--echo *** Create t2 on Master *** -#connection master; -#eval CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(10) -# ) ENGINE=$engine_type; -#RESET MASTER; -# -#--echo *** Start Slave *** -#connection slave; -#START SLAVE; -# -#--echo *** Master Data Insert *** -#connection master; -# -#INSERT INTO t2 () VALUES(1,2,'Kyle, TEX'),(2,1,'JOE AUSTIN'),(3,4,'QA TESTING'); -#SELECT * FROM t2 ORDER BY a; - -#--echo *** Select from slave *** -#sync_slave_with_master; -#SELECT * FROM t2 ORDER BY a; - -#--echo *** Drop t2 *** -#connection master; -#DROP TABLE t2; -#sync_slave_with_master; +--echo *** Create t2 on slave *** +STOP SLAVE; +RESET SLAVE; +eval CREATE TABLE t2 (a INT, b INT PRIMARY KEY, c CHAR(5), + d FLOAT DEFAULT '2.00', + e CHAR(5) DEFAULT 'TEST2') + ENGINE=$engine_type; + +--echo *** Create t2 on Master *** +connection master; +eval CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(10) + ) ENGINE=$engine_type; +RESET MASTER; + +--echo *** Master Data Insert *** +connection master; + +INSERT INTO t2 () VALUES(1,2,'Kyle, TEX'),(2,1,'JOE AUSTIN'),(3,4,'QA TESTING'); +SELECT * FROM t2 ORDER BY a; + +--echo *** Start Slave *** +connection slave; +START SLAVE; +wait_for_slave_to_stop; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS +STOP SLAVE; +RESET SLAVE; +SELECT * FROM t2 ORDER BY a; + +connection master; +RESET MASTER; + +connection slave; +START SLAVE; + +--echo *** Drop t2 *** +connection master; +DROP TABLE t2; +sync_slave_with_master; #################################### ### Try to replicate BLOB to INT ### diff -Nrup a/mysql-test/include/test_fieldsize.inc b/mysql-test/include/test_fieldsize.inc --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/mysql-test/include/test_fieldsize.inc 2007-08-09 21:08:18 -04:00 @@ -0,0 +1,40 @@ +# +# include/test_fieldsize.inc +# +# This include file is designed to create a table with one column +# whose size on the master is greater than that on the slave. The +# test should fail with an error on the slave. +# + +connection master; +DROP TABLE IF EXISTS t1; + +sync_slave_with_master; +STOP SLAVE; +RESET SLAVE; +eval $test_table_slave; + +connection master; +eval $test_table_master; +RESET MASTER; + +eval $test_insert; + +connection slave; +START SLAVE; +wait_for_slave_to_stop; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS + +# The following should be 0 +SELECT COUNT(*) FROM t1; +STOP SLAVE; +RESET SLAVE; + +connection master; +RESET MASTER; + +connection slave; +START SLAVE; + diff -Nrup a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result --- a/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result 2007-07-09 04:54:16 -04:00 +++ b/mysql-test/suite/rpl/r/rpl_extraCol_innodb.result 2007-08-09 21:08:14 -04:00 @@ -33,6 +33,73 @@ a b c d e 3 4 QA 2 TEST *** Drop t1 *** DROP TABLE t1; +*** Create t2 on slave *** +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t2 (a INT, b INT PRIMARY KEY, c CHAR(5), +d FLOAT DEFAULT '2.00', +e CHAR(5) DEFAULT 'TEST2') +ENGINE='InnoDB'; +*** Create t2 on Master *** +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(10) +) ENGINE='InnoDB'; +RESET MASTER; +*** Master Data Insert *** +INSERT INTO t2 () VALUES(1,2,'Kyle, TEX'),(2,1,'JOE AUSTIN'),(3,4,'QA TESTING'); +SELECT * FROM t2 ORDER BY a; +a b c +1 2 Kyle, TEX +2 1 JOE AUSTIN +3 4 QA TESTING +*** Start Slave *** +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size. +STOP SLAVE; +RESET SLAVE; +SELECT * FROM t2 ORDER BY a; +a b c d e +RESET MASTER; +START SLAVE; +*** Drop t2 *** +DROP TABLE t2; *** Create t3 on slave *** STOP SLAVE; RESET SLAVE; diff -Nrup a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result --- a/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result 2007-07-09 04:54:16 -04:00 +++ b/mysql-test/suite/rpl/r/rpl_extraCol_myisam.result 2007-08-09 21:08:15 -04:00 @@ -33,6 +33,73 @@ a b c d e 3 4 QA 2 TEST *** Drop t1 *** DROP TABLE t1; +*** Create t2 on slave *** +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t2 (a INT, b INT PRIMARY KEY, c CHAR(5), +d FLOAT DEFAULT '2.00', +e CHAR(5) DEFAULT 'TEST2') +ENGINE='MyISAM'; +*** Create t2 on Master *** +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(10) +) ENGINE='MyISAM'; +RESET MASTER; +*** Master Data Insert *** +INSERT INTO t2 () VALUES(1,2,'Kyle, TEX'),(2,1,'JOE AUSTIN'),(3,4,'QA TESTING'); +SELECT * FROM t2 ORDER BY a; +a b c +1 2 Kyle, TEX +2 1 JOE AUSTIN +3 4 QA TESTING +*** Start Slave *** +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6. Master's column size should be <= the slave's column size. +STOP SLAVE; +RESET SLAVE; +SELECT * FROM t2 ORDER BY a; +a b c d e +RESET MASTER; +START SLAVE; +*** Drop t2 *** +DROP TABLE t2; *** Create t3 on slave *** STOP SLAVE; RESET SLAVE; diff -Nrup a/mysql-test/suite/rpl/r/rpl_row_colSize.result b/mysql-test/suite/rpl/r/rpl_row_colSize.result --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/mysql-test/suite/rpl/r/rpl_row_colSize.result 2007-08-09 21:08:18 -04:00 @@ -0,0 +1,646 @@ +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; +DROP TABLE IF EXISTS t1; +**** Testing WL#3228 changes. **** +*** Create "wider" table on slave *** +Checking MYSQL_TYPE_NEWDECIMAL fields +DROP TABLE IF EXISTS t1; +Warnings: +Note 1051 Unknown table 't1' +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a DECIMAL(5,2)); +CREATE TABLE t1 (a DECIMAL(20, 10)); +RESET MASTER; +INSERT INTO t1 VALUES (901251.90125); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a NUMERIC(5,2)); +CREATE TABLE t1 (a NUMERIC(20, 10)); +RESET MASTER; +INSERT INTO t1 VALUES (901251.90125); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 10, test.t1 on slave has size 3. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_FLOAT fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a FLOAT(20)); +CREATE TABLE t1 (a FLOAT(47)); +RESET MASTER; +INSERT INTO t1 VALUES (901251.90125); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 5, test.t1 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 type mismatch - received type 5, test.t1 has type 4 +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_BIT fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a BIT(5)); +CREATE TABLE t1 (a BIT(64)); +RESET MASTER; +INSERT INTO t1 VALUES (B'10101'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 8, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 8, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_SET fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a SET('4')); +CREATE TABLE t1 (a SET('1','2','3','4','5','6','7','8','9')); +RESET MASTER; +INSERT INTO t1 VALUES ('4'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_STRING fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a CHAR(10)); +CREATE TABLE t1 (a CHAR(20)); +RESET MASTER; +INSERT INTO t1 VALUES ('This is a test.'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 20, test.t1 on slave has size 11. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 20, test.t1 on slave has size 11. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_ENUM fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a ENUM('44','54')); +CREATE TABLE t1 (a ENUM( +'01','02','03','04','05','06','07','08','09', +'11','12','13','14','15','16','17','18','19', +'21','22','23','24','25','26','27','28','29', +'31','32','33','34','35','36','37','38','39', +'41','42','43','44','45','46','47','48','49', +'51','52','53','54','55','56','57','58','59', +'61','62','63','64','65','66','67','68','69', +'71','72','73','74','75','76','77','78','79', +'81','82','83','84','85','86','87','88','89', +'91','92','93','94','95','96','97','98','99', +'101','102','103','104','105','106','107','108','109', +'111','112','113','114','115','116','117','118','119', +'121','122','123','124','125','126','127','128','129', +'131','132','133','134','135','136','137','138','139', +'141','142','143','144','145','146','147','148','149', +'151','152','153','154','155','156','157','158','159', +'161','162','163','164','165','166','167','168','169', +'171','172','173','174','175','176','177','178','179', +'181','182','183','184','185','186','187','188','189', +'191','192','193','194','195','196','197','198','199', +'201','202','203','204','205','206','207','208','209', +'211','212','213','214','215','216','217','218','219', +'221','222','223','224','225','226','227','228','229', +'231','232','233','234','235','236','237','238','239', +'241','242','243','244','245','246','247','248','249', +'251','252','253','254','255','256','257','258','259', +'261','262','263','264','265','266','267','268','269', +'271','272','273','274','275','276','277','278','279', +'281','282','283','284','285','286','287','288','289', +'291','292','293','294','295','296','297','298','299' + )); +RESET MASTER; +INSERT INTO t1 VALUES ('44'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_VARCHAR fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a VARCHAR(100)); +CREATE TABLE t1 (a VARCHAR(2000)); +RESET MASTER; +INSERT INTO t1 VALUES ('This is a test.'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 100. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 100. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a VARCHAR(10)); +CREATE TABLE t1 (a VARCHAR(200)); +RESET MASTER; +INSERT INTO t1 VALUES ('This is a test.'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 200, test.t1 on slave has size 10. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 200, test.t1 on slave has size 10. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a VARCHAR(1000)); +CREATE TABLE t1 (a VARCHAR(2000)); +RESET MASTER; +INSERT INTO t1 VALUES ('This is a test.'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 1000. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 2000, test.t1 on slave has size 1000. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +Checking MYSQL_TYPE_BLOB fields +DROP TABLE IF EXISTS t1; +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t1 (a TINYBLOB); +CREATE TABLE t1 (a LONGBLOB); +RESET MASTER; +INSERT INTO t1 VALUES ('This is a test.'); +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 4, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 0 size mismatch - master has size 4, test.t1 on slave has size 1. Master's column size should be <= the slave's column size. +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +STOP SLAVE; +RESET SLAVE; +RESET MASTER; +START SLAVE; +*** Cleanup *** +DROP TABLE IF EXISTS t1; diff -Nrup a/mysql-test/suite/rpl/t/rpl_row_colSize.test b/mysql-test/suite/rpl/t/rpl_row_colSize.test --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/mysql-test/suite/rpl/t/rpl_row_colSize.test 2007-08-09 21:08:18 -04:00 @@ -0,0 +1,158 @@ +################################################################## +# rpl_colSize # +# # +# This test is designed to test the changes included in WL#3228. # +# The changes include the ability to replicate with the master # +# having columns that are smaller (shorter) than the slave. # +################################################################## + +-- source include/master-slave.inc +-- source include/have_binlog_format_row.inc + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + + +--echo **** Testing WL#3228 changes. **** +--echo *** Create "wider" table on slave *** +sync_slave_with_master; + +# +# Check each column type to verify error 1532 fires (BUG#22086) +# This check covers only those fields that require additional +# metadata from the master to be replicated to the slave. These +# field types are: +# MYSQL_TYPE_NEWDECIMAL: +# MYSQL_TYPE_FLOAT: +# MYSQL_TYPE_BIT: +# MYSQL_TYPE_SET: +# MYSQL_TYPE_STRING: +# MYSQL_TYPE_ENUM: +# MYSQL_TYPE_VARCHAR: +# MYSQL_TYPE_BLOB: + +# +# Test: Checking MYSQL_TYPE_NEWDECIMAL fields +# +--echo Checking MYSQL_TYPE_NEWDECIMAL fields +let $test_table_master = CREATE TABLE t1 (a DECIMAL(20, 10)); +let $test_table_slave = CREATE TABLE t1 (a DECIMAL(5,2)); +let $test_insert = INSERT INTO t1 VALUES (901251.90125); +source include/test_fieldsize.inc; + +let $test_table_master = CREATE TABLE t1 (a NUMERIC(20, 10)); +let $test_table_slave = CREATE TABLE t1 (a NUMERIC(5,2)); +let $test_insert = INSERT INTO t1 VALUES (901251.90125); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_FLOAT fields +# +--echo Checking MYSQL_TYPE_FLOAT fields +let $test_table_master = CREATE TABLE t1 (a FLOAT(47)); +let $test_table_slave = CREATE TABLE t1 (a FLOAT(20)); +let $test_insert = INSERT INTO t1 VALUES (901251.90125); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_BIT fields +# +--echo Checking MYSQL_TYPE_BIT fields +let $test_table_master = CREATE TABLE t1 (a BIT(64)); +let $test_table_slave = CREATE TABLE t1 (a BIT(5)); +let $test_insert = INSERT INTO t1 VALUES (B'10101'); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_SET fields +# +--echo Checking MYSQL_TYPE_SET fields +let $test_table_master = CREATE TABLE t1 (a SET('1','2','3','4','5','6','7','8','9')); +let $test_table_slave = CREATE TABLE t1 (a SET('4')); +let $test_insert = INSERT INTO t1 VALUES ('4'); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_STRING fields +# +--echo Checking MYSQL_TYPE_STRING fields +let $test_table_master = CREATE TABLE t1 (a CHAR(20)); +let $test_table_slave = CREATE TABLE t1 (a CHAR(10)); +let $test_insert = INSERT INTO t1 VALUES ('This is a test.'); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_ENUM fields +# +--echo Checking MYSQL_TYPE_ENUM fields +let $test_table_master = CREATE TABLE t1 (a ENUM( + '01','02','03','04','05','06','07','08','09', + '11','12','13','14','15','16','17','18','19', + '21','22','23','24','25','26','27','28','29', + '31','32','33','34','35','36','37','38','39', + '41','42','43','44','45','46','47','48','49', + '51','52','53','54','55','56','57','58','59', + '61','62','63','64','65','66','67','68','69', + '71','72','73','74','75','76','77','78','79', + '81','82','83','84','85','86','87','88','89', + '91','92','93','94','95','96','97','98','99', + '101','102','103','104','105','106','107','108','109', + '111','112','113','114','115','116','117','118','119', + '121','122','123','124','125','126','127','128','129', + '131','132','133','134','135','136','137','138','139', + '141','142','143','144','145','146','147','148','149', + '151','152','153','154','155','156','157','158','159', + '161','162','163','164','165','166','167','168','169', + '171','172','173','174','175','176','177','178','179', + '181','182','183','184','185','186','187','188','189', + '191','192','193','194','195','196','197','198','199', + '201','202','203','204','205','206','207','208','209', + '211','212','213','214','215','216','217','218','219', + '221','222','223','224','225','226','227','228','229', + '231','232','233','234','235','236','237','238','239', + '241','242','243','244','245','246','247','248','249', + '251','252','253','254','255','256','257','258','259', + '261','262','263','264','265','266','267','268','269', + '271','272','273','274','275','276','277','278','279', + '281','282','283','284','285','286','287','288','289', + '291','292','293','294','295','296','297','298','299' + )); +let $test_table_slave = CREATE TABLE t1 (a ENUM('44','54')); +let $test_insert = INSERT INTO t1 VALUES ('44'); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_VARCHAR fields +# +--echo Checking MYSQL_TYPE_VARCHAR fields +let $test_table_master = CREATE TABLE t1 (a VARCHAR(2000)); +let $test_table_slave = CREATE TABLE t1 (a VARCHAR(100)); +let $test_insert = INSERT INTO t1 VALUES ('This is a test.'); +source include/test_fieldsize.inc; + +let $test_table_master = CREATE TABLE t1 (a VARCHAR(200)); +let $test_table_slave = CREATE TABLE t1 (a VARCHAR(10)); +let $test_insert = INSERT INTO t1 VALUES ('This is a test.'); +source include/test_fieldsize.inc; + +let $test_table_master = CREATE TABLE t1 (a VARCHAR(2000)); +let $test_table_slave = CREATE TABLE t1 (a VARCHAR(1000)); +let $test_insert = INSERT INTO t1 VALUES ('This is a test.'); +source include/test_fieldsize.inc; + +# +# Test: Checking MYSQL_TYPE_BLOB fields +# +--echo Checking MYSQL_TYPE_BLOB fields +let $test_table_master = CREATE TABLE t1 (a LONGBLOB); +let $test_table_slave = CREATE TABLE t1 (a TINYBLOB); +let $test_insert = INSERT INTO t1 VALUES ('This is a test.'); +source include/test_fieldsize.inc; + +--echo *** Cleanup *** +connection master; +DROP TABLE IF EXISTS t1; +sync_slave_with_master; +# END 5.1 Test Case + diff -Nrup a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result 2007-07-09 04:54:16 -04:00 +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_extraCol.result 2007-08-09 21:08:15 -04:00 @@ -33,6 +33,73 @@ a b c d e 3 4 QA NULL NULL *** Drop t1 *** DROP TABLE t1; +*** Create t2 on slave *** +STOP SLAVE; +RESET SLAVE; +CREATE TABLE t2 (a INT, b INT PRIMARY KEY, c CHAR(5), +d FLOAT DEFAULT '2.00', +e CHAR(5) DEFAULT 'TEST2') +ENGINE='NDB'; +*** Create t2 on Master *** +CREATE TABLE t2 (a INT PRIMARY KEY, b INT, c CHAR(10) +) ENGINE='NDB'; +RESET MASTER; +*** Master Data Insert *** +INSERT INTO t2 () VALUES(1,2,'Kyle, TEX'),(2,1,'JOE AUSTIN'),(3,4,'QA TESTING'); +SELECT * FROM t2 ORDER BY a; +a b c +1 2 Kyle, TEX +2 1 JOE AUSTIN +3 4 QA TESTING +*** Start Slave *** +START SLAVE; +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port # +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1532 +Last_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +Master_SSL_Verify_Server_Cert No +Last_IO_Errno 0 +Last_IO_Error +Last_SQL_Errno 1532 +Last_SQL_Error Table definition on master and slave does not match: Column 2 size mismatch - master has size 10, test.t2 on slave has size 6 +STOP SLAVE; +RESET SLAVE; +SELECT * FROM t2 ORDER BY a; +a b c d e +RESET MASTER; +START SLAVE; +*** Drop t2 *** +DROP TABLE t2; *** Create t3 on slave *** STOP SLAVE; RESET SLAVE; diff -Nrup a/sql/field.cc b/sql/field.cc --- a/sql/field.cc 2007-07-29 18:10:23 -04:00 +++ b/sql/field.cc 2007-08-09 21:08:16 -04:00 @@ -1360,6 +1360,27 @@ bool Field::send_binary(Protocol *protoc } +/** + Check to see if field size is compatible with destination. + + This method is used in row-based replication to verify that the slave's + field size is less than or equal to the master's field size. The + encoded field metadata (from the master or source) is decoded and compared + to the size of this field (the slave or destination). + + @param field_metadata Encoded size in field metadata + + @returns 0 if this field's size is < the source field's size + @returns 1 if this field's size is >= the source field's size +*/ +int Field::compatible_field_size(uint field_metadata) +{ + uint const source_size= pack_length_from_metadata(field_metadata); + uint const destination_size= row_pack_length(); + return (source_size <= destination_size); +} + + int Field::store(const char *to, uint length, CHARSET_INFO *cs, enum_check_fields check_level) { @@ -2690,6 +2711,47 @@ void Field_new_decimal::sql_type(String } +/** + Retrieve the field metadata for new decimal fields. + + Saves the precision in the first byte and decimals() in the second. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_new_decimal::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)precision; + *second_byte= (uchar)decimals(); + return 0; +} + + +/** + Returns the number of bytes field uses in row-based replication + row packed size. + + This method is used in row-based replication to determine the number + of bytes that the field consumes in the row record format. This is + used to skip fields in the master that do not exist on the slave. + + @param field_metadata Encoded size in field metadata + + @retval The size of the field based on the field metadata. +*/ +uint Field_new_decimal::pack_length_from_metadata(uint field_metadata) +{ + uint const source_precision= (field_metadata >> 8U) & 0x00ff; + uint const source_decimal= field_metadata & 0x00ff; + uint const source_size= my_decimal_get_binary_size(source_precision, + source_decimal); + return (source_size); +} + + uint Field_new_decimal::is_equal(Create_field *new_field) { return ((new_field->sql_type == real_type()) && @@ -4087,6 +4149,25 @@ bool Field_float::send_binary(Protocol * } +/** + Retrieve the field metadata for float fields. + + Saves the pack length in the first byte. + The second byte is not used. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_float::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)pack_length(); + return 0; +} + + void Field_float::sql_type(String &res) const { if (dec == NOT_FIXED_DEC) @@ -4404,6 +4485,25 @@ void Field_double::sort_string(uchar *to } +/** + Retrieve the field metadata for double fields. + + Saves the pack length in the first byte. + The second byte is not used. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_double::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)pack_length(); + return 0; +} + + void Field_double::sql_type(String &res) const { CHARSET_INFO *cs=res.charset(); @@ -6445,6 +6545,26 @@ const uchar *Field_string::unpack(uchar } +/** + Retrieve the field metadata for string fields. + + Saves the real type in the first byte and the field length in the + second byte. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_string::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)real_type(); + *second_byte= (uchar)field_length; + return 0; +} + + /* Compare two packed keys @@ -6597,6 +6717,26 @@ Field *Field_string::new_field(MEM_ROOT const uint Field_varstring::MAX_SIZE= UINT_MAX16; +/** + Retrieve the field metadata for varstring fields. + + Saves the field length in the first byte. Note: may consume + 2 bytes. Caller must ensure second byte is contiguous with + first byte (e.g. array index 0,1). + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_varstring::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + char *ptr= (char *)first_byte; + int2store(ptr, field_length); + return 0; +} + int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) { ASSERT_COLUMN_MARKED_FOR_WRITE; @@ -7560,6 +7700,25 @@ int Field_blob::key_cmp(const uchar *a,c } +/** + Retrieve the field metadata for blob fields. + + Saves the pack length without the pointer in the first byte. + The second byte is not used. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_blob::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)pack_length_no_ptr(); + return 0; +} + + uint32 Field_blob::sort_length() const { return (uint32) (current_thd->variables.max_sort_length + @@ -8145,6 +8304,26 @@ longlong Field_enum::val_int(void) } +/** + Retrieve the field metadata for enum fields. + + Saves the real type in the first byte and the pack length in the + second byte. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_enum::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)real_type(); + *second_byte= (uchar)pack_length(); + return 0; +} + + String *Field_enum::val_str(String *val_buffer __attribute__((unused)), String *val_ptr) { @@ -8678,6 +8857,47 @@ uint Field_bit::get_key_image(uchar *buf uint data_length = min(length, bytes_in_rec); memcpy(buff, ptr, data_length); return data_length + 1; +} + + +/** + Retrieve the field metadata for bit fields. + + Saves the bit length in the first byte and the bytes in rec in the + second byte. + + @param first_byte First byte of field metadata + @param second_byte Second byte of field metadata + + @returns 0 success +*/ +int Field_bit::save_field_metadata(uchar *first_byte, + uchar *second_byte) +{ + *first_byte= (uchar)bit_len; + *second_byte= (uchar)bytes_in_rec; + return 0; +} + + +/** + Returns the number of bytes field uses in row-based replication + row packed size. + + This method is used in row-based replication to determine the number + of bytes that the field consumes in the row record format. This is + used to skip fields in the master that do not exist on the slave. + + @param field_metadata Encoded size in field metadata + + @retval The size of the field based on the field metadata. +*/ +uint Field_bit::pack_length_from_metadata(uint field_metadata) +{ + uint const from_len= (field_metadata >> 8U) & 0x00ff; + uint const from_bit_len= field_metadata & 0x00ff; + uint const source_size= from_len + ((from_bit_len > 0) ? 1 : 0); + return (source_size); } diff -Nrup a/sql/field.h b/sql/field.h --- a/sql/field.h 2007-07-29 18:10:24 -04:00 +++ b/sql/field.h 2007-08-09 21:08:16 -04:00 @@ -151,6 +151,13 @@ public: table, which is located on disk). */ virtual uint32 pack_length_in_rec() const { return pack_length(); } + virtual int field_metadata_size() const { return 0; } + virtual int save_field_metadata(uchar *first_byte, uchar *second_byte) + { return 0; } + virtual int compatible_field_size(uint field_metadata); + virtual uint pack_length_from_metadata(uint field_metadata) + { return field_metadata; } + virtual uint row_pack_length() { return 0; } /* data_length() return the "real size" of the data in memory. @@ -628,6 +635,10 @@ public: uint32 max_display_length() { return field_length; } uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } + int field_metadata_size() const { return 2; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint pack_length_from_metadata(uint field_metadata); + uint row_pack_length() { return pack_length(); } uint is_equal(Create_field *new_field); virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); }; @@ -834,6 +845,9 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(float); } + int field_metadata_size() const { return 1; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint row_pack_length() { return pack_length(); } void sql_type(String &str) const; }; @@ -871,6 +885,9 @@ public: int cmp(const uchar *,const uchar *); void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(double); } + int field_metadata_size() const { return 1; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint row_pack_length() { return pack_length(); } void sql_type(String &str) const; }; @@ -1168,6 +1185,11 @@ public: uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); const uchar *unpack(uchar* to, const uchar *from); + int field_metadata_size() const { return 2; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint pack_length_from_metadata(uint field_metadata) + { return (field_metadata & 0x00ff); } + uint row_pack_length() { return (field_length + 1); } int pack_cmp(const uchar *a,const uchar *b,uint key_length, my_bool insert_or_update); int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update); @@ -1214,6 +1236,9 @@ public: enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } enum ha_base_keytype key_type() const; + int field_metadata_size() const { return 2; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint row_pack_length() { return field_length; } bool zero_pack() const { return 0; } int reset(void) { bzero(ptr,field_length+length_bytes); return 0; } uint32 pack_length() const { return (uint32) field_length+length_bytes; } @@ -1334,6 +1359,9 @@ public: */ uint32 pack_length_no_ptr() const { return (uint32) (packlength); } + int field_metadata_size() const { return 1; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint row_pack_length() { return pack_length_no_ptr(); } uint32 sort_length() const; inline uint32 max_data_length() const { @@ -1493,6 +1521,11 @@ public: void sql_type(String &str) const; uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_ENUM; } + int field_metadata_size() const { return 2; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint pack_length_from_metadata(uint field_metadata) + { return (field_metadata & 0x00ff); } + uint row_pack_length() { return pack_length(); } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } bool eq_def(Field *field); @@ -1519,6 +1552,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr) { return Field_set::store((longlong) nr, FALSE); } int store(longlong nr, bool unsigned_val); + virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; @@ -1582,6 +1616,11 @@ public: { get_key_image(buff, length, itRAW); } uint32 pack_length() const { return (uint32) (field_length + 7) / 8; } uint32 pack_length_in_rec() const { return bytes_in_rec; } + int field_metadata_size() const { return 2; } + int save_field_metadata(uchar *first_byte, uchar *second_byte); + uint pack_length_from_metadata(uint field_metadata); + uint row_pack_length() + { return (bytes_in_rec + ((bit_len > 0) ? 1 : 0)); } void sql_type(String &str) const; uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); diff -Nrup a/sql/log_event.cc b/sql/log_event.cc --- a/sql/log_event.cc 2007-07-30 17:39:48 -04:00 +++ b/sql/log_event.cc 2007-08-09 21:08:17 -04:00 @@ -6391,35 +6391,9 @@ void Rows_log_event::print_helper(FILE * const int Table_map_log_event::calc_field_metadata_size() { DBUG_ENTER("Table_map_log_event::calc_field_metadata_size"); - int size= 0; + m_field_metadata_size= 0; for (unsigned int i= 0 ; i < m_table->s->fields ; i++) - { - switch (m_table->s->field[i]->real_type()) { - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_FLOAT: - { - size++; // Store one byte here. - break; - } - case MYSQL_TYPE_BIT: - case MYSQL_TYPE_NEWDECIMAL: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_STRING: - case MYSQL_TYPE_VARCHAR: - case MYSQL_TYPE_SET: - { - size= size + 2; // Store short int here. - break; - } - default: - break; - } - } - m_field_metadata_size= size; + m_field_metadata_size+= m_table->s->field[i]->field_metadata_size(); DBUG_PRINT("info", ("Table_map_log_event: %d bytes in field metadata.", (int)m_field_metadata_size)); DBUG_RETURN(m_field_metadata_size); @@ -6430,15 +6404,14 @@ const int Table_map_log_event::calc_fiel @page How replication of field metadata works. When a table map is created, the master first calls - Table_map_log_event::get_field_metadata_size() which calculates how many + Table_map_log_event::calc_field_metadata_size() which calculates how many values will be in the field metadata. Only those fields that require the - extra data are added (see table above). The master then loops through all - of the fields in the table calling the method - Table_map_log_event::get_field_metadata() which returns the values for the - field that will be saved in the metadata and replicated to the slave. Once - all fields have been processed, the table map is written to the binlog - adding the size of the field metadata and the field metadata to the end of - the body of the table map. + extra data are added. The master then loops through all of the fields in + the table calling the method Table_map_log_event::save_field_metadata() + which returns the values for the field that will be saved in the metadata + and replicated to the slave. Once all fields have been processed, the table + map is written to the binlog adding the size of the field metadata and the + field metadata to the end of the body of the table map. When a table map is read on the slave, the field metadata is read from the table map and passed to the table_def class constructor which saves the @@ -6479,61 +6452,9 @@ int Table_map_log_event::save_field_meta int index= 0; for (unsigned int i= 0 ; i < m_table->s->fields ; i++) { - switch (m_table->s->field[i]->real_type()) { - case MYSQL_TYPE_NEWDECIMAL: - { - m_field_metadata[index++]= - (uchar)((Field_new_decimal *)m_table->s->field[i])->precision; - m_field_metadata[index++]= - (uchar)((Field_new_decimal *)m_table->s->field[i])->decimals(); - break; - } - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - { - m_field_metadata[index++]= - (uchar)((Field_blob *)m_table->s->field[i])->pack_length_no_ptr(); - break; - } - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_FLOAT: - { - m_field_metadata[index++]= (uchar)m_table->s->field[i]->pack_length(); - break; - } - case MYSQL_TYPE_BIT: - { - m_field_metadata[index++]= - (uchar)((Field_bit *)m_table->s->field[i])->bit_len; - m_field_metadata[index++]= - (uchar)((Field_bit *)m_table->s->field[i])->bytes_in_rec; - break; - } - case MYSQL_TYPE_VARCHAR: - { - char *ptr= (char *)&m_field_metadata[index]; - int2store(ptr, m_table->s->field[i]->field_length); - index= index + 2; - break; - } - case MYSQL_TYPE_STRING: - { - m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); - m_field_metadata[index++]= m_table->s->field[i]->field_length; - break; - } - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - { - m_field_metadata[index++]= (uchar)m_table->s->field[i]->real_type(); - m_field_metadata[index++]= m_table->s->field[i]->pack_length(); - break; - } - default: - break; - } + m_table->s->field[i]->save_field_metadata(&m_field_metadata[index], + &m_field_metadata[index+1]); + index+= m_table->s->field[i]->field_metadata_size(); } DBUG_RETURN(0); } diff -Nrup a/sql/rpl_utility.cc b/sql/rpl_utility.cc --- a/sql/rpl_utility.cc 2007-07-30 17:39:49 -04:00 +++ b/sql/rpl_utility.cc 2007-08-09 21:08:17 -04:00 @@ -156,6 +156,25 @@ table_def::compatible_with(RELAY_LOG_INF rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); } + /* + Check the slave's field size against that of the master. + */ + if (!error && + !table->field[col]->compatible_field_size(m_field_metadata[col])) + { + error= 1; + char buf[256]; + my_snprintf(buf, sizeof(buf), "Column %d size mismatch - " + "master has size %d, %s.%s on slave has size %d." + " Master's column size should be <= the slave's " + "column size.", col, + table->field[col]->pack_length_from_metadata( + m_field_metadata[col]), + tsh->db.str, tsh->table_name.str, + table->field[col]->row_pack_length()); + rli->report(ERROR_LEVEL, ER_BINLOG_ROW_WRONG_TABLE_DEF, + ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf); + } } return error;