List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:July 17 2007 2:37pm
Subject:Re: bk commit into 5.1 tree (cbell:1.2538) and wl3915 progress bar
View as plain text  
Chuck, good morning.

I have good news - my testing with all types of fields revealed only
two problems. One is with VARCHAR, i fixed it with a patch; please
find the hunk inlined further.

The second is with table_def::get_field_size
case MYSQL_TYPE_NEWDECIMAL. The length is computed as 

  switch (type(col)) {
  case MYSQL_TYPE_NEWDECIMAL:
    length= my_decimal_get_binary_size(m_field_metadata[col] >> 8, 
             m_field_metadata[col] - ((m_field_metadata[col] >> 8) << 8));

  And that is incorrect. I have a test where a field
  
        f7 DECIMAL(17,9) default '1000.00' 
  
  generates metadata 0x11 0x09 - in
  accord with the declaration - but the actual length of the extra
  data of this field is 7 not 8 as `my_decimal_get_binary_size'
  returns.
  The inserted value was the default via

       INSERT into table set f1=... and no f7=...


Similarly, 3 (wrong) versus 2 (the actual size) for explicitly inserted
      
       INSERT into table  f9='9.999'

   where f9 was declared as 
 
       f9 NUMERIC(6,4) default '2000.00'.

   the metadata in this case are: 0x06 0x04.

This shows that the current method of lenth calculation fits to the
max size values where as actual values seem to be stored somehow
more compact.

I just committed my cset for wl3915 which you can try:

subject: bk commit into 5.1 tree (aelkin:1.2540)

(how do you get url for your commits?)

Notice, that rpl_extraCol_innodb.test the only test at the moment
should not be run but rather to use tables def and inserts into the
tables.
The fragile - segfault - are inserts into table t2i where we have
DECIMAL and NUMERIC. 

> ChangeSet@stripped, 2007-07-16 16:11:30-04:00, cbell@mysql_cab_desk. +25 -0
>   WL#3228 : RBR using different table defs on slave/master
>   
>   This patch adds the ability to store extra field metadata in the table
>   map event. This data can include pack_length() or field_lenght() for
>   fields such as CHAR or VARCHAR enabling developers to add code that
>   can check for compatibilty between master and slave columns. More 
>   importantly, the extra field metadata can be used to store data from the
>   master correctly should a VARCHAR field on the master be <= 255 bytes 
>   while the same field on the slave is > 255 bytes. '
>   
>   The patch also includes the needed changes to unpack to ensure that data
>   which is smaller on the master can be unpacked correctly on the slave.
>   
>   See worklog for additional details.
>
>   mysql-test/r/rpl_colSize.result@stripped, 2007-07-16 16:11:26-04:00,
> cbell@mysql_cab_desk. +47 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch contains a result file for the new test designed to test the 
>     feature of having columns on the master that are smaller than what is 
>     on the slave. 
>     
>     Currently, the only field that does not work is BIT fields. The plan
>     is to finish that work in the course of satisfying BUG#22086. See 
>     worklog for more details.
>
>   mysql-test/r/rpl_colSize.result@stripped, 2007-07-16 16:11:26-04:00,
> cbell@mysql_cab_desk. +0 -0
>
>   mysql-test/r/rpl_ndb_log.result@stripped, 2007-07-16 16:11:15-04:00,
> cbell@mysql_cab_desk. +5 -5
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_basic_11bugs.result@stripped, 2007-07-16 16:11:15-04:00,
> cbell@mysql_cab_desk. +2 -2
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_create_table.result@stripped, 2007-07-16 16:11:16-04:00,
> cbell@mysql_cab_desk. +45 -42
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_flsh_tbls.result@stripped, 2007-07-16 16:11:16-04:00,
> cbell@mysql_cab_desk. +2 -2
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_inexist_tbl.result@stripped, 2007-07-16 16:11:17-04:00,
> cbell@mysql_cab_desk. +2 -2
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_log.result@stripped, 2007-07-16 16:11:17-04:00,
> cbell@mysql_cab_desk. +6 -6
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_log_innodb.result@stripped, 2007-07-16 16:11:18-04:00,
> cbell@mysql_cab_desk. +6 -6
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_max_relay_size.result@stripped, 2007-07-16 16:11:18-04:00,
> cbell@mysql_cab_desk. +10 -10
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_row_until.result@stripped, 2007-07-16 16:11:18-04:00,
> cbell@mysql_cab_desk. +8 -8
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_skip_error.result@stripped, 2007-07-16 16:11:19-04:00,
> cbell@mysql_cab_desk. +1 -1
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_slave_skip.result@stripped, 2007-07-16 16:11:19-04:00,
> cbell@mysql_cab_desk. +2 -2
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/r/rpl_truncate_7ndb.result@stripped, 2007-07-16 16:11:20-04:00,
> cbell@mysql_cab_desk. +32 -32
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test result to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/t/binlog_row_mix_innodb_myisam.test@stripped, 2007-07-16 16:11:20-04:00,
> cbell@mysql_cab_desk. +1 -1
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/t/rpl_colSize.test@stripped, 2007-07-16 16:11:25-04:00, cbell@mysql_cab_desk.
> +111 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch contains a new test designed to test the feature of having
>     columns on the master that are smaller than what is on the slave. 
>     
>     Currently, the only field that does not work is BIT fields. The plan
>     is to finish that work in the course of satisfying BUG#22086. See 
>     worklog for more details.
>
>   mysql-test/t/rpl_colSize.test@stripped, 2007-07-16 16:11:25-04:00, cbell@mysql_cab_desk.
> +0 -0
>
>   mysql-test/t/rpl_row_create_table.test@stripped, 2007-07-16 16:11:21-04:00,
> cbell@mysql_cab_desk. +5 -5
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test to coincide with changes to binlog
>     size of table map event.
>
>   mysql-test/t/rpl_row_flsh_tbls.test@stripped, 2007-07-16 16:11:21-04:00,
> cbell@mysql_cab_desk. +1 -1
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the test to coincide with changes to binlog
>     size of table map event.
>
>   sql/field.cc@stripped, 2007-07-16 16:11:21-04:00, cbell@mysql_cab_desk. +107 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch includes updates to the unpack() methods for the variable
>     length fields. A new parameter was added (from_length) that is the
>     value stored in the field_metadata of the table map from the table_def
>     class. If the value is non-zero and less than what the field on the 
>     slave is then use the from_length else use the original value from the
>     field on the slave.
>
>   sql/field.h@stripped, 2007-07-16 16:11:22-04:00, cbell@mysql_cab_desk. +23 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch includes updates to the unpack() methods for the variable
>     length fields. A new parameter was added (from_length) that is the
>     value stored in the field_metadata of the table map from the table_def
>     class. 
>
>   sql/log_event.cc@stripped, 2007-07-16 16:11:23-04:00, cbell@mysql_cab_desk. +187 -7
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch adds methods to calculate the field metadata size, prepare
>     the field metadata for writing to the binlog, and additions to the
>     Table_map_log_event::write_body method to include the field metadata 
>     in the table map that is written to the binlog.
>
>   sql/log_event.h@stripped, 2007-07-16 16:11:23-04:00, cbell@mysql_cab_desk. +8 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch adds method declarations and variables needed to support
>     storing field metadata in the table map that is written to the binlog.
>
>   sql/rpl_record.cc@stripped, 2007-07-16 16:11:24-04:00, cbell@mysql_cab_desk. +15 -3
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch modifies the unpack_row() method to unpack fields passing in
>     the value from the table_def class. This value is the extra field
>     metadata stored there from the master.
>
>   sql/rpl_rli.h@stripped, 2007-07-16 16:11:24-04:00, cbell@mysql_cab_desk. +10 -0
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch adds a helper function to retrieve the table_def for a given
>     table in the RPL_TABLE_LIST structure.
>
>   sql/rpl_utility.cc@stripped, 2007-07-16 16:11:24-04:00, cbell@mysql_cab_desk. +37 -33
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch adds a helper method that retrieves the correct size 
>     parameter for the field. This method is used to compare the size as
>     sent by the master with that on the slave for all types of fields that
>     can vary in size and storage requirements. 
>
>   sql/rpl_utility.h@stripped, 2007-07-16 16:11:25-04:00, cbell@mysql_cab_desk. +93 -5
>     WL#3228 : RBR using different table defs on slave/master
>     
>     This patch changes the table_def class constructor to pass in the raw
>     data read from the table map and extract it into an array of dimension
>     size (number of fields). It also adds a method to return the field 
>     metadata for any field. The method returns the data stored in the table
>     map or 0 if no data was stored for that field.
>
> Binary files a/mysql-test/r/rpl_colSize.result and b/mysql-test/r/rpl_colSize.result
> differ
> diff -Nrup a/mysql-test/r/rpl_ndb_log.result b/mysql-test/r/rpl_ndb_log.result
> --- a/mysql-test/r/rpl_ndb_log.result	2007-06-11 16:15:20 -04:00
> +++ b/mysql-test/r/rpl_ndb_log.result	2007-07-16 16:11:15 -04:00
> @@ -88,12 +88,12 @@ master-bin.000002	#	Write_rows	1	#	table
>  master-bin.000002	#	Query	1	#	COMMIT
>  show binary logs;
>  Log_name	File_size
> -master-bin.000001	1775
> -master-bin.000002	617
> +master-bin.000001	1785
> +master-bin.000002	621
>  start slave;
>  show binary logs;
>  Log_name	File_size
> -slave-bin.000001	1870
> +slave-bin.000001	1880
>  slave-bin.000002	202
>  show binlog events in 'slave-bin.000001' from 4;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> @@ -133,7 +133,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000002
> -Read_Master_Log_Pos	617
> +Read_Master_Log_Pos	621
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000002
> @@ -148,7 +148,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	617
> +Exec_Master_Log_Pos	621
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> diff -Nrup a/mysql-test/r/rpl_row_basic_11bugs.result
> b/mysql-test/r/rpl_row_basic_11bugs.result
> --- a/mysql-test/r/rpl_row_basic_11bugs.result	2007-06-04 08:02:37 -04:00
> +++ b/mysql-test/r/rpl_row_basic_11bugs.result	2007-07-16 16:11:15 -04:00
> @@ -56,8 +56,8 @@ SHOW BINLOG EVENTS;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  master-bin.000001	4	Format_desc	1	106	Server ver: SERVER_VERSION, Binlog ver: 4
>  master-bin.000001	106	Query	1	192	use `test`; CREATE TABLE t1 (a INT)
> -master-bin.000001	192	Table_map	1	231	table_id: # (test.t1)
> -master-bin.000001	231	Write_rows	1	270	table_id: # flags: STMT_END_F
> +master-bin.000001	192	Table_map	1	232	table_id: # (test.t1)
> +master-bin.000001	232	Write_rows	1	271	table_id: # flags: STMT_END_F
>  DROP TABLE t1;
>  ================ Test for BUG#17620 ================
>  drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
> diff -Nrup a/mysql-test/r/rpl_row_create_table.result
> b/mysql-test/r/rpl_row_create_table.result
> --- a/mysql-test/r/rpl_row_create_table.result	2007-03-30 04:27:01 -04:00
> +++ b/mysql-test/r/rpl_row_create_table.result	2007-07-16 16:11:16 -04:00
> @@ -127,8 +127,9 @@ NULL	5	10
>  NULL	6	12
>  CREATE TABLE t7 (UNIQUE(b)) SELECT a,b FROM tt3;
>  ERROR 23000: Duplicate entry '2' for key 'b'
> -SHOW BINLOG EVENTS FROM 1098;
> +SHOW BINLOG EVENTS FROM 1016;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> +#	1016	Write_rows	#	292	table_id: # flags: STMT_END_F
>  CREATE TABLE t7 (a INT, b INT UNIQUE);
>  INSERT INTO t7 SELECT a,b FROM tt3;
>  ERROR 23000: Duplicate entry '2' for key 'b'
> @@ -137,11 +138,12 @@ a	b
>  1	2
>  2	4
>  3	6
> -SHOW BINLOG EVENTS FROM 1098;
> +SHOW BINLOG EVENTS FROM 1016;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> -#	1098	Query	#	1198	use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
> -#	1198	Table_map	#	1238	table_id: # (test.t7)
> -#	1238	Write_rows	#	1294	table_id: # flags: STMT_END_F
> +#	1016	Write_rows	#	292	table_id: # flags: STMT_END_F
> +#	1099	Query	#	1199	use `test`; CREATE TABLE t7 (a INT, b INT UNIQUE)
> +#	1199	Table_map	#	1240	table_id: # (test.t7)
> +#	1240	Write_rows	#	1296	table_id: # flags: STMT_END_F
>  SELECT * FROM t7 ORDER BY a,b;
>  a	b
>  1	2
> @@ -154,10 +156,11 @@ INSERT INTO t7 SELECT a,b FROM tt4;
>  ROLLBACK;
>  Warnings:
>  Warning	1196	Some non-transactional changed tables couldn't be rolled back
> -SHOW BINLOG EVENTS FROM 1294;
> +SHOW BINLOG EVENTS FROM 1240;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> -#	1294	Table_map	#	1334	table_id: # (test.t7)
> -#	1334	Write_rows	#	1390	table_id: # flags: STMT_END_F
> +#	1240	Write_rows	#	1296	table_id: # flags: STMT_END_F
> +#	1296	Table_map	#	1337	table_id: # (test.t7)
> +#	1337	Write_rows	#	1393	table_id: # flags: STMT_END_F
>  SELECT * FROM t7 ORDER BY a,b;
>  a	b
>  1	2
> @@ -192,10 +195,10 @@ Create Table	CREATE TABLE `t9` (
>    `a` int(11) DEFAULT NULL,
>    `b` int(11) DEFAULT NULL
>  ) ENGINE=MyISAM DEFAULT CHARSET=latin1
> -SHOW BINLOG EVENTS FROM 1390;
> +SHOW BINLOG EVENTS FROM 1393;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> -#	1390	Query	#	1476	use `test`; CREATE TABLE t8 LIKE t4
> -#	1476	Query	#	1615	use `test`; CREATE TABLE `t9` (
> +#	1393	Query	#	1479	use `test`; CREATE TABLE t8 LIKE t4
> +#	1479	Query	#	1618	use `test`; CREATE TABLE `t9` (
>    `a` int(11) DEFAULT NULL,
>    `b` int(11) DEFAULT NULL
>  )
> @@ -276,31 +279,31 @@ SHOW BINLOG EVENTS;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  #	4	Format_desc	#	106	Server ver: #, Binlog ver: #
>  #	106	Query	#	192	use `test`; CREATE TABLE t1 (a INT)
> -#	192	Table_map	#	231	table_id: # (test.t1)
> -#	231	Write_rows	#	275	table_id: # flags: STMT_END_F
> -#	275	Query	#	343	use `test`; BEGIN
> -#	343	Query	#	125	use `test`; CREATE TABLE `t2` (
> +#	192	Table_map	#	232	table_id: # (test.t1)
> +#	232	Write_rows	#	276	table_id: # flags: STMT_END_F
> +#	276	Query	#	344	use `test`; BEGIN
> +#	344	Query	#	125	use `test`; CREATE TABLE `t2` (
>    `a` int(11) DEFAULT NULL
>  ) ENGINE=InnoDB
> -#	468	Table_map	#	164	table_id: # (test.t2)
> -#	507	Write_rows	#	208	table_id: # flags: STMT_END_F
> -#	551	Xid	#	578	COMMIT /* XID */
> -#	578	Query	#	646	use `test`; BEGIN
> -#	646	Query	#	125	use `test`; CREATE TABLE `t3` (
> +#	469	Table_map	#	165	table_id: # (test.t2)
> +#	509	Write_rows	#	209	table_id: # flags: STMT_END_F
> +#	553	Xid	#	580	COMMIT /* XID */
> +#	580	Query	#	648	use `test`; BEGIN
> +#	648	Query	#	125	use `test`; CREATE TABLE `t3` (
>    `a` int(11) DEFAULT NULL
>  ) ENGINE=InnoDB
> -#	771	Table_map	#	164	table_id: # (test.t3)
> -#	810	Write_rows	#	208	table_id: # flags: STMT_END_F
> -#	854	Xid	#	881	COMMIT /* XID */
> -#	881	Query	#	949	use `test`; BEGIN
> -#	949	Query	#	125	use `test`; CREATE TABLE `t4` (
> +#	773	Table_map	#	165	table_id: # (test.t3)
> +#	813	Write_rows	#	209	table_id: # flags: STMT_END_F
> +#	857	Xid	#	884	COMMIT /* XID */
> +#	884	Query	#	952	use `test`; BEGIN
> +#	952	Query	#	125	use `test`; CREATE TABLE `t4` (
>    `a` int(11) DEFAULT NULL
>  ) ENGINE=InnoDB
> -#	1074	Table_map	#	164	table_id: # (test.t4)
> -#	1113	Write_rows	#	208	table_id: # flags: STMT_END_F
> -#	1157	Xid	#	1184	COMMIT /* XID */
> -#	1184	Table_map	#	1223	table_id: # (test.t1)
> -#	1223	Write_rows	#	1267	table_id: # flags: STMT_END_F
> +#	1077	Table_map	#	165	table_id: # (test.t4)
> +#	1117	Write_rows	#	209	table_id: # flags: STMT_END_F
> +#	1161	Xid	#	1188	COMMIT /* XID */
> +#	1188	Table_map	#	1228	table_id: # (test.t1)
> +#	1228	Write_rows	#	1272	table_id: # flags: STMT_END_F
>  SHOW TABLES;
>  Tables_in_test
>  t1
> @@ -367,15 +370,15 @@ SHOW BINLOG EVENTS;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  #	4	Format_desc	#	106	Server ver: #, Binlog ver: #
>  #	106	Query	#	192	use `test`; CREATE TABLE t1 (a INT)
> -#	192	Table_map	#	231	table_id: # (test.t1)
> -#	231	Write_rows	#	275	table_id: # flags: STMT_END_F
> -#	275	Query	#	375	use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB
> -#	375	Query	#	443	use `test`; BEGIN
> -#	443	Table_map	#	39	table_id: # (test.t2)
> -#	482	Write_rows	#	83	table_id: # flags: STMT_END_F
> -#	526	Table_map	#	122	table_id: # (test.t2)
> -#	565	Write_rows	#	161	table_id: # flags: STMT_END_F
> -#	604	Xid	#	631	COMMIT /* XID */
> +#	192	Table_map	#	232	table_id: # (test.t1)
> +#	232	Write_rows	#	276	table_id: # flags: STMT_END_F
> +#	276	Query	#	376	use `test`; CREATE TABLE t2 (a INT) ENGINE=INNODB
> +#	376	Query	#	444	use `test`; BEGIN
> +#	444	Table_map	#	40	table_id: # (test.t2)
> +#	484	Write_rows	#	84	table_id: # flags: STMT_END_F
> +#	528	Table_map	#	124	table_id: # (test.t2)
> +#	568	Write_rows	#	163	table_id: # flags: STMT_END_F
> +#	607	Xid	#	634	COMMIT /* XID */
>  SELECT * FROM t2 ORDER BY a;
>  a
>  1
> @@ -394,10 +397,10 @@ INSERT INTO t2 SELECT a+2 FROM tt2;
>  ROLLBACK;
>  SELECT * FROM t2 ORDER BY a;
>  a
> -SHOW BINLOG EVENTS FROM 631;
> +SHOW BINLOG EVENTS FROM 634;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
> -#	631	Query	#	80	use `test`; TRUNCATE TABLE t2
> -#	711	Xid	#	738	COMMIT /* XID */
> +#	634	Query	#	80	use `test`; TRUNCATE TABLE t2
> +#	714	Xid	#	741	COMMIT /* XID */
>  SELECT * FROM t2 ORDER BY a;
>  a
>  DROP TABLE t1,t2;
> diff -Nrup a/mysql-test/r/rpl_row_flsh_tbls.result
> b/mysql-test/r/rpl_row_flsh_tbls.result
> --- a/mysql-test/r/rpl_row_flsh_tbls.result	2007-03-30 04:27:01 -04:00
> +++ b/mysql-test/r/rpl_row_flsh_tbls.result	2007-07-16 16:11:16 -04:00
> @@ -12,13 +12,13 @@ create table t4 (a int);
>  insert into t4 select * from t3;
>  rename table t1 to t5, t2 to t1;
>  flush no_write_to_binlog tables;
> -SHOW BINLOG EVENTS FROM 619 ;
> +SHOW BINLOG EVENTS FROM 621 ;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  master-bin.000001	#	Query	1	#	use `test`; rename table t1 to t5, t2 to t1
>  select * from t3;
>  a
>  flush tables;
> -SHOW BINLOG EVENTS FROM 619 ;
> +SHOW BINLOG EVENTS FROM 621 ;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  master-bin.000001	#	Query	1	#	use `test`; rename table t1 to t5, t2 to t1
>  master-bin.000001	#	Query	1	#	use `test`; flush tables
> diff -Nrup a/mysql-test/r/rpl_row_inexist_tbl.result
> b/mysql-test/r/rpl_row_inexist_tbl.result
> --- a/mysql-test/r/rpl_row_inexist_tbl.result	2007-06-11 16:15:21 -04:00
> +++ b/mysql-test/r/rpl_row_inexist_tbl.result	2007-07-16 16:11:17 -04:00
> @@ -24,7 +24,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	597
> +Read_Master_Log_Pos	601
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -39,7 +39,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	1146
>  Last_Error	Error 'Table 'test.t1' doesn't exist' on opening table `test`.`t1`
>  Skip_Counter	0
> -Exec_Master_Log_Pos	524
> +Exec_Master_Log_Pos	527
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> diff -Nrup a/mysql-test/r/rpl_row_log.result b/mysql-test/r/rpl_row_log.result
> --- a/mysql-test/r/rpl_row_log.result	2007-06-11 16:15:21 -04:00
> +++ b/mysql-test/r/rpl_row_log.result	2007-07-16 16:11:17 -04:00
> @@ -66,13 +66,13 @@ master-bin.000002	#	Table_map	1	#	table_
>  master-bin.000002	#	Write_rows	1	#	table_id: # flags: STMT_END_F
>  show binary logs;
>  Log_name	File_size
> -master-bin.000001	1260
> -master-bin.000002	377
> +master-bin.000001	1264
> +master-bin.000002	378
>  start slave;
>  show binary logs;
>  Log_name	File_size
> -slave-bin.000001	1358
> -slave-bin.000002	278
> +slave-bin.000001	1362
> +slave-bin.000002	279
>  show binlog events in 'slave-bin.000001' from 4;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  slave-bin.000001	#	Format_desc	2	#	Server ver: VERSION, Binlog ver: 4
> @@ -98,7 +98,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000002
> -Read_Master_Log_Pos	377
> +Read_Master_Log_Pos	378
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000002
> @@ -113,7 +113,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	377
> +Exec_Master_Log_Pos	378
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> diff -Nrup a/mysql-test/r/rpl_row_log_innodb.result
> b/mysql-test/r/rpl_row_log_innodb.result
> --- a/mysql-test/r/rpl_row_log_innodb.result	2007-06-11 16:15:21 -04:00
> +++ b/mysql-test/r/rpl_row_log_innodb.result	2007-07-16 16:11:18 -04:00
> @@ -71,13 +71,13 @@ master-bin.000002	#	Write_rows	1	#	table
>  master-bin.000002	#	Xid	1	#	COMMIT /* XID */
>  show binary logs;
>  Log_name	File_size
> -master-bin.000001	1314
> -master-bin.000002	404
> +master-bin.000001	1318
> +master-bin.000002	405
>  start slave;
>  show binary logs;
>  Log_name	File_size
> -slave-bin.000001	1412
> -slave-bin.000002	305
> +slave-bin.000001	1416
> +slave-bin.000002	306
>  show binlog events in 'slave-bin.000001' from 4;
>  Log_name	Pos	Event_type	Server_id	End_log_pos	Info
>  slave-bin.000001	#	Format_desc	2	#	Server ver: VERSION, Binlog ver: 4
> @@ -106,7 +106,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000002
> -Read_Master_Log_Pos	404
> +Read_Master_Log_Pos	405
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000002
> @@ -121,7 +121,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	404
> +Exec_Master_Log_Pos	405
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> diff -Nrup a/mysql-test/r/rpl_row_max_relay_size.result
> b/mysql-test/r/rpl_row_max_relay_size.result
> --- a/mysql-test/r/rpl_row_max_relay_size.result	2007-06-11 16:15:21 -04:00
> +++ b/mysql-test/r/rpl_row_max_relay_size.result	2007-07-16 16:11:18 -04:00
> @@ -30,7 +30,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	58668
> +Read_Master_Log_Pos	59468
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -45,7 +45,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	58668
> +Exec_Master_Log_Pos	59468
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> @@ -78,7 +78,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	58668
> +Read_Master_Log_Pos	59468
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -93,7 +93,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	58668
> +Exec_Master_Log_Pos	59468
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> @@ -126,7 +126,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	58668
> +Read_Master_Log_Pos	59468
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -141,7 +141,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	58668
> +Exec_Master_Log_Pos	59468
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> @@ -217,7 +217,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	58754
> +Read_Master_Log_Pos	59554
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -232,7 +232,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	58754
> +Exec_Master_Log_Pos	59554
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> @@ -261,7 +261,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	58830
> +Read_Master_Log_Pos	59630
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -276,7 +276,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	58830
> +Exec_Master_Log_Pos	59630
>  Relay_Log_Space	#
>  Until_Condition	None
>  Until_Log_File	
> diff -Nrup a/mysql-test/r/rpl_row_until.result b/mysql-test/r/rpl_row_until.result
> --- a/mysql-test/r/rpl_row_until.result	2007-06-11 16:15:22 -04:00
> +++ b/mysql-test/r/rpl_row_until.result	2007-07-16 16:11:18 -04:00
> @@ -26,7 +26,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	744
> +Read_Master_Log_Pos	747
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -41,7 +41,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	315
> +Exec_Master_Log_Pos	316
>  Relay_Log_Space	#
>  Until_Condition	Master
>  Until_Log_File	master-bin.000001
> @@ -72,7 +72,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	744
> +Read_Master_Log_Pos	747
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -87,7 +87,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	315
> +Exec_Master_Log_Pos	316
>  Relay_Log_Space	#
>  Until_Condition	Master
>  Until_Log_File	master-no-such-bin.000001
> @@ -116,7 +116,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	744
> +Read_Master_Log_Pos	747
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -131,7 +131,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	590
> +Exec_Master_Log_Pos	592
>  Relay_Log_Space	#
>  Until_Condition	Relay
>  Until_Log_File	slave-relay-bin.000004
> @@ -158,7 +158,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	744
> +Read_Master_Log_Pos	747
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -173,7 +173,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	744
> +Exec_Master_Log_Pos	747
>  Relay_Log_Space	#
>  Until_Condition	Master
>  Until_Log_File	master-bin.000001
> diff -Nrup a/mysql-test/r/rpl_skip_error.result b/mysql-test/r/rpl_skip_error.result
> --- a/mysql-test/r/rpl_skip_error.result	2007-06-24 20:35:08 -04:00
> +++ b/mysql-test/r/rpl_skip_error.result	2007-07-16 16:11:19 -04:00
> @@ -32,5 +32,5 @@ a
>  3
>  show slave status;
> 
> Slave_IO_State	Master_Host	Master_User	Master_Port	Connect_Retry	Master_Log_File	Read_Master_Log_Pos	Relay_Log_File	Relay_Log_Pos	Relay_Master_Log_File	Slave_IO_Running	Slave_SQL_Running	Replicate_Do_DB	Replicate_Ignore_DB	Replicate_Do_Table	Replicate_Ignore_Table	Replicate_Wild_Do_Table	Replicate_Wild_Ignore_Table	Last_Errno	Last_Error	Skip_Counter	Exec_Master_Log_Pos	Relay_Log_Space	Until_Condition	Until_Log_File	Until_Log_Pos	Master_SSL_Allowed	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	Last_IO_Errno	Last_IO_Error	Last_SQL_Errno	Last_SQL_Error
>
> -#	127.0.0.1	root	MASTER_PORT	1	master-bin.000001	776	#	#	master-bin.000001	Yes	Yes							0		0	776	#	None		0	No						#	No	0		0	
>
> +#	127.0.0.1	root	MASTER_PORT	1	master-bin.000001	781	#	#	master-bin.000001	Yes	Yes							0		0	781	#	None		0	No						#	No	0		0	
>  drop table t1;
> diff -Nrup a/mysql-test/r/rpl_slave_skip.result b/mysql-test/r/rpl_slave_skip.result
> --- a/mysql-test/r/rpl_slave_skip.result	2007-06-13 09:16:26 -04:00
> +++ b/mysql-test/r/rpl_slave_skip.result	2007-07-16 16:11:19 -04:00
> @@ -44,7 +44,7 @@ Master_User	root
>  Master_Port	MASTER_PORT
>  Connect_Retry	1
>  Master_Log_File	master-bin.000001
> -Read_Master_Log_Pos	714
> +Read_Master_Log_Pos	718
>  Relay_Log_File	#
>  Relay_Log_Pos	#
>  Relay_Master_Log_File	master-bin.000001
> @@ -59,7 +59,7 @@ Replicate_Wild_Ignore_Table	
>  Last_Errno	0
>  Last_Error	
>  Skip_Counter	0
> -Exec_Master_Log_Pos	484
> +Exec_Master_Log_Pos	486
>  Relay_Log_Space	#
>  Until_Condition	Master
>  Until_Log_File	master-bin.000001
> diff -Nrup a/mysql-test/r/rpl_truncate_7ndb.result
> b/mysql-test/r/rpl_truncate_7ndb.result
> --- a/mysql-test/r/rpl_truncate_7ndb.result	2007-03-29 22:44:45 -04:00
> +++ b/mysql-test/r/rpl_truncate_7ndb.result	2007-07-16 16:11:20 -04:00
> @@ -32,14 +32,14 @@ Log_name	Pos	Event_type	Server_id	End_lo
>  master-bin.000001	4	Format_desc	1	106	Server ver: SERVER_VERSION, Binlog ver: 4
>  master-bin.000001	106	Query	1	223	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b
> LONG) ENGINE=NDB
>  master-bin.000001	223	Query	1	287	BEGIN
> -master-bin.000001	287	Table_map	1	40	table_id: # (test.t1)
> -master-bin.000001	327	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
> -master-bin.000001	385	Write_rows	1	157	table_id: #
> -master-bin.000001	444	Write_rows	1	195	table_id: #
> -master-bin.000001	482	Write_rows	1	233	table_id: # flags: STMT_END_F
> -master-bin.000001	520	Query	1	585	COMMIT
> -master-bin.000001	585	Query	1	665	use `test`; TRUNCATE TABLE t1
> -master-bin.000001	665	Query	1	741	use `test`; DROP TABLE t1
> +master-bin.000001	287	Table_map	1	41	table_id: # (test.t1)
> +master-bin.000001	328	Table_map	1	102	table_id: # (mysql.ndb_apply_status)
> +master-bin.000001	389	Write_rows	1	161	table_id: #
> +master-bin.000001	448	Write_rows	1	199	table_id: #
> +master-bin.000001	486	Write_rows	1	237	table_id: # flags: STMT_END_F
> +master-bin.000001	524	Query	1	589	COMMIT
> +master-bin.000001	589	Query	1	669	use `test`; TRUNCATE TABLE t1
> +master-bin.000001	669	Query	1	745	use `test`; DROP TABLE t1
>  **** On Master ****
>  CREATE TABLE t1 (a INT PRIMARY KEY, b LONG) ENGINE=NDB;
>  INSERT INTO t1 VALUES (1,1), (2,2);
> @@ -69,27 +69,27 @@ Log_name	Pos	Event_type	Server_id	End_lo
>  master-bin.000001	4	Format_desc	1	106	Server ver: SERVER_VERSION, Binlog ver: 4
>  master-bin.000001	106	Query	1	223	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b
> LONG) ENGINE=NDB
>  master-bin.000001	223	Query	1	287	BEGIN
> -master-bin.000001	287	Table_map	1	40	table_id: # (test.t1)
> -master-bin.000001	327	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
> -master-bin.000001	385	Write_rows	1	157	table_id: #
> -master-bin.000001	444	Write_rows	1	195	table_id: #
> -master-bin.000001	482	Write_rows	1	233	table_id: # flags: STMT_END_F
> -master-bin.000001	520	Query	1	585	COMMIT
> -master-bin.000001	585	Query	1	665	use `test`; TRUNCATE TABLE t1
> -master-bin.000001	665	Query	1	741	use `test`; DROP TABLE t1
> -master-bin.000001	741	Query	1	858	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b
> LONG) ENGINE=NDB
> -master-bin.000001	858	Query	1	922	BEGIN
> -master-bin.000001	922	Table_map	1	40	table_id: # (test.t1)
> -master-bin.000001	962	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
> -master-bin.000001	1020	Write_rows	1	157	table_id: #
> -master-bin.000001	1079	Write_rows	1	195	table_id: #
> -master-bin.000001	1117	Write_rows	1	233	table_id: # flags: STMT_END_F
> -master-bin.000001	1155	Query	1	1220	COMMIT
> -master-bin.000001	1220	Query	1	1284	BEGIN
> -master-bin.000001	1284	Table_map	1	40	table_id: # (test.t1)
> -master-bin.000001	1324	Table_map	1	98	table_id: # (mysql.ndb_apply_status)
> -master-bin.000001	1382	Write_rows	1	157	table_id: #
> -master-bin.000001	1441	Delete_rows	1	191	table_id: #
> -master-bin.000001	1475	Delete_rows	1	225	table_id: # flags: STMT_END_F
> -master-bin.000001	1509	Query	1	1574	COMMIT
> -master-bin.000001	1574	Query	1	1650	use `test`; DROP TABLE t1
> +master-bin.000001	287	Table_map	1	41	table_id: # (test.t1)
> +master-bin.000001	328	Table_map	1	102	table_id: # (mysql.ndb_apply_status)
> +master-bin.000001	389	Write_rows	1	161	table_id: #
> +master-bin.000001	448	Write_rows	1	199	table_id: #
> +master-bin.000001	486	Write_rows	1	237	table_id: # flags: STMT_END_F
> +master-bin.000001	524	Query	1	589	COMMIT
> +master-bin.000001	589	Query	1	669	use `test`; TRUNCATE TABLE t1
> +master-bin.000001	669	Query	1	745	use `test`; DROP TABLE t1
> +master-bin.000001	745	Query	1	862	use `test`; CREATE TABLE t1 (a INT PRIMARY KEY, b
> LONG) ENGINE=NDB
> +master-bin.000001	862	Query	1	926	BEGIN
> +master-bin.000001	926	Table_map	1	41	table_id: # (test.t1)
> +master-bin.000001	967	Table_map	1	102	table_id: # (mysql.ndb_apply_status)
> +master-bin.000001	1028	Write_rows	1	161	table_id: #
> +master-bin.000001	1087	Write_rows	1	199	table_id: #
> +master-bin.000001	1125	Write_rows	1	237	table_id: # flags: STMT_END_F
> +master-bin.000001	1163	Query	1	1228	COMMIT
> +master-bin.000001	1228	Query	1	1292	BEGIN
> +master-bin.000001	1292	Table_map	1	41	table_id: # (test.t1)
> +master-bin.000001	1333	Table_map	1	102	table_id: # (mysql.ndb_apply_status)
> +master-bin.000001	1394	Write_rows	1	161	table_id: #
> +master-bin.000001	1453	Delete_rows	1	195	table_id: #
> +master-bin.000001	1487	Delete_rows	1	229	table_id: # flags: STMT_END_F
> +master-bin.000001	1521	Query	1	1586	COMMIT
> +master-bin.000001	1586	Query	1	1662	use `test`; DROP TABLE t1
> diff -Nrup a/mysql-test/t/binlog_row_mix_innodb_myisam.test
> b/mysql-test/t/binlog_row_mix_innodb_myisam.test
> --- a/mysql-test/t/binlog_row_mix_innodb_myisam.test	2007-06-09 01:55:02 -04:00
> +++ b/mysql-test/t/binlog_row_mix_innodb_myisam.test	2007-07-16 16:11:20 -04:00
> @@ -20,7 +20,7 @@
>  # ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction
>  # and does not make slave to stop)
>  flush logs;
> ---exec $MYSQL_BINLOG --start-position=520 $MYSQLTEST_VARDIR/log/master-bin.000001
> > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
> +--exec $MYSQL_BINLOG --start-position=522 $MYSQLTEST_VARDIR/log/master-bin.000001
> > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
>  --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
>  eval select
>  (@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
> diff -Nrup a/mysql-test/t/rpl_colSize.test b/mysql-test/t/rpl_colSize.test
> --- /dev/null	Wed Dec 31 16:00:00 196900
> +++ b/mysql-test/t/rpl_colSize.test	2007-07-16 16:11:25 -04:00
> @@ -0,0 +1,111 @@
> +##################################################################
> +# 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/have_binlog_format_row.inc
> +-- source include/master-slave.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;
> +STOP SLAVE;
> +RESET SLAVE;
> +
> +eval CREATE TABLE t1 (
> +  a float     (47),
> +  b double    (143,9),
> +  c decimal   (65,30),
> +  d numeric   (4,0),
> +  e bit       (32),
> +  f char      (21),
> +  g varchar   (1300),
> +  h binary    (33),
> +  j varbinary (200),
> +  k enum      ('5','6','7', '8','9','0'),
> +  l set      
> ('1','2','3','4','5','6','7','8','9','0','11','12','13','14','15','16','17','18','19','21','22','23','24','25','26','27','28','29'),
> +  m TINYBLOB,
> +  n BLOB,
> +  o MEDIUMBLOB,
> +  p LONGBLOB,
> +  q TINYTEXT,
> +  r TEXT,
> +  s MEDIUMTEXT,
> +  t LONGTEXT
> +);
> +
> +--echo *** Create same table on master but with narrow columns ***
> +connection master;
> +eval CREATE TABLE t1 (
> +  a float     (44),
> +  b double    (10,3),
> +  c decimal   (10,2),
> +  d numeric   (3,0),
> +  e bit       (16),
> +  f char      (10),
> +  g varchar   (100),
> +  h binary    (20),
> +  j varbinary (20),
> +  k enum      ('5','6','7'),
> +  l set       ('1','2','3','4','5','6','7','8','9','0'),
> +  m TINYBLOB,
> +  n BLOB,
> +  o MEDIUMBLOB,
> +  p LONGBLOB,
> +  q TINYTEXT,
> +  r TEXT,
> +  s MEDIUMTEXT,
> +  t LONGTEXT
> +);
> +
> +RESET MASTER;
> +
> +--echo *** Start replication ***
> +connection slave;
> +START SLAVE;
> +
> +--echo *** Insert data on master and display it. ***
> +connection master;
> +
> +INSERT INTO t1 () VALUES (
> +  17.567, 
> +  2.123, 
> +  10.20, 
> +  125,
> +  hex(64),
> +  'TEST',
> +  'This is a test',
> +  'binary data',
> +  'more binary data',
> +  '6',
> +  '7',
> +  "blob 1",
> +  "blob  2",
> +  "blob   3",
> +  "blob    4",
> +  "text 1",
> +  "text  2",
> +  "text   3",
> +  "text    4");
> +
> +SELECT * FROM t1 ORDER BY a;
> +
> +--echo *** Select data from slave to compare ***
> +sync_slave_with_master;
> +connection slave;
> +
> +SELECT * FROM t1 ORDER BY a;
> +
> +--echo *** Cleanup  ***
> +connection master;
> +DROP TABLE t1;
> +sync_slave_with_master;
> +
> +# END 5.1 Test Case
> diff -Nrup a/mysql-test/t/rpl_row_create_table.test
> b/mysql-test/t/rpl_row_create_table.test
> --- a/mysql-test/t/rpl_row_create_table.test	2007-06-06 13:48:13 -04:00
> +++ b/mysql-test/t/rpl_row_create_table.test	2007-07-16 16:11:21 -04:00
> @@ -72,7 +72,7 @@ CREATE TABLE t7 (UNIQUE(b)) SELECT a,b F
>  # Shouldn't be written to the binary log
>  --replace_column 1 # 4 #
>  --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
> -SHOW BINLOG EVENTS FROM 1098;
> +SHOW BINLOG EVENTS FROM 1016;
>  
>  # Test that INSERT-SELECT works the same way as for SBR.
>  CREATE TABLE t7 (a INT, b INT UNIQUE);
> @@ -82,7 +82,7 @@ SELECT * FROM t7 ORDER BY a,b;
>  # Should be written to the binary log
>  --replace_column 1 # 4 #
>  --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
> -SHOW BINLOG EVENTS FROM 1098;
> +SHOW BINLOG EVENTS FROM 1016;
>  sync_slave_with_master;
>  SELECT * FROM t7 ORDER BY a,b;
>  
> @@ -94,7 +94,7 @@ INSERT INTO t7 SELECT a,b FROM tt4;
>  ROLLBACK;
>  --replace_column 1 # 4 #
>  --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
> -SHOW BINLOG EVENTS FROM 1294;
> +SHOW BINLOG EVENTS FROM 1240;
>  SELECT * FROM t7 ORDER BY a,b;
>  sync_slave_with_master;
>  SELECT * FROM t7 ORDER BY a,b;
> @@ -110,7 +110,7 @@ CREATE TEMPORARY TABLE tt7 SELECT 1;
>  --query_vertical SHOW CREATE TABLE t9
>  --replace_column 1 # 4 #
>  --replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/
> -SHOW BINLOG EVENTS FROM 1390;
> +SHOW BINLOG EVENTS FROM 1393;
>  sync_slave_with_master;
>  --echo **** On Slave ****
>  --query_vertical SHOW CREATE TABLE t8
> @@ -227,7 +227,7 @@ ROLLBACK;
>  SELECT * FROM t2 ORDER BY a;
>  --replace_column 1 # 4 #
>  --replace_regex /\/\* xid=.* \*\//\/* XID *\// /Server ver: .*, Binlog ver:
> .*/Server ver: #, Binlog ver: #/ /table_id: [0-9]+/table_id: #/
> -SHOW BINLOG EVENTS FROM 631;
> +SHOW BINLOG EVENTS FROM 634;
>  sync_slave_with_master;
>  SELECT * FROM t2 ORDER BY a;
>  
> diff -Nrup a/mysql-test/t/rpl_row_flsh_tbls.test
> b/mysql-test/t/rpl_row_flsh_tbls.test
> --- a/mysql-test/t/rpl_row_flsh_tbls.test	2007-03-29 15:37:59 -04:00
> +++ b/mysql-test/t/rpl_row_flsh_tbls.test	2007-07-16 16:11:21 -04:00
> @@ -1,7 +1,7 @@
>  # depends on the binlog output
>  -- source include/have_binlog_format_row.inc
>  
> -let $rename_event_pos= 619;
> +let $rename_event_pos= 621;
>  
>  # Bug#18326: Do not lock table for writing during prepare of statement
>  # The use of the ps protocol causes extra table maps in the binlog, so
> diff -Nrup a/sql/field.cc b/sql/field.cc
> --- a/sql/field.cc	2007-06-21 11:12:54 -04:00
> +++ b/sql/field.cc	2007-07-16 16:11:21 -04:00
> @@ -2642,6 +2642,35 @@ uint Field_new_decimal::is_equal(Create_
>            (new_field->decimals == dec));
>  }
>  
> +const uchar *Field_new_decimal::unpack(uchar* to, const uchar *from, uint
> from_length)
> +{
> +  uint from_precision= from_length >> 8U;
> +  uint from_decimal= from_length - (from_precision << 8U);
> +  uint length=pack_length();
> +  uint from_pack_len= my_decimal_get_binary_size(from_precision, from_decimal);
> +  uint len= (from_length && (from_pack_len < length)) ?
> +            from_pack_len : length;
> +  if (from_pack_len && (from_pack_len < length))
> +  {
> +    /*
> +      If the master's data is smaller than the slave, we need to convert
> +      the binary to decimal then resize the decimal converting it back to
> +      a decimal and write that to the raw data buffer.
> +    */
> +    decimal_digit_t dec_buf[DECIMAL_MAX_PRECISION];
> +    decimal_t dec;
> +    dec.len= from_precision;
> +    dec.buf= dec_buf;
> +    double dbl;
> +    bin2decimal((uchar*) from, &dec, from_precision, from_decimal);
> +    decimal2double(&dec, &dbl);
> +    double2decimal(dbl, &dec);
> +    decimal2bin(&dec, to, precision, decimals());
> +  }
> +  else
> +    memcpy(to, from, len); // Sizes are the same, just copy the data.
> +  return from+len;
> +}
>  
>  /****************************************************************************
>  ** tiny int
> @@ -6291,6 +6320,27 @@ uchar *Field_string::pack(uchar *to, con
>  }
>  
>  
> +/*
> +  When unpacking data that may be smaller in the "from" than the "to," use
> +  the from_length to unpack rather than the to's length.
> +*/
> +const uchar *Field_string::unpack(uchar *to, const uchar *from, uint from_length)
> +{
> +  uint length= 0;
> +  uint f_length= (from_length && (from_length < field_length)) ? 
> +                from_length : field_length;
> +  if (f_length > 255)
> +  {
> +    length= uint2korr(from);
> +    from+= 2;
> +  }
> +  else
> +    length= (uint) *from++;
> +  memcpy(to, from, (int) length);
> +  bfill(to+length, field_length - length, ' ');
> +  return from+length;
> +}
> +
>  const uchar *Field_string::unpack(uchar *to, const uchar *from)
>  {
>    uint length;
> @@ -6783,7 +6833,34 @@ uchar *Field_varstring::pack_key_from_ke
>  
>  /*
>    unpack field packed with Field_varstring::pack()
> +
> +  When unpacking data that may be smaller in the "from" than the "to," use
> +  the from_length to unpack rather than the to's length_bytes.
>  */
> +const uchar *Field_varstring::unpack(uchar *to, const uchar *from, uint
> from_length)
> +{
> +  uint length;
> +  uint l_bytes= (from_length && (from_length < field_length)) ? 
> +                (from_length <= 255) ? 1 : 2 : length_bytes;
> +  if (l_bytes == 1)
> +    if (length_bytes == 1)
> +      length= (uint) (*to= *from++);
> +    else
> +    {
> +      to[1]= 0;
> +      to[0]= *from++;
> +      length= to[0];
> +    }
> +  else
> +  {
> +    length= uint2korr(from);
> +    to[0]= *from++;
> +    to[1]= *from++;
> +  }
> +  if (length)
> +    memcpy(to+ length_bytes, from, length);
> +  return from+length;
> +}
>  
>  const uchar *Field_varstring::unpack(uchar *to, const uchar *from)
>  {
> @@ -7476,6 +7553,14 @@ uchar *Field_blob::pack(uchar *to, const
>    return to+packlength+length;
>  }
>  
> +/*
> +  Note: from_length included to satisfy inheritance rules, but is not needed
> +  for blob fields.
> +*/
> +const uchar *Field_blob::unpack(uchar *to, const uchar *from, uint from_length)
> +{
> +  return unpack(to, from);
> +}
>  
>  const uchar *Field_blob::unpack(uchar *to, const uchar *from)
>  {
> @@ -8523,6 +8608,28 @@ uchar *Field_bit::pack(uchar *to, const 
>    return to + length;
>  }
>  
> +
> +/*
> +  When unpacking data that may be smaller in the "from" than the "to," use
> +  the from_length to unpack rather than the to's length.
> +*/
> +const uchar *Field_bit::unpack(uchar *to, const uchar *from, uint from_length)
> +{
> +  if (bit_len > 0)
> +  {
> +    /*
> +      set_rec_bits is a macro, don't put the post-increment in the
> +      argument since that might cause strange side-effects.
> +
> +      For the choice of the second argument, see the explanation for
> +      Field_bit::pack().
> +    */
> +    set_rec_bits(*from, bit_ptr + (to - ptr), bit_ofs, bit_len);
> +    from++;
> +  }
> +  memcpy(to, from, from_length);
> +  return from + from_length;
> +}
>  
>  const uchar *Field_bit::unpack(uchar *to, const uchar *from)
>  {
> diff -Nrup a/sql/field.h b/sql/field.h
> --- a/sql/field.h	2007-06-15 13:36:14 -04:00
> +++ b/sql/field.h	2007-07-16 16:11:22 -04:00
> @@ -343,6 +343,17 @@ public:
>      memcpy(to,from,length);
>      return to+length;
>    }
> +  virtual const uchar *unpack(uchar* to, const uchar *from, uint from_length)
> +  {
> +    uint length=pack_length();
> +    uint len= (from_length && (from_length < length)) ?
> +              from_length : length;
> +    if (from_length > length)
> +      memcpy(to,from,length);
> +    else
> +      memcpy(to,from,len);
> +    return from+len;
> +  }
>    virtual const uchar *unpack(uchar* to, const uchar *from)
>    {
>      uint length=pack_length();
> @@ -626,6 +637,7 @@ public:
>    uint size_of() const { return sizeof(*this); } 
>    uint32 pack_length() const { return (uint32) bin_size; }
>    uint is_equal(Create_field *new_field);
> +  const uchar *unpack(uchar* to, const uchar *from, uint from_length);
>  };
>  
>  
> @@ -1162,6 +1174,7 @@ public:
>    void sort_string(uchar *buff,uint length);
>    void sql_type(String &str) const;
>    uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0);
> +  const uchar *unpack(uchar* to, const uchar *from, uint from_length);
>    const uchar *unpack(uchar* to, const uchar *from);
>    int pack_cmp(const uchar *a,const uchar *b,uint key_length,
>                 my_bool insert_or_update);
> @@ -1238,6 +1251,7 @@ public:
>    uchar *pack_key(uchar *to, const uchar *from, uint max_length);
>    uchar *pack_key_from_key_image(uchar* to, const uchar *from,
>                                   uint max_length);
> +  const uchar *unpack(uchar* to, const uchar *from, uint from_length);
>    const uchar *unpack(uchar* to, const uchar *from);
>    const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
>    int pack_cmp(const uchar *a, const uchar *b, uint key_length,
> @@ -1293,6 +1307,9 @@ public:
>                    l_char_length <= 16777215 ? 3 : 4;
>      }
>    }
> +  Field_blob(uint32 packlength_arg)
> +    :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, "temp",
> system_charset_info),
> +    packlength(packlength_arg) {}
>    enum_field_types type() const { return MYSQL_TYPE_BLOB;}
>    enum ha_base_keytype key_type() const
>      { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
> @@ -1314,6 +1331,8 @@ public:
>    void sort_string(uchar *buff,uint length);
>    uint32 pack_length() const
>    { return (uint32) (packlength+table->s->blob_ptr_size); }
> +  uint32 pack_length_no_ptr() const
> +  { return (uint32) (packlength); }
>    uint32 sort_length() const;
>    inline uint32 max_data_length() const
>    {
> @@ -1329,6 +1348,8 @@ public:
>    {
>      store_length(ptr, packlength, number);
>    }
> +  uint32 get_packed_size(const uchar *ptr)
> +    {return packlength + get_length(ptr);}
>   
>    inline uint32 get_length(uint row_offset=0)
>    { return get_length(ptr+row_offset); }
> @@ -1377,6 +1398,7 @@ public:
>    uchar *pack_key(uchar *to, const uchar *from, uint max_length);
>    uchar *pack_key_from_key_image(uchar* to, const uchar *from,
>                                   uint max_length);
> +  const uchar *unpack(uchar *to, const uchar *from, uint from_length);
>    const uchar *unpack(uchar *to, const uchar *from);
>    const uchar *unpack_key(uchar* to, const uchar *from, uint max_length);
>    int pack_cmp(const uchar *a, const uchar *b, uint key_length,
> @@ -1552,6 +1574,7 @@ public:
>    uint32 pack_length_in_rec() const { return bytes_in_rec; }
>    void sql_type(String &str) const;
>    uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0);
> +  const uchar *unpack(uchar* to, const uchar *from, uint from_length);
>    const uchar *unpack(uchar* to, const uchar *from);
>    virtual void set_default();
>  
> diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
> --- a/sql/log_event.cc	2007-06-28 09:07:53 -04:00
> +++ b/sql/log_event.cc	2007-07-16 16:11:23 -04:00
> @@ -6023,11 +6023,8 @@ int Rows_log_event::do_apply_event(RELAY
>  #ifdef HAVE_QUERY_CACHE
>      query_cache.invalidate_locked_for_write(rli->tables_to_lock);
>  #endif
> -    const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
>    }
>  
> -  DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count
> == 0);
> -
>    TABLE* table=
> const_cast<RELAY_LOG_INFO*>(rli)->m_table_map.get_table(m_table_id);
>  
>    if (table)
> @@ -6122,6 +6119,15 @@ int Rows_log_event::do_apply_event(RELAY
>      }
>    }
>  
> +  /*
> +    We need to delay this clear until the table def is no longer needed.
> +    The table def is needed in unpack_row().
> +  */
> +  if (rli->tables_to_lock)
> +    const_cast<RELAY_LOG_INFO*>(rli)->clear_tables_to_lock();
> +
> +  DBUG_ASSERT(rli->tables_to_lock == NULL && rli->tables_to_lock_count
> == 0);
> +
>    if (error)
>    {                     /* error has occured during the transaction */
>      rli->report(ERROR_LEVEL, thd->net.last_errno,
> @@ -6370,6 +6376,140 @@ void Rows_log_event::print_helper(FILE *
>  /**************************************************************************
>  	Table_map_log_event member functions and support functions
>  **************************************************************************/
> +/**
> +  * Calculate field metadata size based on the real_type of the field.
> +  *
> +  * @returns int Size of field metadata.
> +  */
> +#if !defined(MYSQL_CLIENT)
> +int Table_map_log_event::get_field_metadata_size()
> +{
> +  DBUG_ENTER("Table_map_log_event::get_field_metadata_size");
> +  int 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:
> +    case MYSQL_TYPE_BIT:
> +    {
> +      size++;                         // Store one byte here.
> +      break; 
> +    }
> +    case MYSQL_TYPE_NEWDECIMAL:
> +    case MYSQL_TYPE_ENUM:
> +    case MYSQL_TYPE_STRING:
> +    case MYSQL_TYPE_VARCHAR:
> +    case MYSQL_TYPE_SET:
> +    {
> +      size= size + sizeof(short int); // Store short int here.
> +      break;
> +    }
> +    default:
> +      break;
> +    }
> +  }
> +  m_field_metadata_size= size;
> +  DBUG_PRINT("info", ("Table_map_log_event: %d bytes in field metadata.",
> +                       (int)m_field_metadata_size));
> +  DBUG_RETURN(m_field_metadata_size);
> +}
> +#endif /* !defined(MYSQL_CLIENT) */
> +
> +/**
> +  * 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 
> +  * 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.
> +  * 
> +  * 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 
> +  * field metadata from the table map into an array based on the type of the 
> +  * field. Field metadata values not present (those fields that do not use extra 
> +  * data) in the table map are initialized as zero (0). The array size is the 
> +  * same as the columns for the table on the slave.
> +*/
> +
> +/**
> +  * Save the field metadata based on the real_type of the field.
> +  * The metadata saved depends on the type of the field. Some fields
> +  * store a single byte for pack_length() while others store two bytes
> +  * for field_length (max length).
> +  *
> +  * @returns int 0 = Ok.
> +  */
> +#if !defined(MYSQL_CLIENT)
> +int Table_map_log_event::get_field_metadata()
> +{
> +  DBUG_ENTER("Table_map_log_event::get_field_metadata");
> +  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])->bytes_in_rec;
> +      break;
> +    }
> +    case MYSQL_TYPE_STRING:
> +    case MYSQL_TYPE_VARCHAR:
> +    {
> +      short int *x= (short int *)&m_field_metadata[index];
> +      int2store(x, m_table->s->field[i]->field_length);
> +      index= index + sizeof(short int);
> +      break;
> +    }
> +    case MYSQL_TYPE_ENUM:
> +    case MYSQL_TYPE_SET:
> +    {
> +      short int *x= (short int *)&m_field_metadata[index];
> +      int2store(x, m_table->s->field[i]->pack_length());
> +      index= index + sizeof(short int);
> +      break;
> +    }
> +    default:
> +      break;
> +    }
> +  }
> +  DBUG_RETURN(0);
> +}
> +#endif /* !defined(MYSQL_CLIENT) */
>  
>  /*
>    Constructor used to build an event for writing to the binary log.
> @@ -6385,7 +6525,7 @@ Table_map_log_event::Table_map_log_event
>      m_dblen(m_dbnam ? tbl->s->db.length : 0),
>      m_tblnam(tbl->s->table_name.str),
>      m_tbllen(tbl->s->table_name.length),
> -    m_colcnt(tbl->s->fields), m_coltype(0),
> +    m_colcnt(tbl->s->fields), m_field_metadata(0),
>      m_table_id(tid),
>      m_flags(flags)
>  {
> @@ -6406,6 +6546,16 @@ Table_map_log_event::Table_map_log_event
>    m_data_size+= m_dblen + 2;	// Include length and terminating \0
>    m_data_size+= m_tbllen + 2;	// Include length and terminating \0
>    m_data_size+= 1 + m_colcnt;	// COLCNT and column types
> +  m_field_metadata_size= get_field_metadata_size();
> +
> +  /*
> +    Now set the size of the data to the size of the field metadata array
> +    plus one or two bytes for number of elements in the field metadata array.
> +  */
> +  if (m_field_metadata_size > 255)
> +    m_data_size+= m_field_metadata_size + 2; 
> +  else
> +    m_data_size+= m_field_metadata_size + 1; 
>  
>    /* If malloc fails, catched in is_valid() */
>    if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
> @@ -6414,6 +6564,12 @@ Table_map_log_event::Table_map_log_event
>      for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
>        m_coltype[i]= m_table->field[i]->type();
>    }
> +
> +  /*
> +    Create an array for the field metadata and store it.
> +  */
> +  m_field_metadata= new uchar[m_field_metadata_size];
> +  get_field_metadata();
>  }
>  #endif /* !defined(MYSQL_CLIENT) */
>  
> @@ -6429,8 +6585,10 @@ Table_map_log_event::Table_map_log_event
>  #ifndef MYSQL_CLIENT
>    m_table(NULL),
>  #endif
> -  m_memory(NULL)
> +  m_memory(NULL),
> +  m_field_metadata(0), m_field_metadata_size(0)
>  {
> +  unsigned int bytes_read= 0;
>    DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
>  
>    uint8 common_header_len= description_event->common_header_len;
> @@ -6503,12 +6661,24 @@ Table_map_log_event::Table_map_log_event
>      memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
>    }
>  
> +  ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
> +  bytes_read= ptr_after_colcnt - (uchar *)buf;
> +  DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
> +  if (bytes_read < event_len)
> +  {
> +    m_field_metadata_size= net_field_length(&ptr_after_colcnt);
> +
> +    m_field_metadata= new uchar[m_field_metadata_size];
> +    memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
> +  }
> +
>    DBUG_VOID_RETURN;
>  }
>  #endif
>  
>  Table_map_log_event::~Table_map_log_event()
>  {
> +  delete[] m_field_metadata;
>    my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
>  }
>  
> @@ -6639,7 +6809,9 @@ int Table_map_log_event::do_apply_event(
>        inside st_relay_log_info::clear_tables_to_lock() by calling the
>        table_def destructor explicitly.
>      */
> -    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt);
> +    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, 
> +         m_field_metadata, m_field_metadata_size);
> +
>      table_list->m_tabledef_valid= TRUE;
>  
>      /*
> @@ -6711,12 +6883,20 @@ bool Table_map_log_event::write_data_bod
>    uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
>    DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
>  
> +  /*
> +    Store the size of the field metadata.
> +  */
> +  uchar mbuf[sizeof(m_field_metadata_size)];
> +  uchar *const mbuf_end= net_store_length(mbuf, (size_t) m_field_metadata_size);
> +
>    return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
>            my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
>            my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
>            my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
>            my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
> -          my_b_safe_write(file, m_coltype, m_colcnt));
> +          my_b_safe_write(file, m_coltype, m_colcnt) ||
> +          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
> +          my_b_safe_write(file, m_field_metadata, m_field_metadata_size));
>   }
>  #endif
>  
> diff -Nrup a/sql/log_event.h b/sql/log_event.h
> --- a/sql/log_event.h	2007-06-04 19:15:00 -04:00
> +++ b/sql/log_event.h	2007-07-16 16:11:23 -04:00
> @@ -2049,6 +2049,8 @@ public:
>  
>    virtual int get_data_size() { return m_data_size; } 
>  #ifndef MYSQL_CLIENT
> +  virtual int get_field_metadata_size();
> +  virtual int get_field_metadata();
>    virtual bool write_data_header(IO_CACHE *file);
>    virtual bool write_data_body(IO_CACHE *file);
>    virtual const char *get_db() { return m_dbnam; }
> @@ -2085,6 +2087,12 @@ private:
>    flag_set       m_flags;
>  
>    size_t         m_data_size;
> +
> +  uchar          *m_field_metadata;        // buffer for field metadata
> +  /*
> +    The size of field metadata buffer set by calling get_field_metadata_size()
> +  */
> +  ulong         m_field_metadata_size;   
>  };
>  
>  
> diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
> --- a/sql/rpl_record.cc	2007-06-11 16:15:28 -04:00
> +++ b/sql/rpl_record.cc	2007-07-16 16:11:24 -04:00
> @@ -17,6 +17,7 @@
>  #include "rpl_rli.h"
>  #include "rpl_record.h"
>  #include "slave.h"                  // Need to pull in slave_print_msg
> +#include "rpl_utility.h"
>  
>  /**
>     Pack a record of data for a table into a format suitable for
> @@ -169,6 +170,8 @@ unpack_row(RELAY_LOG_INFO const *rli,
>             uchar const **const row_end, ulong *const master_reclength,
>             MY_BITMAP* const rw_set, Log_event_type const event_type)
>  {
> +  my_bool stop= FALSE;
> +
>    DBUG_ENTER("unpack_row");
>    DBUG_ASSERT(row_data);
>    size_t const master_null_byte_count= (bitmap_bits_set(cols) + 7) / 8;
> @@ -191,7 +194,9 @@ unpack_row(RELAY_LOG_INFO const *rli,
>    unsigned int null_mask= 1U;
>    // The "current" null bits
>    unsigned int null_bits= *null_ptr++;
> -  for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr)
> +  int i= 0;
> +  table_def *tabledef=
> const_cast<RELAY_LOG_INFO*>(rli)->get_tabledef(table);
> +  for (field_ptr= begin_ptr ; field_ptr < end_ptr && !stop ;
> ++field_ptr)
>    {
>      Field *const f= *field_ptr;
>  
> @@ -220,14 +225,21 @@ unpack_row(RELAY_LOG_INFO const *rli,
>          f->set_notnull();
>  
>          /*
> -          We only unpack the field if it was non-null
> +          We only unpack the field if it was non-null.
> +          Use the master's size information if available else call
> +          normal unpack operation.
>          */
> -        pack_ptr= f->unpack(f->ptr, pack_ptr);
> +        if (tabledef && tabledef->field_metadata(i))
> +          pack_ptr= f->unpack(f->ptr, pack_ptr,
> tabledef->field_metadata(i));
> +        else
> +          pack_ptr= f->unpack(f->ptr, pack_ptr);
>        }
>  
>        bitmap_set_bit(rw_set, f->field_index);
>        null_mask <<= 1;
> +      i++;
>      }
> +
>    }
>  
>    /*
> diff -Nrup a/sql/rpl_rli.h b/sql/rpl_rli.h
> --- a/sql/rpl_rli.h	2007-06-11 16:15:29 -04:00
> +++ b/sql/rpl_rli.h	2007-07-16 16:11:24 -04:00
> @@ -18,6 +18,7 @@
>  
>  #include "rpl_tblmap.h"
>  #include "rpl_reporting.h"
> +#include "rpl_utility.h"
>  
>  struct RPL_TABLE_LIST;
>  
> @@ -300,6 +301,15 @@ typedef struct st_relay_log_info : publi
>    RPL_TABLE_LIST *tables_to_lock;           /* RBR: Tables to lock  */
>    uint tables_to_lock_count;        /* RBR: Count of tables to lock */
>    table_mapping m_table_map;      /* RBR: Mapping table-id to table */
> +
> +  inline table_def *get_tabledef(TABLE *tbl)
> +  {
> +    table_def *td= 0;
> +    for (TABLE_LIST *ptr= tables_to_lock; ptr && !td; ptr=
> ptr->next_global)
> +      if (ptr->table == tbl)
> +        td= &((RPL_TABLE_LIST *)ptr)->m_tabledef;
> +    return (td);
> +  }
>  
>    /*
>      Last charset (6 bytes) seen by slave SQL thread is cached here; it helps



*** /tmp/geta17705	2007-07-17 14:58:18.000000000 +0300
--- rpl_utility.cc	2007-07-17 14:18:12.000000000 +0300
*************** uint32 table_def::get_field_size(uint co
*** 83,89 ****
      length= m_field_metadata[col];
      break;
    case MYSQL_TYPE_VARCHAR:
!     length= m_field_metadata[col] + m_field_metadata[col] > 255 ? 2 : 1;
      break;
    case MYSQL_TYPE_TINY_BLOB:
    case MYSQL_TYPE_MEDIUM_BLOB:
--- 83,90 ----
      length= m_field_metadata[col];
      break;
    case MYSQL_TYPE_VARCHAR:
!     length= m_field_metadata[col] > 255 ? 2 : 1; // c&p of
Field_varstring::data_length()
!     length+= length == 1 ? (uint32) *master_data : uint2korr(master_data);
      break;
    case MYSQL_TYPE_TINY_BLOB:
    case MYSQL_TYPE_MEDIUM_BLOB:


> diff -Nrup a/sql/rpl_utility.cc b/sql/rpl_utility.cc
> --- a/sql/rpl_utility.cc	2007-06-11 16:15:29 -04:00
> +++ b/sql/rpl_utility.cc	2007-07-16 16:11:24 -04:00
> @@ -16,16 +16,32 @@
>  #include "rpl_utility.h"
>  #include "rpl_rli.h"
>  
> -uint32
> -field_length_from_packed(enum_field_types const field_type, 
> -                         uchar const *const data)
> +/*********************************************************************
> + *                   table_def member definitions                    *
> + *********************************************************************/
> +
> +/*
> +  This function returns the field size in raw bytes based on the type
> +  and the encoded field data from the master's raw data.
> +*/
> +uint32 table_def::get_field_size(uint col, uchar *master_data)
>  {
>    uint32 length;
>  
> -  switch (field_type) {
> -  case MYSQL_TYPE_DECIMAL:
> +  switch (type(col)) {
>    case MYSQL_TYPE_NEWDECIMAL:
> -    length= ~(uint32) 0;
> +    length= my_decimal_get_binary_size(m_field_metadata[col] >> 8, 
> +             m_field_metadata[col] - ((m_field_metadata[col] >> 8) <<
> 8));
> +    break;
> +  case MYSQL_TYPE_DECIMAL:
> +  case MYSQL_TYPE_FLOAT:
> +  case MYSQL_TYPE_DOUBLE:
> +    length= m_field_metadata[col];
> +    break;
> +  case MYSQL_TYPE_SET:
> +  case MYSQL_TYPE_ENUM:
> +  case MYSQL_TYPE_STRING:
> +    length= m_field_metadata[col] + 1;
>      break;
>    case MYSQL_TYPE_YEAR:
>    case MYSQL_TYPE_TINY:
> @@ -45,12 +61,6 @@ field_length_from_packed(enum_field_type
>      length= 8;
>      break;
>  #endif
> -  case MYSQL_TYPE_FLOAT:
> -    length= sizeof(float);
> -    break;
> -  case MYSQL_TYPE_DOUBLE:
> -    length= sizeof(double);
> -    break;
>    case MYSQL_TYPE_NULL:
>      length= 0;
>      break;
> @@ -69,41 +79,29 @@ field_length_from_packed(enum_field_type
>    case MYSQL_TYPE_DATETIME:
>      length= 8;
>      break;
> -    break;
>    case MYSQL_TYPE_BIT:
> -    length= ~(uint32) 0;
> +    length= m_field_metadata[col];
>      break;
> -  default:
> -    /* This case should never be chosen */
> -    DBUG_ASSERT(0);
> -    /* If something goes awfully wrong, it's better to get a string than die */
> -  case MYSQL_TYPE_STRING:
> -    length= uint2korr(data);
> -    break;
> -
> -  case MYSQL_TYPE_ENUM:
> -  case MYSQL_TYPE_SET:
> -  case MYSQL_TYPE_VAR_STRING:
>    case MYSQL_TYPE_VARCHAR:
> -    length= ~(uint32) 0;                               // NYI
> +    length= m_field_metadata[col] + m_field_metadata[col] > 255 ? 2 : 1;
>      break;
> -
>    case MYSQL_TYPE_TINY_BLOB:
>    case MYSQL_TYPE_MEDIUM_BLOB:
>    case MYSQL_TYPE_LONG_BLOB:
>    case MYSQL_TYPE_BLOB:
>    case MYSQL_TYPE_GEOMETRY:
> -    length= ~(uint32) 0;                               // NYI
> +  {
> +    Field_blob *fb= new Field_blob(m_field_metadata[col]);
> +    length= fb->get_packed_size(master_data);
> +    delete fb;
>      break;
>    }
> -
> +  default:
> +    length= -1;
> +  }
>    return length;
>  }
>  
> -/*********************************************************************
> - *                   table_def member definitions                    *
> - *********************************************************************/
> -
>  /*
>    Is the definition compatible with a table?
>  
> @@ -138,8 +136,14 @@ table_def::compatible_with(RELAY_LOG_INF
>                  ER(ER_BINLOG_ROW_WRONG_TABLE_DEF), buf);
>    }
>  
> +  /*
> +    We now check for column type and size compatibility.
> +  */
>    for (uint col= 0 ; col < cols_to_check ; ++col)
>    {
> +    /*
> +      Checking types.
> +    */
>      if (table->field[col]->type() != type(col))
>      {
>        DBUG_ASSERT(col < size() && col < tsh->fields);
> diff -Nrup a/sql/rpl_utility.h b/sql/rpl_utility.h
> --- a/sql/rpl_utility.h	2007-05-23 18:39:21 -04:00
> +++ b/sql/rpl_utility.h	2007-07-16 16:11:25 -04:00
> @@ -25,9 +25,6 @@
>  struct st_relay_log_info;
>  typedef st_relay_log_info RELAY_LOG_INFO;
>  
> -uint32
> -field_length_from_packed(enum_field_types field_type, uchar const *data);
> -
>  /**
>    A table definition from the master.
>  
> @@ -58,18 +55,78 @@ public:
>      @param types Array of types
>      @param size  Number of elements in array 'types'
>     */
> -  table_def(field_type *types, ulong size)
> -    : m_size(size), m_type(new unsigned char [size])
> +  table_def(field_type *types, ulong size, uchar *field_metadata, 
> +      int metadata_size)
> +    : m_size(size), m_type(new unsigned char [size]), m_field_metadata(0)
>    {
>      if (m_type)
>        memcpy(m_type, types, size);
>      else
>        m_size= 0;
> +    /*
> +      Extract the data from the table map into the field metadata array
> +      iff there is field metadata. The variable metadata_size will be
> +      0 if we are replicating from a down-level server hence no field
> +      metadata was written to the table map. This can also happen if 
> +      there were no fields in the master that needed extra metadata.
> +    */
> +    if (m_size && metadata_size)
> +    { 
> +      m_field_metadata= new short int[m_size];
> +      int index= 0;
> +      for (unsigned int i= 0; i < m_size; i++)
> +      {
> +        switch (m_type[i]) {
> +        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:
> +        case MYSQL_TYPE_BIT:
> +        {
> +          /*
> +            These types store a single byte.
> +          */
> +          m_field_metadata[i]= (uchar)field_metadata[index];
> +          index++;
> +          break;
> +        }
> +        case MYSQL_TYPE_SET:
> +        case MYSQL_TYPE_ENUM:
> +        case MYSQL_TYPE_STRING:
> +        case MYSQL_TYPE_VARCHAR:
> +        {
> +          /*
> +            These types store two bytes.
> +          */
> +          short int *x= (short int *)&field_metadata[index];
> +          m_field_metadata[i]= sint2korr(x);
> +          index= index + sizeof(short int);
> +          break;
> +        }
> +        case MYSQL_TYPE_NEWDECIMAL:
> +        {
> +          short int x= field_metadata[index] << 8U; // precision
> +          index++;
> +          x = x + field_metadata[index];            // decimals
> +          m_field_metadata[i]= x;
> +          index++;
> +          break;
> +        }
> +        default:
> +          m_field_metadata[i]= 0;
> +          break;
> +        }
> +      }
> +    }
>    }
>  
>    ~table_def() {
>      if (m_type)
>        delete [] m_type;
> +    if (m_field_metadata)
> +      delete [] m_field_metadata;
>  #ifndef DBUG_OFF
>      m_type= 0;
>      m_size= 0;
> @@ -99,6 +156,36 @@ public:
>      return m_type[index];
>    }
>  
> +  /*
> +    This function allows callers to get the extra field data from the
> +    table map for a given field. If there is no metadata for that field
> +    or there is no extra metadata at all, the function returns 0.
> +
> +    The function returns the value for the field metadata for column at 
> +    position indicated by index. As mentioned, if the field was a type 
> +    that stores field metadata, that value is returned else zero (0) is 
> +    returned. This method is used in the unpack() methods of the 
> +    corresponding fields to properly extract the data from the binary log 
> +    in the event that the master's field is smaller than the slave.
> +  */
> +  uint field_metadata(uint index) const
> +  {
> +    DBUG_ASSERT(index < m_size);
> +    if (m_field_metadata)
> +      return m_field_metadata[index];
> +    else
> +      return 0;
> +  }
> +
> +  /*
> +    This function returns the field size in raw bytes based on the type
> +    and the encoded field data from the master's raw data. This method can 
> +    be used for situations where the slave needs to skip a column (e.g., 
> +    WL#3915) or needs to advance the pointer for the fields in the raw 
> +    data from the master to a specific column.
> +  */
> +  uint32 get_field_size(uint col, uchar *master_data);
> +
>    /**
>      Decide if the table definition is compatible with a table.
>  
> @@ -121,6 +208,7 @@ public:
>  private:
>    ulong m_size;           // Number of elements in the types array
>    field_type *m_type;                     // Array of type descriptors
> +  short int *m_field_metadata;
>  };
>  
>  /**
>
>
> -- 
> MySQL Code Commits Mailing List
> For list archives: http://lists.mysql.com/commits
> To unsubscribe:    http://lists.mysql.com/commits?unsub=1
>

cheers,

Andrei
Thread
bk commit into 5.1 tree (cbell:1.2538)cbell16 Jul
  • Re: bk commit into 5.1 tree (cbell:1.2538) and wl3915 progress barAndrei Elkin17 Jul