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