From 12443de1b2c16970711336defee2e7c3d695d848 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 May 2006 15:00:38 +0200 Subject: [PATCH 01/37] WL#3259 (RBR with more columns on slave than on master): Extended replication to allow extra columns added last on slave as compared with table on master. mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Testing that replication can handle extra extra columns on slave. mysql-test/r/rpl_row_tabledefs.result: Result file change sql/Makefile.am: Adding new files. sql/field.cc: Implementing missing Field_bit::set_default() sql/field.h: Implementing missing Field_bit::set_default() sql/log_event.cc: Extending unpack_row() and replace_record() to handle the case when there are more columns on the slave than on the master. Especially handle BIT columns correctly. Using newly introduced table_def class to perform comparison. sql/log_event.h: Adding field to table_map_log_event. Changing prototype for do_prepare_row(). sql/mysql_priv.h: Adding include guards mysql-test/t/rpl_row_tabledefs.test: New BitKeeper file ``mysql-test/t/rpl_row_tabledefs.test'' sql/rpl_utility.cc: New BitKeeper file ``sql/rpl_utility.cc'' sql/rpl_utility.h: New BitKeeper file ``sql/rpl_utility.h'' --- .../extra/rpl_tests/rpl_row_tabledefs.test | 79 +++-- mysql-test/r/rpl_row_tabledefs.result | 142 ++++---- mysql-test/t/rpl_row_tabledefs.test | 8 + sql/Makefile.am | 4 +- sql/field.cc | 8 + sql/field.h | 2 + sql/log_event.cc | 327 +++++++++++------- sql/log_event.h | 35 +- sql/mysql_priv.h | 5 + sql/rpl_utility.cc | 156 +++++++++ sql/rpl_utility.h | 60 ++++ 11 files changed, 591 insertions(+), 235 deletions(-) create mode 100644 mysql-test/t/rpl_row_tabledefs.test create mode 100644 sql/rpl_utility.cc create mode 100644 sql/rpl_utility.h diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index 94a3af87ecd..0aabd633394 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -3,11 +3,16 @@ # Consider making these part of the basic RBR tests. --- source include/have_binlog_format_row.inc --- source include/master-slave.inc +connection slave; +STOP SLAVE; +SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; +START SLAVE; connection master; -eval CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; +eval CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; eval CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; eval CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; eval CREATE TABLE t4 (a INT) ENGINE=$engine_type; @@ -15,15 +20,21 @@ eval CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=$engine_type; eval CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=$engine_type; # Table used to detect that slave is running -eval CREATE TABLE t9 (a INT PRIMARY KEY) ENGINE=$engine_type; +eval CREATE TABLE t9 (a INT) ENGINE=$engine_type; sync_slave_with_master; -# On the slave, we add one column last in table 't1', -ALTER TABLE t1 ADD x INT DEFAULT 42; -# ... add one column in the middle of table 't2', and -ALTER TABLE t2 ADD x INT DEFAULT 42 AFTER a; -# ... add one column first in table 't3'. -ALTER TABLE t3 ADD x INT DEFAULT 42 FIRST; + +# On the slave, we add one INT column last in table 't1_int', +ALTER TABLE t1_int ADD x INT DEFAULT 42; +# ... and add one BIT column last in table 't1_bit', +ALTER TABLE t1_bit ADD x BIT(3) DEFAULT b'011'; +# ... and add one CHAR column last in table 't1_char', +ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; +# ... and add one non-nullable INT column last in table 't1_text' +# with no default, +ALTER TABLE t1_nodef ADD x INT NOT NULL; +# ... and remove the last column in t2 +ALTER TABLE t2 DROP b; # ... change the type of the single column in table 't4' ALTER TABLE t4 MODIFY a FLOAT; # ... change the type of the middle column of table 't5' @@ -31,13 +42,37 @@ ALTER TABLE t5 MODIFY b FLOAT; # ... change the type of the last column of table 't6' ALTER TABLE t6 MODIFY c FLOAT; -# Each of these should generate an error and stop the slave +# Insert some values for tables on slave side. These should not be +# modified when the row from the master is applied. +INSERT INTO t1_int VALUES (2,4,4711); +INSERT INTO t1_char VALUES (2,4,'Foo is a bar'); +INSERT INTO t1_bit VALUES (2,4,b'101'); + +--echo **** On Master **** connection master; -INSERT INTO t9 VALUES (1); +INSERT INTO t1_int VALUES (1,2); +INSERT INTO t1_int VALUES (2,5); +INSERT INTO t1_bit VALUES (1,2); +INSERT INTO t1_bit VALUES (2,5); +INSERT INTO t1_char VALUES (1,2); +INSERT INTO t1_char VALUES (2,5); +SELECT * FROM t1_int; +SELECT * FROM t1_bit; +SELECT * FROM t1_char; +--echo **** On Slave **** +sync_slave_with_master; +SELECT a,b,x FROM t1_int; +SELECT a,b,HEX(x) FROM t1_bit; +SELECT a,b,x FROM t1_char; + +# Each of these should generate an error and stop the slave + +connection master; +INSERT INTO t9 VALUES (2); sync_slave_with_master; # Now slave is guaranteed to be running connection master; -INSERT INTO t1 VALUES (1,2); +INSERT INTO t1_nodef VALUES (1,2); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT @@ -62,21 +97,6 @@ SHOW SLAVE STATUS; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; -connection master; -INSERT INTO t9 VALUES (3); -sync_slave_with_master; -# Now slave is guaranteed to be running -connection master; -INSERT INTO t3 VALUES (3,6); -connection slave; -wait_for_slave_to_stop; ---replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; - connection master; INSERT INTO t9 VALUES (4); sync_slave_with_master; @@ -124,6 +144,7 @@ START SLAVE; connection master; --disable_warnings -DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t9; +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; --enable_warnings sync_slave_with_master; diff --git a/mysql-test/r/rpl_row_tabledefs.result b/mysql-test/r/rpl_row_tabledefs.result index 715ffcc7578..31a7330041f 100644 --- a/mysql-test/r/rpl_row_tabledefs.result +++ b/mysql-test/r/rpl_row_tabledefs.result @@ -4,21 +4,64 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=myisam; -CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE=myisam; -CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=myisam; -CREATE TABLE t4 (a INT) ENGINE=myisam; -CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=myisam; -CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=myisam; -CREATE TABLE t9 (a INT PRIMARY KEY) ENGINE=myisam; -ALTER TABLE t1 ADD x INT DEFAULT 42; -ALTER TABLE t2 ADD x INT DEFAULT 42 AFTER a; -ALTER TABLE t3 ADD x INT DEFAULT 42 FIRST; +STOP SLAVE; +SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; +START SLAVE; +CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; +CREATE TABLE t4 (a INT) ENGINE='MyISAM'; +CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='MyISAM'; +CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='MyISAM'; +CREATE TABLE t9 (a INT) ENGINE='MyISAM'; +ALTER TABLE t1_int ADD x INT DEFAULT 42; +ALTER TABLE t1_bit ADD x BIT(3) DEFAULT b'011'; +ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; +ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t6 MODIFY c FLOAT; -INSERT INTO t9 VALUES (1); -INSERT INTO t1 VALUES (1,2); +INSERT INTO t1_int VALUES (2,4,4711); +INSERT INTO t1_char VALUES (2,4,'Foo is a bar'); +INSERT INTO t1_bit VALUES (2,4,b'101'); +**** On Master **** +INSERT INTO t1_int VALUES (1,2); +INSERT INTO t1_int VALUES (2,5); +INSERT INTO t1_bit VALUES (1,2); +INSERT INTO t1_bit VALUES (2,5); +INSERT INTO t1_char VALUES (1,2); +INSERT INTO t1_char VALUES (2,5); +SELECT * FROM t1_int; +a b +1 2 +2 5 +SELECT * FROM t1_bit; +a b +1 2 +2 5 +SELECT * FROM t1_char; +a b +1 2 +2 5 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +2 5 4711 +1 2 42 +SELECT a,b,HEX(x) FROM t1_bit; +a b HEX(x) +2 5 5 +1 2 3 +SELECT a,b,x FROM t1_char; +a b x +2 5 Foo is a bar +1 2 Just a test +INSERT INTO t9 VALUES (2); +INSERT INTO t1_nodef VALUES (1,2); SHOW SLAVE STATUS; Slave_IO_State # Master_Host 127.0.0.1 @@ -26,7 +69,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1042 +Read_Master_Log_Pos 1934 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -38,10 +81,10 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1454 -Last_Error Table width mismatch - received 2 columns, test.t1 has 3 columns +Last_Errno 1364 +Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef Skip_Counter 0 -Exec_Master_Log_Pos 968 +Exec_Master_Log_Pos 1850 Relay_Log_Space # Until_Condition None Until_Log_File @@ -64,7 +107,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1185 +Read_Master_Log_Pos 2085 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -76,48 +119,10 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1454 -Last_Error Table width mismatch - received 2 columns, test.t2 has 3 columns +Last_Errno 1514 +Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns Skip_Counter 0 -Exec_Master_Log_Pos 1111 -Relay_Log_Space # -Until_Condition None -Until_Log_File -Until_Log_Pos 0 -Master_SSL_Allowed No -Master_SSL_CA_File -Master_SSL_CA_Path -Master_SSL_Cert -Master_SSL_Cipher -Master_SSL_Key -Seconds_Behind_Master # -SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; -START SLAVE; -INSERT INTO t9 VALUES (3); -INSERT INTO t3 VALUES (3,6); -SHOW SLAVE STATUS; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_PORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1328 -Relay_Log_File # -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running Yes -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 1454 -Last_Error Table width mismatch - received 2 columns, test.t3 has 3 columns -Skip_Counter 0 -Exec_Master_Log_Pos 1254 +Exec_Master_Log_Pos 2007 Relay_Log_Space # Until_Condition None Until_Log_File @@ -140,7 +145,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1466 +Read_Master_Log_Pos 2231 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -152,10 +157,10 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1454 +Last_Errno 1514 Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 1397 +Exec_Master_Log_Pos 2158 Relay_Log_Space # Until_Condition None Until_Log_File @@ -178,7 +183,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1614 +Read_Master_Log_Pos 2387 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -190,10 +195,10 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1454 +Last_Errno 1514 Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 1535 +Exec_Master_Log_Pos 2304 Relay_Log_Space # Until_Condition None Until_Log_File @@ -216,7 +221,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1762 +Read_Master_Log_Pos 2543 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -228,10 +233,10 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1454 +Last_Errno 1514 Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 1683 +Exec_Master_Log_Pos 2460 Relay_Log_Space # Until_Condition None Until_Log_File @@ -245,4 +250,5 @@ Master_SSL_Key Seconds_Behind_Master # SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; -DROP TABLE IF EXISTS t1,t2,t3,t4,t5,t6,t9; +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; diff --git a/mysql-test/t/rpl_row_tabledefs.test b/mysql-test/t/rpl_row_tabledefs.test new file mode 100644 index 00000000000..ab4914e15fa --- /dev/null +++ b/mysql-test/t/rpl_row_tabledefs.test @@ -0,0 +1,8 @@ + +-- source include/have_binlog_format_row.inc +-- source include/master-slave.inc + +let $engine_type = 'MyISAM'; +-- source extra/rpl_tests/rpl_row_tabledefs.test + + diff --git a/sql/Makefile.am b/sql/Makefile.am index 60e7891931f..71c91cdf7fa 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -53,7 +53,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ sql_manager.h sql_map.h sql_string.h unireg.h \ sql_error.h field.h handler.h mysqld_suffix.h \ ha_heap.h ha_myisam.h ha_myisammrg.h ha_partition.h \ - opt_range.h protocol.h rpl_tblmap.h \ + opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \ log.h sql_show.h rpl_rli.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ @@ -91,7 +91,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \ - rpl_injector.cc \ + rpl_utility.cc rpl_injector.cc \ sql_union.cc sql_derived.cc \ client.c sql_client.cc mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc \ diff --git a/sql/field.cc b/sql/field.cc index 1176257359f..32e63597c30 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8259,6 +8259,14 @@ const char *Field_bit::unpack(char *to, const char *from) } +void Field_bit::set_default() +{ + my_ptrdiff_t const offset= table->s->default_values - table->record[0]; + uchar bits= get_rec_bits(bit_ptr + offset, bit_ofs, bit_len); + set_rec_bits(bits, bit_ptr, bit_ofs, bit_len); + Field::set_default(); +} + /* Bit field support for non-MyISAM tables. */ diff --git a/sql/field.h b/sql/field.h index b473100eaab..d8dcb85fd5a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1384,6 +1384,8 @@ public: void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); const char *unpack(char* to, const char *from); + virtual void set_default(); + Field *new_key_field(MEM_ROOT *root, struct st_table *new_table, char *new_ptr, uchar *new_null_ptr, uint new_null_bit); diff --git a/sql/log_event.cc b/sql/log_event.cc index 8a39b1fc4eb..3164a62d876 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -24,6 +24,7 @@ #include "mysql_priv.h" #include "slave.h" #include "rpl_filter.h" +#include "rpl_utility.h" #include #endif /* MYSQL_CLIENT */ #include @@ -5258,38 +5259,86 @@ int Rows_log_event::do_add_row_data(byte *const row_data, #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) /* - Unpack a row into a record. The row is assumed to only consist of the fields - for which the bitset represented by 'arr' and 'bits'; the other parts of the + Unpack a row into a record. + + The row is assumed to only consist of the fields for which the + bitset represented by 'arr' and 'bits'; the other parts of the record are left alone. + + At most 'colcnt' columns are read: if the table is larger than that, + the remaining fields are not filled in. */ -static char const *unpack_row(TABLE *table, - byte *record, char const *row, - MY_BITMAP const *cols) +static int +unpack_row(RELAY_LOG_INFO *rli, + TABLE *table, uint colcnt, byte *record, + char const *row, MY_BITMAP const *cols, + char const **row_end, ulong *master_reclength) { DBUG_ASSERT(record && row); - MY_BITMAP *write_set= table->file->write_set; + my_size_t const n_null_bytes= table->s->null_bytes; my_ptrdiff_t const offset= record - (byte*) table->record[0]; - - memcpy(record, row, n_null_bytes); - char const *ptr= row + n_null_bytes; + memcpy(record, row, n_null_bytes); // [1] + int error= 0; bitmap_set_all(write_set); - Field **const begin_ptr = table->field; - for (Field **field_ptr= begin_ptr ; *field_ptr ; ++field_ptr) - { - Field *const f= *field_ptr; - if (bitmap_is_set(cols, field_ptr - begin_ptr)) + Field **const begin_ptr = table->field; + Field **field_ptr; + { + char const *ptr= row + n_null_bytes; + for (field_ptr= begin_ptr ; *field_ptr ; ++field_ptr) { - /* Field...::unpack() cannot return 0 */ - ptr= f->unpack(f->ptr + offset, ptr); + Field *const f= *field_ptr; + + if (colcnt == 0) + break; + + if (bitmap_is_set(cols, field_ptr - begin_ptr)) + { + /* Field...::unpack() cannot return 0 */ + ptr= f->unpack(f->ptr + offset, ptr); + --colcnt; + } + else + bitmap_clear_bit(write_set, (field_ptr - begin_ptr) + 1); + } + + *row_end = ptr; + if (master_reclength) + { + if (*field_ptr) + *master_reclength = (*field_ptr)->ptr - table->record[0]; + else + *master_reclength = table->s->reclength; + } + } + + /* + Set properties for remaining columns, if there are any. We let the + corresponding bit in the write_set be set, to write the value if + it was not there already. We iterate over all remaining columns, + even if there were an error, to get as many error messages as + possible. We are still able to return a pointer to the next row, + so wedo that. + */ + for ( ; *field_ptr ; ++field_ptr) + { + if ((*field_ptr)->flags & (NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG)) + { + slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD, + "Field `%s` of table `%s`.`%s` " + "has no default value and cannot be NULL", + (*field_ptr)->field_name, table->s->db.str, + table->s->table_name.str); + error = ER_NO_DEFAULT_FOR_FIELD; } else - bitmap_clear_bit(write_set, (field_ptr - begin_ptr) + 1); + (*field_ptr)->set_default(); } - return ptr; + + return error; } int Rows_log_event::exec_event(st_relay_log_info *rli) @@ -5444,7 +5493,11 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) error= do_before_row_operations(table); while (error == 0 && row_start < (const char*)m_rows_end) { - char const *row_end= do_prepare_row(thd, table, row_start); + char const *row_end= NULL; + if ((error= do_prepare_row(thd, rli, table, row_start, &row_end))) + break; // We should to the after-row operation even in the + // case of error + DBUG_ASSERT(row_end != NULL); // cannot happen DBUG_ASSERT(row_end <= (const char*)m_rows_end); @@ -5646,7 +5699,7 @@ void Rows_log_event::pack_info(Protocol *protocol) #endif /************************************************************************** - Table_map_log_event member functions + Table_map_log_event member functions and support functions **************************************************************************/ /* @@ -5910,71 +5963,9 @@ int Table_map_log_event::exec_event(st_relay_log_info *rli) */ DBUG_ASSERT(m_table->in_use); - /* - Check that the number of columns and the field types in the - event match the number of columns and field types in the opened - table. - */ - uint col= m_table->s->fields; - - if (col == m_colcnt) + table_def const def(m_coltype, m_colcnt); + if (def.compatible_with(rli, m_table)) { - while (col-- > 0) - if (m_table->field[col]->type() != m_coltype[col]) - break; - } - - TABLE_SHARE const *const tsh= m_table->s; - - /* - Check the following termination conditions: - - (col == m_table->s->fields) - ==> (m_table->s->fields != m_colcnt) - (0 <= col < m_table->s->fields) - ==> (m_table->field[col]->type() != m_coltype[col]) - - Logically, A ==> B is equivalent to !A || B - - Since col is unsigned, is suffices to check that col <= - tsh->fields. If col wrapped (by decreasing col when it is 0), - the number will be UINT_MAX, which is greater than tsh->fields. - */ - DBUG_ASSERT(!(col == tsh->fields) || tsh->fields != m_colcnt); - DBUG_ASSERT(!(col < tsh->fields) || - (m_table->field[col]->type() != m_coltype[col])); - - if (col <= tsh->fields) - { - /* - If we get here, the number of columns in the event didn't - match the number of columns in the table on the slave, *or* - there were a column in the table on the slave that did not - have the same type as given in the event. - - If 'col' has the value that was assigned to it, it was a - mismatch between the number of columns on the master and the - slave. - */ - if (col == tsh->fields) - { - DBUG_ASSERT(tsh->db.str && tsh->table_name.str); - slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, - "Table width mismatch - " - "received %u columns, %s.%s has %u columns", - m_colcnt, tsh->db.str, tsh->table_name.str, tsh->fields); - } - else - { - DBUG_ASSERT(col < m_colcnt && col < tsh->fields); - DBUG_ASSERT(tsh->db.str && tsh->table_name.str); - slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, - "Column %d type mismatch - " - "received type %d, %s.%s has type %d", - col, m_coltype[col], tsh->db.str, tsh->table_name.str, - m_table->field[col]->type()); - } - thd->query_error= 1; DBUG_RETURN(ERR_BAD_TABLE_DEF); } @@ -6085,6 +6076,25 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) } #endif +#ifndef DBUG_OFF +static void +print_column_values(char const *text, THD *thd, TABLE *table) +{ + THD *old_thd= table->in_use; + if (table->in_use == NULL) + table->in_use= thd; + for (Field **fptr= table->field ; *fptr ; ++fptr) + { + char buf[MAX_FIELD_WIDTH]; + String str(buf, sizeof(buf), system_charset_info); + (*fptr)->val_str(&str); + DBUG_PRINT("info", ("%s for column %d is '%s'", + text, fptr - table->field, str.c_ptr())); + } + table->in_use= old_thd; +} +#endif + /************************************************************************** Write_rows_log_event member functions **************************************************************************/ @@ -6169,19 +6179,22 @@ int Write_rows_log_event::do_after_row_operations(TABLE *table, int error) return error; } -char const *Write_rows_log_event::do_prepare_row(THD *thd, TABLE *table, - char const *row_start) +int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, + TABLE *table, + char const *row_start, + char const **row_end) { - char const *ptr= row_start; DBUG_ASSERT(table != NULL); - /* - This assertion actually checks that there is at least as many - columns on the slave as on the master. - */ - DBUG_ASSERT(table->s->fields >= m_width); - DBUG_ASSERT(ptr); - ptr= unpack_row(table, (byte*)table->record[0], ptr, &m_cols); - return ptr; + DBUG_ASSERT(row_start && row_end); + + int error; + error= unpack_row(rli, + table, m_width, (byte*)table->record[0], + row_start, &m_cols, row_end, &m_master_reclength); +#ifndef DBUG_OFF + print_column_values("Unpacked value", thd, table); +#endif + return error; } /* @@ -6237,24 +6250,33 @@ namespace { @param thd Thread context for writing the record. @param table Table to which record should be written. - + @param master_reclength + Offset to first column that is not present on the master, + alternatively the length of the record on the master side. @return Error code on failure, 0 on success. */ static int -replace_record(THD *thd, TABLE *table) +replace_record(THD *thd, TABLE *table, + ulong const master_reclength, + uint const master_fields) { + DBUG_ENTER("replace_record"); DBUG_ASSERT(table != NULL && thd != NULL); int error; int keynum; auto_afree_ptr key(NULL); +#ifndef DBUG_OFF + print_column_values("Starting write value", thd, table); +#endif + while ((error= table->file->ha_write_row(table->record[0]))) { if ((keynum= table->file->get_dup_key(error)) < 0) { /* We failed to retrieve the duplicate key */ - return HA_ERR_FOUND_DUPP_KEY; + DBUG_RETURN(HA_ERR_FOUND_DUPP_KEY); } /* @@ -6271,20 +6293,20 @@ replace_record(THD *thd, TABLE *table) { error= table->file->rnd_pos(table->record[1], table->file->dupp_ref); if (error) - return error; + DBUG_RETURN(error); } else { if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) { - return my_errno; + DBUG_RETURN(my_errno); } if (key.get() == NULL) { key.assign(static_cast(my_alloca(table->s->max_unique_length))); if (key.get() == NULL) - return ENOMEM; + DBUG_RETURN(ENOMEM); } key_copy((byte*)key.get(), table->record[0], table->key_info + keynum, 0); @@ -6293,7 +6315,7 @@ replace_record(THD *thd, TABLE *table) table->key_info[keynum].key_length, HA_READ_KEY_EXACT); if (error) - return error; + DBUG_RETURN(error); } /* @@ -6301,6 +6323,59 @@ replace_record(THD *thd, TABLE *table) will enable us to update it or, alternatively, delete it (so that we can insert the new row afterwards). + First we copy the columns into table->record[0] that are not + present on the master from table->record[1], if there are any. + */ + + DBUG_PRINT("info", ("Copying to %p from offset %u to %u", + table->record[0], + master_reclength, table->s->reclength)); +#ifndef DBUG_OFF + print_column_values("After copy value", thd, table); +#endif + if (master_reclength < table->s->reclength) + bmove_align(table->record[0] + master_reclength, + table->record[1] + master_reclength, + table->s->reclength - master_reclength); + + /* + Bit columns are special. We iterate over all the remaining + columns and copy the "extra" bits to the new record. This is + not a very good solution: it should be refactored on + opportunity. + + REFACTORING SUGGESTION (Matz). Introduce a member function + similar to move_field_offset() called copy_field_offset() to + copy field values and implement it for all Field subclasses. Use + this function to copy data from the found record to the record + that are going to be inserted. + + The copy_field_offset() function need to be a virtual function, + which in this case will prevent copying an entire range of + fields efficiently. + */ + { + Field **field_ptr= table->field + master_fields; + for ( ; *field_ptr ; ++field_ptr) + { + switch ((*field_ptr)->real_type()) + { + default: + /* Nothing to do */ + break; + + case FIELD_TYPE_BIT: + Field_bit *f= static_cast(*field_ptr); + my_ptrdiff_t const offset= table->record[1] - table->record[0]; + uchar const bits= + get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len); + set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len); + break; + } + } + } + + /* REPLACE is defined as either INSERT or DELETE + INSERT. If possible, we can replace it with an UPDATE, but that will not work on InnoDB if FOREIGN KEY checks are necessary. @@ -6320,22 +6395,22 @@ replace_record(THD *thd, TABLE *table) { error=table->file->ha_update_row(table->record[1], table->record[0]); - return error; + DBUG_RETURN(error); } else { if ((error= table->file->ha_delete_row(table->record[1]))) - return error; + DBUG_RETURN(error); /* Will retry ha_write_row() with the offending row removed. */ } } - return error; + DBUG_RETURN(error); } int Write_rows_log_event::do_exec_row(TABLE *table) { DBUG_ASSERT(table != NULL); - int error= replace_record(thd, table); + int error= replace_record(thd, table, m_master_reclength, m_width); return error; } #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ @@ -6606,20 +6681,22 @@ int Delete_rows_log_event::do_after_row_operations(TABLE *table, int error) return error; } -char const *Delete_rows_log_event::do_prepare_row(THD *thd, TABLE *table, - char const *row_start) +int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, + TABLE *table, + char const *row_start, + char const **row_end) { - char const *ptr= row_start; - DBUG_ASSERT(ptr); + int error; + DBUG_ASSERT(row_start && row_end); /* This assertion actually checks that there is at least as many columns on the slave as on the master. */ DBUG_ASSERT(table->s->fields >= m_width); - DBUG_ASSERT(ptr != NULL); - ptr= unpack_row(table, table->record[0], ptr, &m_cols); - + error= unpack_row(rli, + table, m_width, table->record[0], + row_start, &m_cols, row_end, &m_master_reclength); /* If we will access rows using the random access method, m_key will be set to NULL, so we do not need to make a key copy in that case. @@ -6631,7 +6708,7 @@ char const *Delete_rows_log_event::do_prepare_row(THD *thd, TABLE *table, key_copy(m_key, table->record[0], key_info, 0); } - return ptr; + return error; } int Delete_rows_log_event::do_exec_row(TABLE *table) @@ -6757,11 +6834,13 @@ int Update_rows_log_event::do_after_row_operations(TABLE *table, int error) return error; } -char const *Update_rows_log_event::do_prepare_row(THD *thd, TABLE *table, - char const *row_start) +int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, + TABLE *table, + char const *row_start, + char const **row_end) { - char const *ptr= row_start; - DBUG_ASSERT(ptr); + int error; + DBUG_ASSERT(row_start && row_end); /* This assertion actually checks that there is at least as many columns on the slave as on the master. @@ -6769,10 +6848,14 @@ char const *Update_rows_log_event::do_prepare_row(THD *thd, TABLE *table, DBUG_ASSERT(table->s->fields >= m_width); /* record[0] is the before image for the update */ - ptr= unpack_row(table, table->record[0], ptr, &m_cols); - DBUG_ASSERT(ptr != NULL); + error= unpack_row(rli, + table, m_width, table->record[0], + row_start, &m_cols, row_end, &m_master_reclength); + row_start = *row_end; /* m_after_image is the after image for the update */ - ptr= unpack_row(table, m_after_image, ptr, &m_cols); + error= unpack_row(rli, + table, m_width, m_after_image, + row_start, &m_cols, row_end, &m_master_reclength); /* If we will access rows using the random access method, m_key will @@ -6785,7 +6868,7 @@ char const *Update_rows_log_event::do_prepare_row(THD *thd, TABLE *table, key_copy(m_key, table->record[0], key_info, 0); } - return ptr; + return error; } int Update_rows_log_event::do_exec_row(TABLE *table) diff --git a/sql/log_event.h b/sql/log_event.h index b24686514e3..5f0d31b4e11 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1854,6 +1854,7 @@ protected: ulong m_table_id; /* Table ID */ MY_BITMAP m_cols; /* Bitmap denoting columns available */ ulong m_width; /* The width of the columns bitmap */ + ulong m_master_reclength; /* Length of record on master side */ /* Bit buffer in the same memory as the class */ uint32 m_bitbuf[128/(sizeof(uint32)*8)]; @@ -1907,12 +1908,15 @@ private: since SQL thread specific data is not available: that data is made available for the do_exec function. - RETURN VALUE A pointer to the start of the next row, or NULL if the preparation failed. Currently, preparation cannot fail, but don't rely on this behavior. + + RETURN VALUE + Error code, if something went wrong, 0 otherwise. */ - virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start) = 0; + virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*, + char const *row_start, char const **row_end) = 0; /* Primitive to do the actual execution necessary for a row. @@ -1980,10 +1984,11 @@ private: gptr m_memory; byte *m_after_image; - virtual int do_before_row_operations(TABLE *table); - virtual int do_after_row_operations(TABLE *table, int error); - virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); - virtual int do_exec_row(TABLE *table); + virtual int do_before_row_operations(TABLE *table); + virtual int do_after_row_operations(TABLE *table, int error); + virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*, + char const *row_start, char const **row_end); + virtual int do_exec_row(TABLE *table); #endif }; @@ -2044,10 +2049,11 @@ private: byte *m_key; byte *m_after_image; - virtual int do_before_row_operations(TABLE *table); - virtual int do_after_row_operations(TABLE *table, int error); - virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); - virtual int do_exec_row(TABLE *table); + virtual int do_before_row_operations(TABLE *table); + virtual int do_after_row_operations(TABLE *table, int error); + virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*, + char const *row_start, char const **row_end); + virtual int do_exec_row(TABLE *table); #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */ }; @@ -2114,10 +2120,11 @@ private: byte *m_key; byte *m_after_image; - virtual int do_before_row_operations(TABLE *table); - virtual int do_after_row_operations(TABLE *table, int error); - virtual char const *do_prepare_row(THD*, TABLE*, char const *row_start); - virtual int do_exec_row(TABLE *table); + virtual int do_before_row_operations(TABLE *table); + virtual int do_after_row_operations(TABLE *table, int error); + virtual int do_prepare_row(THD*, RELAY_LOG_INFO*, TABLE*, + char const *row_start, char const **row_end); + virtual int do_exec_row(TABLE *table); #endif }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c471b11fee2..b362be6d3b7 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -21,6 +21,9 @@ except the part which must be in the server and in the client. */ +#ifndef MYSQL_PRIV_H +#define MYSQL_PRIV_H + #ifndef MYSQL_CLIENT #include @@ -1773,3 +1776,5 @@ bool schema_table_store_record(THD *thd, TABLE *table); #endif /* MYSQL_SERVER */ #endif /* MYSQL_CLIENT */ + +#endif /* MYSQL_PRIV_H */ diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc new file mode 100644 index 00000000000..fc706178aa3 --- /dev/null +++ b/sql/rpl_utility.cc @@ -0,0 +1,156 @@ +/* Copyright 2006 MySQL AB. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "rpl_utility.h" + +uint32 +field_length_from_packed(enum_field_types const field_type, + byte const *const data) +{ + uint32 length; + + switch (field_type) { + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_NEWDECIMAL: + length= ~0UL; + break; + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_TINY: + length= 1; + break; + case MYSQL_TYPE_SHORT: + length= 2; + break; + case MYSQL_TYPE_INT24: + length= 3; + break; + case MYSQL_TYPE_LONG: + length= 4; + break; +#ifdef HAVE_LONG_LONG + case MYSQL_TYPE_LONGLONG: + 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; + case MYSQL_TYPE_NEWDATE: + length= 3; + break; + case MYSQL_TYPE_DATE: + length= 4; + break; + case MYSQL_TYPE_TIME: + length= 3; + break; + case MYSQL_TYPE_TIMESTAMP: + length= 4; + break; + case MYSQL_TYPE_DATETIME: + length= 8; + break; + break; + case MYSQL_TYPE_BIT: + length= ~0UL; + 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= ~0UL; // NYI + 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= ~0UL; // NYI + break; + } +} + +/********************************************************************* + * table_def member definitions * + *********************************************************************/ + +/* + Is the definition compatible with a table? + + Compare the definition with a table to see if it is compatible with + it. A table definition is compatible with a table if + - the columns types of the table definition is a (not necessarily + proper) prefix of the column type of the table, or + - the other way around +*/ +int +table_def::compatible_with(RELAY_LOG_INFO *rli, TABLE *table) + const +{ + /* + We only check the initial columns for the tables. + */ + uint const cols_to_check= min(table->s->fields, size()); + int error= 0; + + TABLE_SHARE const *const tsh= table->s; + + /* + To get proper error reporting for all columns of the table, we + both check the width and iterate over all columns. + */ + if (tsh->fields < size()) + { + DBUG_ASSERT(tsh->db.str && tsh->table_name.str); + error= 1; + slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, + "Table width mismatch - " + "received %u columns, %s.%s has %u columns", + size(), tsh->db.str, tsh->table_name.str, tsh->fields); + } + + for (uint col= 0 ; col < cols_to_check ; ++col) + { + if (table->field[col]->type() != type(col)) + { + DBUG_ASSERT(col < size() && col < tsh->fields); + DBUG_ASSERT(tsh->db.str && tsh->table_name.str); + error= 1; + slave_print_msg(ERROR_LEVEL, rli, ER_BINLOG_ROW_WRONG_TABLE_DEF, + "Column %d type mismatch - " + "received type %d, %s.%s has type %d", + col, type(col), tsh->db.str, tsh->table_name.str, + table->field[col]->type()); + } + } + + return error; +} diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h new file mode 100644 index 00000000000..0ac3c10eec6 --- /dev/null +++ b/sql/rpl_utility.h @@ -0,0 +1,60 @@ +/* Copyright 2006 MySQL AB. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#ifndef RPL_UTILITY_H +#define RPL_UTILITY_H + +#ifndef __cplusplus +#error "Don't include this C++ header file from a non-C++ file!" +#endif + +#include "mysql_priv.h" + +uint32 +field_length_from_packed(enum_field_types const field_type, + byte const *const data); + +/* + A table definition from the master. + + RESPONSIBILITIES + + - Extract table definition data from the table map event + - Check if table definition in table map is compatible with table + definition on slave + */ + +class table_def +{ +public: + typedef unsigned char field_type; + + table_def(field_type *t, my_size_t s) + : m_type(t), m_size(s) + { + } + + my_size_t size() const { return m_size; } + field_type type(my_ptrdiff_t i) const { return m_type[i]; } + + int compatible_with(RELAY_LOG_INFO *rli, TABLE *table) const; + +private: + my_size_t m_size; + field_type *m_type; +}; + +#endif /* RPL_UTILITY_H */ From 9a7ad1bf132f1d4fc3f774f4ef2ea66053147f02 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 May 2006 11:15:14 +0200 Subject: [PATCH 02/37] bug (colcnt) + compile fix mysql-test/t/disabled.def: disabled hanging test --- mysql-test/t/disabled.def | 1 + sql/log_event.cc | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index c0827e09990..a3bedbaa22d 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -24,6 +24,7 @@ rpl_deadlock_innodb : BUG#16920 2006-04-12 kent fails in show slave stat rpl_ndb_2innodb : BUG#19004 2006-03-22 tomas ndb: partition by range and update hangs rpl_ndb_2myisam : BUG#19004 2006-03-22 tomas ndb: partition by range and update hangs rpl_ndb_auto_inc : BUG#17086 2006-02-16 jmiller CR: auto_increment_increment and auto_increment_offset produce duplicate key er +rpl_ndb_commit_afterflush : LOCK TABLES cases hang in ndb injector thread rpl_ndb_ddl : result file needs update + test needs to checked rpl_ndb_innodb2ndb : BUG#18094 2006-03-16 mats Slave caches invalid table definition after atlters causes select failure rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ diff --git a/sql/log_event.cc b/sql/log_event.cc index 3164a62d876..9991656c3eb 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5294,12 +5294,11 @@ unpack_row(RELAY_LOG_INFO *rli, if (colcnt == 0) break; - + --colcnt; if (bitmap_is_set(cols, field_ptr - begin_ptr)) { /* Field...::unpack() cannot return 0 */ ptr= f->unpack(f->ptr + offset, ptr); - --colcnt; } else bitmap_clear_bit(write_set, (field_ptr - begin_ptr) + 1); @@ -6076,6 +6075,7 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) } #endif +#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) #ifndef DBUG_OFF static void print_column_values(char const *text, THD *thd, TABLE *table) @@ -6094,6 +6094,7 @@ print_column_values(char const *text, THD *thd, TABLE *table) table->in_use= old_thd; } #endif +#endif /************************************************************************** Write_rows_log_event member functions From 16105170c00aa1e403d47e8fb4a673ba8a623197 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 May 2006 20:05:25 +0200 Subject: [PATCH 03/37] WL#3259 (RBR with more columns on slave than on master): Added support for UPDATE. Some minor fixes. mysql-test/t/rpl_row_tabledefs_2myisam.test: Rename: mysql-test/t/rpl_row_tabledefs.test -> mysql-test/t/rpl_row_tabledefs_2myisam.test mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Extending test to ensure that there is one more null byte on slave than it is on the master. Some cleanup. sql/field.cc: Added support to find the last null byte for a field. sql/field.h: Added support to find the last null byte for a field. sql/log_event.cc: unpack_row() will now deduce the number of null bytes on the slave and use that when copying the null bytes from the row. Factored out code to copy "extra" record fields into separate function. Used that function to copy the "extra" fields when updating a row as well. mysql-test/r/rpl_row_tabledefs_2myisam.result: Result change mysql-test/r/rpl_row_tabledefs_3innodb.result: New BitKeeper file ``mysql-test/r/rpl_row_tabledefs_3innodb.result'' mysql-test/r/rpl_row_tabledefs_7ndb.result: New BitKeeper file ``mysql-test/r/rpl_row_tabledefs_7ndb.result'' mysql-test/t/rpl_row_tabledefs_3innodb.test: New BitKeeper file ``mysql-test/t/rpl_row_tabledefs_3innodb.test'' --- .../extra/rpl_tests/rpl_row_tabledefs.test | 64 ++-- ...esult => rpl_row_tabledefs_2myisam.result} | 68 +++-- mysql-test/r/rpl_row_tabledefs_3innodb.result | 286 ++++++++++++++++++ mysql-test/r/rpl_row_tabledefs_7ndb.result | 286 ++++++++++++++++++ ...fs.test => rpl_row_tabledefs_2myisam.test} | 0 mysql-test/t/rpl_row_tabledefs_3innodb.test | 9 + sql/field.cc | 32 ++ sql/field.h | 19 ++ sql/log_event.cc | 169 +++++++---- 9 files changed, 828 insertions(+), 105 deletions(-) rename mysql-test/r/{rpl_row_tabledefs.result => rpl_row_tabledefs_2myisam.result} (84%) create mode 100644 mysql-test/r/rpl_row_tabledefs_3innodb.result create mode 100644 mysql-test/r/rpl_row_tabledefs_7ndb.result rename mysql-test/t/{rpl_row_tabledefs.test => rpl_row_tabledefs_2myisam.test} (100%) create mode 100644 mysql-test/t/rpl_row_tabledefs_3innodb.test diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index 0aabd633394..b17103d8396 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -3,7 +3,14 @@ # Consider making these part of the basic RBR tests. -connection slave; +connection master; +--disable_warnings +--disable_query_log +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; +--enable_query_log +--enable_warnings +sync_slave_with_master; STOP SLAVE; SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; START SLAVE; @@ -26,8 +33,12 @@ sync_slave_with_master; # On the slave, we add one INT column last in table 't1_int', ALTER TABLE t1_int ADD x INT DEFAULT 42; -# ... and add one BIT column last in table 't1_bit', -ALTER TABLE t1_bit ADD x BIT(3) DEFAULT b'011'; +# ... and add BIT columns last in table 't1_bit' to ensure that we +# have at least one extra null byte on the slave, +ALTER TABLE t1_bit + ADD x BIT(3) DEFAULT b'011', + ADD y BIT(5) DEFAULT b'10101', + ADD z BIT(2) DEFAULT b'10'; # ... and add one CHAR column last in table 't1_char', ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; # ... and add one non-nullable INT column last in table 't1_text' @@ -44,9 +55,9 @@ ALTER TABLE t6 MODIFY c FLOAT; # Insert some values for tables on slave side. These should not be # modified when the row from the master is applied. -INSERT INTO t1_int VALUES (2,4,4711); -INSERT INTO t1_char VALUES (2,4,'Foo is a bar'); -INSERT INTO t1_bit VALUES (2,4,b'101'); +INSERT INTO t1_int VALUES (2, 4, 4711); +INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); +INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); --echo **** On Master **** connection master; @@ -62,7 +73,21 @@ SELECT * FROM t1_char; --echo **** On Slave **** sync_slave_with_master; SELECT a,b,x FROM t1_int; -SELECT a,b,HEX(x) FROM t1_bit; +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +SELECT a,b,x FROM t1_char; + +--echo **** On Master **** +connection master; +UPDATE t1_int SET b=2*b WHERE a=2; +UPDATE t1_char SET b=2*b WHERE a=2; +UPDATE t1_bit SET b=2*b WHERE a=2; +SELECT * FROM t1_int; +SELECT * FROM t1_bit; +SELECT * FROM t1_char; +--echo **** On Slave **** +sync_slave_with_master; +SELECT a,b,x FROM t1_int; +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; SELECT a,b,x FROM t1_char; # Each of these should generate an error and stop the slave @@ -76,9 +101,8 @@ INSERT INTO t1_nodef VALUES (1,2); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -91,9 +115,8 @@ INSERT INTO t2 VALUES (2,4); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -106,9 +129,8 @@ INSERT INTO t4 VALUES (4); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -121,9 +143,8 @@ INSERT INTO t5 VALUES (5,10,25); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -136,9 +157,8 @@ INSERT INTO t6 VALUES (6,12,36); connection slave; wait_for_slave_to_stop; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 8 # 9 # 23 # 33 # ---vertical_results -SHOW SLAVE STATUS; +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; diff --git a/mysql-test/r/rpl_row_tabledefs.result b/mysql-test/r/rpl_row_tabledefs_2myisam.result similarity index 84% rename from mysql-test/r/rpl_row_tabledefs.result rename to mysql-test/r/rpl_row_tabledefs_2myisam.result index 31a7330041f..37559b0412a 100644 --- a/mysql-test/r/rpl_row_tabledefs.result +++ b/mysql-test/r/rpl_row_tabledefs_2myisam.result @@ -18,16 +18,19 @@ CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='MyISAM'; CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='MyISAM'; CREATE TABLE t9 (a INT) ENGINE='MyISAM'; ALTER TABLE t1_int ADD x INT DEFAULT 42; -ALTER TABLE t1_bit ADD x BIT(3) DEFAULT b'011'; +ALTER TABLE t1_bit +ADD x BIT(3) DEFAULT b'011', +ADD y BIT(5) DEFAULT b'10101', +ADD z BIT(2) DEFAULT b'10'; ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; ALTER TABLE t1_nodef ADD x INT NOT NULL; ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t6 MODIFY c FLOAT; -INSERT INTO t1_int VALUES (2,4,4711); -INSERT INTO t1_char VALUES (2,4,'Foo is a bar'); -INSERT INTO t1_bit VALUES (2,4,b'101'); +INSERT INTO t1_int VALUES (2, 4, 4711); +INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); +INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); **** On Master **** INSERT INTO t1_int VALUES (1,2); INSERT INTO t1_int VALUES (2,5); @@ -52,14 +55,43 @@ SELECT a,b,x FROM t1_int; a b x 2 5 4711 1 2 42 -SELECT a,b,HEX(x) FROM t1_bit; -a b HEX(x) -2 5 5 -1 2 3 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +2 5 5 1C 1 +1 2 3 15 2 SELECT a,b,x FROM t1_char; a b x 2 5 Foo is a bar 1 2 Just a test +**** On Master **** +UPDATE t1_int SET b=2*b WHERE a=2; +UPDATE t1_char SET b=2*b WHERE a=2; +UPDATE t1_bit SET b=2*b WHERE a=2; +SELECT * FROM t1_int; +a b +1 2 +2 10 +SELECT * FROM t1_bit; +a b +1 2 +2 10 +SELECT * FROM t1_char; +a b +1 2 +2 10 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +2 10 4711 +1 2 42 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +2 10 5 1C 1 +1 2 3 15 2 +SELECT a,b,x FROM t1_char; +a b x +2 10 Foo is a bar +1 2 Just a test INSERT INTO t9 VALUES (2); INSERT INTO t1_nodef VALUES (1,2); SHOW SLAVE STATUS; @@ -69,7 +101,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 1934 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -84,7 +116,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1364 Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef Skip_Counter 0 -Exec_Master_Log_Pos 1850 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -107,7 +139,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 2085 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -122,7 +154,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1514 Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns Skip_Counter 0 -Exec_Master_Log_Pos 2007 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -145,7 +177,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 2231 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -160,7 +192,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1514 Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 2158 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -183,7 +215,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 2387 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -198,7 +230,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1514 Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 2304 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File @@ -221,7 +253,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 2543 +Read_Master_Log_Pos # Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 @@ -236,7 +268,7 @@ Replicate_Wild_Ignore_Table Last_Errno 1514 Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 -Exec_Master_Log_Pos 2460 +Exec_Master_Log_Pos # Relay_Log_Space # Until_Condition None Until_Log_File diff --git a/mysql-test/r/rpl_row_tabledefs_3innodb.result b/mysql-test/r/rpl_row_tabledefs_3innodb.result new file mode 100644 index 00000000000..17f41850bc7 --- /dev/null +++ b/mysql-test/r/rpl_row_tabledefs_3innodb.result @@ -0,0 +1,286 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +STOP SLAVE; +SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; +START SLAVE; +CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; +CREATE TABLE t4 (a INT) ENGINE='InnoDB'; +CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='InnoDB'; +CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='InnoDB'; +CREATE TABLE t9 (a INT) ENGINE='InnoDB'; +ALTER TABLE t1_int ADD x INT DEFAULT 42; +ALTER TABLE t1_bit +ADD x BIT(3) DEFAULT b'011', +ADD y BIT(5) DEFAULT b'10101', +ADD z BIT(2) DEFAULT b'10'; +ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; +ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t2 DROP b; +ALTER TABLE t4 MODIFY a FLOAT; +ALTER TABLE t5 MODIFY b FLOAT; +ALTER TABLE t6 MODIFY c FLOAT; +INSERT INTO t1_int VALUES (2, 4, 4711); +INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); +INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); +**** On Master **** +INSERT INTO t1_int VALUES (1,2); +INSERT INTO t1_int VALUES (2,5); +INSERT INTO t1_bit VALUES (1,2); +INSERT INTO t1_bit VALUES (2,5); +INSERT INTO t1_char VALUES (1,2); +INSERT INTO t1_char VALUES (2,5); +SELECT * FROM t1_int; +a b +1 2 +2 5 +SELECT * FROM t1_bit; +a b +1 2 +2 5 +SELECT * FROM t1_char; +a b +1 2 +2 5 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +2 5 4711 +1 2 42 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +2 5 5 1C 1 +1 2 3 15 2 +SELECT a,b,x FROM t1_char; +a b x +2 5 Foo is a bar +1 2 Just a test +**** On Master **** +UPDATE t1_int SET b=2*b WHERE a=2; +UPDATE t1_char SET b=2*b WHERE a=2; +UPDATE t1_bit SET b=2*b WHERE a=2; +SELECT * FROM t1_int; +a b +1 2 +2 10 +SELECT * FROM t1_bit; +a b +1 2 +2 10 +SELECT * FROM t1_char; +a b +1 2 +2 10 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +2 10 4711 +1 2 42 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +2 10 5 1C 1 +1 2 3 15 2 +SELECT a,b,x FROM t1_char; +a b x +2 10 Foo is a bar +1 2 Just a test +INSERT INTO t9 VALUES (2); +INSERT INTO t1_nodef VALUES (1,2); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1364 +Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (2); +INSERT INTO t2 VALUES (2,4); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (4); +INSERT INTO t4 VALUES (4); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (5); +INSERT INTO t5 VALUES (5,10,25); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (6); +INSERT INTO t6 VALUES (6,12,36); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; diff --git a/mysql-test/r/rpl_row_tabledefs_7ndb.result b/mysql-test/r/rpl_row_tabledefs_7ndb.result new file mode 100644 index 00000000000..0d0da3b6185 --- /dev/null +++ b/mysql-test/r/rpl_row_tabledefs_7ndb.result @@ -0,0 +1,286 @@ +stop slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +STOP SLAVE; +SET GLOBAL SQL_MODE='STRICT_ALL_TABLES'; +START SLAVE; +CREATE TABLE t1_int (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t1_bit (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t1_char (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t1_nodef (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t2 (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='NDB'; +CREATE TABLE t4 (a INT) ENGINE='NDB'; +CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='NDB'; +CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='NDB'; +CREATE TABLE t9 (a INT) ENGINE='NDB'; +ALTER TABLE t1_int ADD x INT DEFAULT 42; +ALTER TABLE t1_bit +ADD x BIT(3) DEFAULT b'011', +ADD y BIT(5) DEFAULT b'10101', +ADD z BIT(2) DEFAULT b'10'; +ALTER TABLE t1_char ADD x CHAR(20) DEFAULT 'Just a test'; +ALTER TABLE t1_nodef ADD x INT NOT NULL; +ALTER TABLE t2 DROP b; +ALTER TABLE t4 MODIFY a FLOAT; +ALTER TABLE t5 MODIFY b FLOAT; +ALTER TABLE t6 MODIFY c FLOAT; +INSERT INTO t1_int VALUES (2, 4, 4711); +INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); +INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); +**** On Master **** +INSERT INTO t1_int VALUES (1,2); +INSERT INTO t1_int VALUES (2,5); +INSERT INTO t1_bit VALUES (1,2); +INSERT INTO t1_bit VALUES (2,5); +INSERT INTO t1_char VALUES (1,2); +INSERT INTO t1_char VALUES (2,5); +SELECT * FROM t1_int; +a b +1 2 +2 5 +SELECT * FROM t1_bit; +a b +1 2 +2 5 +SELECT * FROM t1_char; +a b +1 2 +2 5 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +1 2 42 +2 5 42 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +1 2 3 15 2 +2 5 3 15 2 +SELECT a,b,x FROM t1_char; +a b x +1 2 Just a test +2 5 Just a test +**** On Master **** +UPDATE t1_int SET b=2*b WHERE a=2; +UPDATE t1_char SET b=2*b WHERE a=2; +UPDATE t1_bit SET b=2*b WHERE a=2; +SELECT * FROM t1_int; +a b +1 2 +2 10 +SELECT * FROM t1_bit; +a b +1 2 +2 10 +SELECT * FROM t1_char; +a b +1 2 +2 10 +**** On Slave **** +SELECT a,b,x FROM t1_int; +a b x +1 2 42 +2 10 42 +SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; +a b HEX(x) HEX(y) HEX(z) +1 2 3 15 2 +2 10 3 15 2 +SELECT a,b,x FROM t1_char; +a b x +1 2 Just a test +2 10 Just a test +INSERT INTO t9 VALUES (2); +INSERT INTO t1_nodef VALUES (1,2); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1364 +Last_Error Error in Write_rows event: error during transaction execution on table test.t1_nodef +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (2); +INSERT INTO t2 VALUES (2,4); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (4); +INSERT INTO t4 VALUES (4); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (5); +INSERT INTO t5 VALUES (5,10,25); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +INSERT INTO t9 VALUES (6); +INSERT INTO t6 VALUES (6,12,36); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running No +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 1514 +Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; +START SLAVE; +DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; diff --git a/mysql-test/t/rpl_row_tabledefs.test b/mysql-test/t/rpl_row_tabledefs_2myisam.test similarity index 100% rename from mysql-test/t/rpl_row_tabledefs.test rename to mysql-test/t/rpl_row_tabledefs_2myisam.test diff --git a/mysql-test/t/rpl_row_tabledefs_3innodb.test b/mysql-test/t/rpl_row_tabledefs_3innodb.test new file mode 100644 index 00000000000..7824fbfb663 --- /dev/null +++ b/mysql-test/t/rpl_row_tabledefs_3innodb.test @@ -0,0 +1,9 @@ + +-- source include/have_binlog_format_row.inc +-- source include/have_innodb.inc +-- source include/master-slave.inc + +let $engine_type = 'InnoDB'; +-- source extra/rpl_tests/rpl_row_tabledefs.test + + diff --git a/sql/field.cc b/sql/field.cc index 32e63597c30..3b841c74009 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1237,6 +1237,14 @@ uint Field::offset() } +my_size_t +Field::do_last_null_byte() const +{ + DBUG_ASSERT(null_ptr == NULL || (byte*) null_ptr >= table->record[0]); + return null_ptr ? (byte*) null_ptr - table->record[0] + 1 : 0; +} + + void Field::copy_from_tmp(int row_offset) { memcpy(ptr,ptr+row_offset,pack_length()); @@ -8012,6 +8020,30 @@ Field_bit::Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, } +my_size_t +Field_bit::do_last_null_byte() const +{ + /* + Code elsewhere is assuming that bytes are 8 bits, so I'm using + that value instead of the correct one: CHAR_BIT. + + REFACTOR SUGGESTION (Matz): Change to use the correct number of + bits. On systems with CHAR_BIT > 8 (not very common), the storage + will lose the extra bits. + */ + DBUG_PRINT("debug", ("bit_ofs=%d, bit_len=%d, bit_ptr=%p", + bit_ofs, bit_len, bit_ptr)); + uchar *result; + if (bit_len == 0) + result= null_ptr; + else if (bit_ofs + bit_len > 8) + result= bit_ptr + 1; + else + result= bit_ptr; + + return result ? (byte*) result - table->record[0] + 1 : 0; +} + Field *Field_bit::new_key_field(MEM_ROOT *root, struct st_table *new_table, char *new_ptr, uchar *new_null_ptr, diff --git a/sql/field.h b/sql/field.h index d8dcb85fd5a..8f782400dcc 100644 --- a/sql/field.h +++ b/sql/field.h @@ -212,6 +212,19 @@ public: { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; } inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; } inline bool real_maybe_null(void) { return null_ptr != 0; } + + /* + Return a pointer to the last byte of the null bytes where the + field conceptually is placed. In the case that the field does not + use any bits of the null bytes, a null pointer is returned. + */ + my_size_t last_null_byte() const { + my_size_t bytes= do_last_null_byte(); + DBUG_PRINT("debug", ("last_null_byte() ==> %d", bytes)); + DBUG_ASSERT(bytes <= table->s->null_bytes); + return bytes; + } + virtual void make_field(Send_field *); virtual void sort_string(char *buff,uint length)=0; virtual bool optimize_range(uint idx, uint part); @@ -371,6 +384,9 @@ public: friend class Item_sum_min; friend class Item_sum_max; friend class Item_func_group_concat; + +private: + virtual my_size_t do_last_null_byte() const; }; @@ -1399,6 +1415,9 @@ public: Field::move_field_offset(ptr_diff); bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*); } + +private: + virtual my_size_t do_last_null_byte() const; }; diff --git a/sql/log_event.cc b/sql/log_event.cc index 9991656c3eb..f62c6b5034f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5270,16 +5270,28 @@ int Rows_log_event::do_add_row_data(byte *const row_data, */ static int unpack_row(RELAY_LOG_INFO *rli, - TABLE *table, uint colcnt, byte *record, + TABLE *table, uint const colcnt, byte *record, char const *row, MY_BITMAP const *cols, char const **row_end, ulong *master_reclength) { DBUG_ASSERT(record && row); MY_BITMAP *write_set= table->file->write_set; - - my_size_t const n_null_bytes= table->s->null_bytes; my_ptrdiff_t const offset= record - (byte*) table->record[0]; - memcpy(record, row, n_null_bytes); // [1] + my_size_t master_null_bytes= table->s->null_bytes; + + if (colcnt != table->s->fields) + { + Field **fptr= &table->field[colcnt-1]; + do + master_null_bytes= (*fptr)->last_null_byte(); + while (master_null_bytes == 0 && fptr-- > table->field); + + if (master_null_bytes == 0) + master_null_bytes= table->s->null_bytes; + } + + DBUG_ASSERT(master_null_bytes <= table->s->null_bytes); + memcpy(record, row, master_null_bytes); // [1] int error= 0; bitmap_set_all(write_set); @@ -5287,14 +5299,12 @@ unpack_row(RELAY_LOG_INFO *rli, Field **const begin_ptr = table->field; Field **field_ptr; { - char const *ptr= row + n_null_bytes; - for (field_ptr= begin_ptr ; *field_ptr ; ++field_ptr) + char const *ptr= row + master_null_bytes; + Field **const end_ptr= begin_ptr + colcnt; + for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr) { Field *const f= *field_ptr; - if (colcnt == 0) - break; - --colcnt; if (bitmap_is_set(cols, field_ptr - begin_ptr)) { /* Field...::unpack() cannot return 0 */ @@ -6190,7 +6200,7 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, int error; error= unpack_row(rli, - table, m_width, (byte*)table->record[0], + table, m_width, table->record[0], row_start, &m_cols, row_end, &m_master_reclength); #ifndef DBUG_OFF print_column_values("Unpacked value", thd, table); @@ -6241,6 +6251,79 @@ namespace { } +/* + Copy "extra" columns from record[1] to record[0]. + + Copy the extra fields that are not present on the master but are + present on the slave from record[1] to record[0]. This is used + after fetching a record that are to be updated, either inside + replace_record() or as part of executing an update_row(). + */ +static int +copy_extra_record_fields(TABLE *table, + my_size_t master_reclength, + my_ptrdiff_t master_fields) +{ + DBUG_PRINT("info", ("Copying to %p from field %d at offset %u to field %d at offset %u", + table->record[0], + master_fields, master_reclength, + table->s->fields, table->s->reclength)); + if (master_reclength < table->s->reclength) + bmove_align(table->record[0] + master_reclength, + table->record[1] + master_reclength, + table->s->reclength - master_reclength); + + /* + Bit columns are special. We iterate over all the remaining + columns and copy the "extra" bits to the new record. This is + not a very good solution: it should be refactored on + opportunity. + + REFACTORING SUGGESTION (Matz). Introduce a member function + similar to move_field_offset() called copy_field_offset() to + copy field values and implement it for all Field subclasses. Use + this function to copy data from the found record to the record + that are going to be inserted. + + The copy_field_offset() function need to be a virtual function, + which in this case will prevent copying an entire range of + fields efficiently. + */ + { + Field **field_ptr= table->field + master_fields; + for ( ; *field_ptr ; ++field_ptr) + { + /* + Set the null bit according to the values in record[1] + */ + if ((*field_ptr)->maybe_null() && + (*field_ptr)->is_null_in_record(reinterpret_cast(table->record[1]))) + (*field_ptr)->set_null(); + else + (*field_ptr)->set_notnull(); + + /* + Do the extra work for special columns. + */ + switch ((*field_ptr)->real_type()) + { + default: + /* Nothing to do */ + break; + + case FIELD_TYPE_BIT: + Field_bit *f= static_cast(*field_ptr); + my_ptrdiff_t const offset= table->record[1] - table->record[0]; + uchar const bits= + get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len); + set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len); + break; + } + } + } + return 0; // All OK +} + /* Replace the provided record in the database. @@ -6327,54 +6410,7 @@ replace_record(THD *thd, TABLE *table, First we copy the columns into table->record[0] that are not present on the master from table->record[1], if there are any. */ - - DBUG_PRINT("info", ("Copying to %p from offset %u to %u", - table->record[0], - master_reclength, table->s->reclength)); -#ifndef DBUG_OFF - print_column_values("After copy value", thd, table); -#endif - if (master_reclength < table->s->reclength) - bmove_align(table->record[0] + master_reclength, - table->record[1] + master_reclength, - table->s->reclength - master_reclength); - - /* - Bit columns are special. We iterate over all the remaining - columns and copy the "extra" bits to the new record. This is - not a very good solution: it should be refactored on - opportunity. - - REFACTORING SUGGESTION (Matz). Introduce a member function - similar to move_field_offset() called copy_field_offset() to - copy field values and implement it for all Field subclasses. Use - this function to copy data from the found record to the record - that are going to be inserted. - - The copy_field_offset() function need to be a virtual function, - which in this case will prevent copying an entire range of - fields efficiently. - */ - { - Field **field_ptr= table->field + master_fields; - for ( ; *field_ptr ; ++field_ptr) - { - switch ((*field_ptr)->real_type()) - { - default: - /* Nothing to do */ - break; - - case FIELD_TYPE_BIT: - Field_bit *f= static_cast(*field_ptr); - my_ptrdiff_t const offset= table->record[1] - table->record[0]; - uchar const bits= - get_rec_bits(f->bit_ptr + offset, f->bit_ofs, f->bit_len); - set_rec_bits(bits, f->bit_ptr, f->bit_ofs, f->bit_len); - break; - } - } - } + copy_extra_record_fields(table, master_reclength, master_fields); /* REPLACE is defined as either INSERT or DELETE + INSERT. If @@ -6887,17 +6923,20 @@ int Update_rows_log_event::do_exec_row(TABLE *table) example, the partition engine). Since find_and_fetch_row() puts the fetched record (i.e., the old - record) in record[0], we have to move it out of the way and into - record[1]. After that, we can put the new record (i.e., the after - image) into record[0]. + record) in record[1], we can keep it there. We put the new record + (i.e., the after image) into record[0], and copy the fields that + are on the slave (i.e., in record[1]) into record[0], effectively + overwriting the default values that where put there by the + unpack_row() function. */ - bmove_align(table->record[1], table->record[0], table->s->reclength); bmove_align(table->record[0], m_after_image, table->s->reclength); + copy_extra_record_fields(table, m_master_reclength, m_width); /* - Now we should have the right row to update. The old row (the one - we're looking for) has to be in record[1] and the new row has to - be in record[0] for all storage engines to work correctly. + Now we have the right row to update. The old row (the one we're + looking for) is in record[1] and the new row has is in record[0]. + We also have copied the original values already in the slave's + database into the after image delivered from the master. */ error= table->file->ha_update_row(table->record[1], table->record[0]); From 2457ca1cb572e900126df151cafda181cab649a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 1 Aug 2006 12:23:02 +0200 Subject: [PATCH 04/37] I had forgotten to delete an already disabled line of C++ code. sql/sql_insert.cc: I had forgotten to delete this line (it was already disabled using //; this line was not needed because we do the empty() every time we write to the binlog (in MYSQL_LOG::write()); t/binlog_stm_binlog.test already tests that the empty() indeed happens for INSERT DELAYED. --- sql/sql_insert.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 25ed03c4051..6ea9246636e 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2086,8 +2086,6 @@ bool delayed_insert::handle_inserts(void) thd.start_time=row->start_time; thd.query_start_used=row->query_start_used; - /* for the binlog, forget auto_increment ids generated by previous rows */ -// thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty(); thd.first_successful_insert_id_in_prev_stmt= row->first_successful_insert_id_in_prev_stmt; thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt= From 08e6a3095e0fb0db7a02e14f8048a735c2c40c9c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Aug 2006 10:48:47 +0930 Subject: [PATCH 05/37] mysqldump.c: Tidy up style: no space before = or +=. client/mysqldump.c: Tidy up style: no space before = or +=. --- client/mysqldump.c | 94 +++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 4318e4b9528..5b197499776 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -617,13 +617,13 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), tty_password=1; break; case 'r': - if (!(md_result_file = my_fopen(argument, O_WRONLY | FILE_BINARY, + if (!(md_result_file= my_fopen(argument, O_WRONLY | FILE_BINARY, MYF(MY_WME)))) exit(1); break; case 'W': #ifdef __WIN__ - opt_protocol = MYSQL_PROTOCOL_PIPE; + opt_protocol= MYSQL_PROTOCOL_PIPE; #endif break; case 'N': @@ -638,7 +638,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #include case 'V': print_version(); exit(0); case 'X': - opt_xml = 1; + opt_xml= 1; extended_insert= opt_drop= opt_lock= opt_disable_keys= opt_autocommit= opt_create_db= 0; break; @@ -1404,7 +1404,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, const char *insert_option; char name_buff[NAME_LEN+3],table_buff[NAME_LEN*2+3]; char table_buff2[NAME_LEN*2+3], query_buff[512]; - FILE *sql_file = md_result_file; + FILE *sql_file= md_result_file; int len; MYSQL_RES *result; MYSQL_ROW row; @@ -1451,7 +1451,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, opt_quoted_table= quote_name(table, table_buff2, 0); if (opt_order_by_primary) - order_by = primary_key_fields(result_table); + order_by= primary_key_fields(result_table); if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff)) { @@ -1503,7 +1503,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, field= mysql_fetch_field_direct(result, 0); if (strcmp(field->name, "View") == 0) { - char *scv_buff = NULL; + char *scv_buff= NULL; if (verbose) fprintf(stderr, "-- It's a view, create dummy table for view\n"); @@ -1541,7 +1541,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); safe_exit(EX_MYSQLERR); - DBUG_RETURN(0); + DBUG_RETURN(0); } else my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); @@ -1909,7 +1909,7 @@ static void dump_triggers_for_table (char *table, char *db) char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; char query_buff[512]; uint old_opt_compatible_mode=opt_compatible_mode; - FILE *sql_file = md_result_file; + FILE *sql_file= md_result_file; MYSQL_RES *result; MYSQL_ROW row; @@ -2160,15 +2160,15 @@ static void dump_table(char *table, char *db) end= strmov(end,buff); if (where || order_by) { - query = alloc_query_str((ulong) ((end - query) + 1 + + query= alloc_query_str((ulong) ((end - query) + 1 + (where ? strlen(where) + 7 : 0) + (order_by ? strlen(order_by) + 10 : 0))); - end = strmov(query, query_buf); + end= strmov(query, query_buf); if (where) - end = strxmov(end, " WHERE ", where, NullS); + end= strxmov(end, " WHERE ", where, NullS); if (order_by) - end = strxmov(end, " ORDER BY ", order_by, NullS); + end= strxmov(end, " ORDER BY ", order_by, NullS); } if (mysql_real_query(sock, query, (uint) (end - query))) { @@ -2189,10 +2189,10 @@ static void dump_table(char *table, char *db) result_table); if (where || order_by) { - query = alloc_query_str((ulong) (strlen(query) + 1 + + query= alloc_query_str((ulong) (strlen(query) + 1 + (where ? strlen(where) + 7 : 0) + (order_by ? strlen(order_by) + 10 : 0))); - end = strmov(query, query_buf); + end= strmov(query, query_buf); if (where) { @@ -2201,7 +2201,7 @@ static void dump_table(char *table, char *db) fprintf(md_result_file, "-- WHERE: %s\n", where); check_io(md_result_file); } - end = strxmov(end, " WHERE ", where, NullS); + end= strxmov(end, " WHERE ", where, NullS); } if (order_by) { @@ -2210,7 +2210,7 @@ static void dump_table(char *table, char *db) fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); check_io(md_result_file); } - end = strxmov(end, " ORDER BY ", order_by, NullS); + end= strxmov(end, " ORDER BY ", order_by, NullS); } } if (!opt_xml && !opt_compact) @@ -2283,12 +2283,12 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } - for (i = 0; i < mysql_num_fields(res); i++) + for (i= 0; i < mysql_num_fields(res); i++) { int is_blob; ulong length= lengths[i]; - if (!(field = mysql_fetch_field(res))) + if (!(field= mysql_fetch_field(res))) { my_snprintf(query, QUERY_LENGTH, "%s: Not enough fields from table %s! Aborting.\n", @@ -2360,7 +2360,7 @@ static void dump_table(char *table, char *db) else { /* change any strings ("inf", "-inf", "nan") into NULL */ - char *ptr = row[i]; + char *ptr= row[i]; if (my_isalpha(charset_info, *ptr) || (*ptr == '-' && my_isalpha(charset_info, ptr[1]))) dynstr_append(&extended_row, "NULL"); @@ -2420,7 +2420,7 @@ static void dump_table(char *table, char *db) else { /* change any strings ("inf", "-inf", "nan") into NULL */ - char *ptr = row[i]; + char *ptr= row[i]; if (opt_xml) { print_xml_tag1(md_result_file, "\t\t", "field name=", @@ -2466,10 +2466,10 @@ static void dump_table(char *table, char *db) { ulong row_length; dynstr_append(&extended_row,")"); - row_length = 2 + extended_row.length; + row_length= 2 + extended_row.length; if (total_length + row_length < opt_net_buffer_length) { - total_length += row_length; + total_length+= row_length; fputc(',',md_result_file); /* Always row break */ fputs(extended_row.str,md_result_file); } @@ -2481,7 +2481,7 @@ static void dump_table(char *table, char *db) fputs(insert_pat.str,md_result_file); fputs(extended_row.str,md_result_file); - total_length = row_length+init_length; + total_length= row_length+init_length; } check_io(md_result_file); } @@ -2546,15 +2546,15 @@ err: static char *getTableName(int reset) { - static MYSQL_RES *res = NULL; + static MYSQL_RES *res= NULL; MYSQL_ROW row; if (!res) { - if (!(res = mysql_list_tables(sock,NullS))) + if (!(res= mysql_list_tables(sock,NullS))) return(NULL); } - if ((row = mysql_fetch_row(res))) + if ((row= mysql_fetch_row(res))) return((char*) row[0]); if (reset) @@ -2562,7 +2562,7 @@ static char *getTableName(int reset) else { mysql_free_result(res); - res = NULL; + res= NULL; } return(NULL); } /* getTableName */ @@ -2576,7 +2576,7 @@ static int dump_all_databases() if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES")) return 1; - while ((row = mysql_fetch_row(tableres))) + while ((row= mysql_fetch_row(tableres))) { if (dump_all_tables_in_db(row[0])) result=1; @@ -2584,13 +2584,13 @@ static int dump_all_databases() if (seen_views) { if (mysql_query(sock, "SHOW DATABASES") || - !(tableres = mysql_store_result(sock))) + !(tableres= mysql_store_result(sock))) { my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s", MYF(0), mysql_error(sock)); return 1; } - while ((row = mysql_fetch_row(tableres))) + while ((row= mysql_fetch_row(tableres))) { if (dump_all_views_in_db(row[0])) result=1; @@ -2657,7 +2657,7 @@ static int init_dumping(char *database) "SHOW CREATE DATABASE IF NOT EXISTS %s", qdatabase); - if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) + if (mysql_query(sock, qbuf) || !(dbinfo= mysql_store_result(sock))) { /* Old server version, dump generic CREATE DATABASE */ if (opt_drop_database) @@ -2674,7 +2674,7 @@ static int init_dumping(char *database) fprintf(md_result_file, "\n/*!40000 DROP DATABASE IF EXISTS %s*/;\n", qdatabase); - row = mysql_fetch_row(dbinfo); + row= mysql_fetch_row(dbinfo); if (row[1]) { fprintf(md_result_file,"\n%s;\n",row[1]); @@ -2983,7 +2983,7 @@ static int do_show_master_status(MYSQL *mysql_con) } else { - row = mysql_fetch_row(master); + row= mysql_fetch_row(master); if (row && row[0] && row[1]) { /* SHOW MASTER STATUS reports file and position */ @@ -3110,7 +3110,7 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, MYSQL_FIELD *field; mysql_field_seek(result, 0); - for ( ; (field = mysql_fetch_field(result)) ; row++) + for ( ; (field= mysql_fetch_field(result)) ; row++) { if (!strcmp(field->name,name)) { @@ -3239,17 +3239,17 @@ char check_if_ignore_table(const char *table_name, char *table_type) static char *primary_key_fields(const char *table_name) { - MYSQL_RES *res = NULL; + MYSQL_RES *res= NULL; MYSQL_ROW row; /* SHOW KEYS FROM + table name * 2 (escaped) + 2 quotes + \0 */ char show_keys_buff[15 + 64 * 2 + 3]; - uint result_length = 0; - char *result = 0; + uint result_length= 0; + char *result= 0; my_snprintf(show_keys_buff, sizeof(show_keys_buff), "SHOW KEYS FROM %s", table_name); if (mysql_query(sock, show_keys_buff) || - !(res = mysql_store_result(sock))) + !(res= mysql_store_result(sock))) { fprintf(stderr, "Warning: Couldn't read keys from table %s;" " records are NOT sorted (%s)\n", @@ -3264,12 +3264,12 @@ static char *primary_key_fields(const char *table_name) * row, and UNIQUE keys come before others. So we only need to check * the first key, not all keys. */ - if ((row = mysql_fetch_row(res)) && atoi(row[1]) == 0) + if ((row= mysql_fetch_row(res)) && atoi(row[1]) == 0) { /* Key is unique */ do - result_length += strlen(row[4]) + 1; /* + 1 for ',' or \0 */ - while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1); + result_length+= strlen(row[4]) + 1; /* + 1 for ',' or \0 */ + while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1); } /* Build the ORDER BY clause result */ @@ -3277,17 +3277,17 @@ static char *primary_key_fields(const char *table_name) { char *end; /* result (terminating \0 is already in result_length) */ - result = my_malloc(result_length + 10, MYF(MY_WME)); + result= my_malloc(result_length + 10, MYF(MY_WME)); if (!result) { fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n"); goto cleanup; } mysql_data_seek(res, 0); - row = mysql_fetch_row(res); - end = strmov(result, row[4]); - while ((row = mysql_fetch_row(res)) && atoi(row[3]) > 1) - end = strxmov(end, ",", row[4], NullS); + row= mysql_fetch_row(res); + end= strmov(result, row[4]); + while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1) + end= strxmov(end, ",", row[4], NullS); } cleanup: @@ -3355,7 +3355,7 @@ static my_bool get_view_structure(char *table, char* db) char table_buff[NAME_LEN*2+3]; char table_buff2[NAME_LEN*2+3]; char query[QUERY_LENGTH]; - FILE *sql_file = md_result_file; + FILE *sql_file= md_result_file; DBUG_ENTER("get_view_structure"); if (tFlag) /* Don't write table creation info */ From 7fd78b848a53bc18395857c933b0a41730cacb3c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 2 Aug 2006 11:26:08 +0930 Subject: [PATCH 06/37] BUG#13926: --order-by-primary fails if PKEY contains quote character. Quote PKEY. mysql-test/t/mysqldump.test: Test for BUG#13926: --order-by-primary fails if PKEY contains quote character mysql-test/r/mysqldump.result: Test results for BUG#13926: --order-by-primary fails if PKEY contains quote character client/mysqldump.c: Fix for BUG#13926: --order-by-primary fails if PKEY contains quote character. Quote PKEY. --- client/mysqldump.c | 16 ++++++-- mysql-test/r/mysqldump.result | 71 +++++++++++++++++++++++++++++++++++ mysql-test/t/mysqldump.test | 20 ++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 5b197499776..f8f95ca7fd8 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3245,6 +3245,8 @@ static char *primary_key_fields(const char *table_name) char show_keys_buff[15 + 64 * 2 + 3]; uint result_length= 0; char *result= 0; + char buff[NAME_LEN * 2 + 3]; + char *quoted_field; my_snprintf(show_keys_buff, sizeof(show_keys_buff), "SHOW KEYS FROM %s", table_name); @@ -3268,8 +3270,10 @@ static char *primary_key_fields(const char *table_name) { /* Key is unique */ do - result_length+= strlen(row[4]) + 1; /* + 1 for ',' or \0 */ - while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1); + { + quoted_field= quote_name(row[4], buff, 0); + result_length+= strlen(quoted_field) + 1; /* + 1 for ',' or \0 */ + } while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1); } /* Build the ORDER BY clause result */ @@ -3285,9 +3289,13 @@ static char *primary_key_fields(const char *table_name) } mysql_data_seek(res, 0); row= mysql_fetch_row(res); - end= strmov(result, row[4]); + quoted_field= quote_name(row[4], buff, 0); + end= strmov(result, quoted_field); while ((row= mysql_fetch_row(res)) && atoi(row[3]) > 1) - end= strxmov(end, ",", row[4], NullS); + { + quoted_field= quote_name(row[4], buff, 0); + end= strxmov(end, ",", quoted_field, NullS); + } } cleanup: diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 118079906bf..b2a01bde10f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2867,3 +2867,74 @@ drop view nasishnasifu; drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; +USE test; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( +`a b` INT, +`c"d` INT, +`e``f` INT, +PRIMARY KEY (`a b`, `c"d`, `e``f`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t1 values (0815, 4711, 2006); +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS "t1"; +CREATE TABLE "t1" ( + "a b" int(11) NOT NULL default '0', + "c""d" int(11) NOT NULL default '0', + "e`f" int(11) NOT NULL default '0', + PRIMARY KEY ("a b","c""d","e`f") +); + +LOCK TABLES "t1" WRITE; +/*!40000 ALTER TABLE "t1" DISABLE KEYS */; +INSERT INTO "t1" VALUES (815,4711,2006); +/*!40000 ALTER TABLE "t1" ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a b` int(11) NOT NULL default '0', + `c"d` int(11) NOT NULL default '0', + `e``f` int(11) NOT NULL default '0', + PRIMARY KEY (`a b`,`c"d`,`e``f`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (815,4711,2006); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +DROP TABLE `t1`; +End of 5.0 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 858d8910781..a0060863959 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1228,3 +1228,23 @@ drop view nasishnasifu; drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; +USE test; + +# +# BUG#13926: --order-by-primary fails if PKEY contains quote character +# +--disable_warnings +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a b` INT, + `c"d` INT, + `e``f` INT, + PRIMARY KEY (`a b`, `c"d`, `e``f`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t1 values (0815, 4711, 2006); + +--exec $MYSQL_DUMP --skip-comments --compatible=ansi --order-by-primary test t1 +--exec $MYSQL_DUMP --skip-comments --order-by-primary test t1 +DROP TABLE `t1`; +--enable_warnings +--echo End of 5.0 tests From f6144fb75eaed8f0d7f25349cf9f8e0ae03dad4f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 16 Aug 2006 14:55:57 +0200 Subject: [PATCH 07/37] BUG#20863 (if binlog format is changed between update and unlock table, wrong binlogging): Fix to allow the binlog format to be changed between the LOCK and UNLOCK tables, as well as under MIXED mode. mysql-test/r/rpl_switch_stm_row_mixed.result: Result change mysql-test/t/rpl_switch_stm_row_mixed.test: Adding test to see that binlog format can be changed when using LOCK/UNLOCK TABLES both under ROW format and MIXED format. sql/log.cc: Removing pre-condition assertion since binlog can now be statement based. sql/sql_class.cc: Adding code to always flush pending event regardless of the binlog format used. The only exception is if we are inside a stored routine, where the pending event is never flushed. --- mysql-test/r/rpl_switch_stm_row_mixed.result | 35 ++++++++++++++--- mysql-test/t/rpl_switch_stm_row_mixed.test | 33 +++++++++++++++- sql/log.cc | 2 +- sql/sql_class.cc | 40 ++++++++++---------- 4 files changed, 83 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/rpl_switch_stm_row_mixed.result b/mysql-test/r/rpl_switch_stm_row_mixed.result index 313037bb9dc..e23749dc402 100644 --- a/mysql-test/r/rpl_switch_stm_row_mixed.result +++ b/mysql-test/r/rpl_switch_stm_row_mixed.result @@ -7,6 +7,8 @@ start slave; drop database if exists mysqltest1; create database mysqltest1; use mysqltest1; +set session binlog_format=row; +set global binlog_format=row; show global variables like "binlog_format%"; Variable_name Value binlog_format ROW @@ -157,11 +159,29 @@ count(*) select count(*) from t5; count(*) 58 +SET SESSION BINLOG_FORMAT=STATEMENT; +CREATE TABLE t11 (song VARCHAR(255)); +LOCK TABLES t11 WRITE; +SET SESSION BINLOG_FORMAT=ROW; +INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); +SET SESSION BINLOG_FORMAT=STATEMENT; +INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); +UNLOCK TABLES; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +USE mysqltest1; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t12 (data LONG); +LOCK TABLES t12 WRITE; +INSERT INTO t12 VALUES(UUID()); +UNLOCK TABLES; show binlog events from 102; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # drop database if exists mysqltest1 -master-bin.000001 # Table_map 1 # table_id: # (mysql.proc) -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Query 1 # create database mysqltest1 master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t1 (a varchar(100)) master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) @@ -178,10 +198,6 @@ master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F -master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F -master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work") master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E6379 COLLATE latin1_swedish_ci master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' @@ -269,4 +285,11 @@ master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t11 (song VARCHAR(255)) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; INSERT INTO t11 VALUES('Careful With That Axe, Eugene') +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t12 (data LONG) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t12) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F drop database mysqltest1; diff --git a/mysql-test/t/rpl_switch_stm_row_mixed.test b/mysql-test/t/rpl_switch_stm_row_mixed.test index 4a79b3995c4..8afc1ea37cf 100644 --- a/mysql-test/t/rpl_switch_stm_row_mixed.test +++ b/mysql-test/t/rpl_switch_stm_row_mixed.test @@ -1,4 +1,4 @@ --- source include/have_binlog_format_row.inc +-- source include/have_row_based.inc -- source include/master-slave.inc connection master; @@ -8,6 +8,9 @@ create database mysqltest1; --enable_warnings use mysqltest1; +set session binlog_format=row; +set global binlog_format=row; + show global variables like "binlog_format%"; show session variables like "binlog_format%"; select @@global.binlog_format, @@session.binlog_format; @@ -196,10 +199,38 @@ if ($you_want_to_test_UDF) select count(*) from t9; } +# +# Bug#20863 If binlog format is changed between update and unlock of +# tables, wrong binlog +# + +connection master; +SET SESSION BINLOG_FORMAT=STATEMENT; +CREATE TABLE t11 (song VARCHAR(255)); +LOCK TABLES t11 WRITE; +SET SESSION BINLOG_FORMAT=ROW; +INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); +SET SESSION BINLOG_FORMAT=STATEMENT; +INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); +UNLOCK TABLES; + +--query_vertical SELECT * FROM t11 +sync_slave_with_master; +USE mysqltest1; +--query_vertical SELECT * FROM t11 + +connection master; +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t12 (data LONG); +LOCK TABLES t12 WRITE; +INSERT INTO t12 VALUES(UUID()); +UNLOCK TABLES; + --replace_column 2 # 5 # --replace_regex /table_id: [0-9]+/table_id: #/ show binlog events from 102; sync_slave_with_master; + # as we're using UUID we don't SELECT but use "diff" like in rpl_row_UUID --exec $MYSQL_DUMP --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_master.sql --exec $MYSQL_DUMP_SLAVE --compact --order-by-primary --skip-extended-insert --no-create-info mysqltest1 > $MYSQLTEST_VARDIR/tmp/rpl_switch_stm_row_mixed_slave.sql diff --git a/sql/log.cc b/sql/log.cc index ec73400ea3c..b8b0d05b9dc 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3153,7 +3153,7 @@ int MYSQL_BIN_LOG:: flush_and_set_pending_rows_event(THD *thd, Rows_log_event* event) { DBUG_ENTER("MYSQL_BIN_LOG::flush_and_set_pending_rows_event(event)"); - DBUG_ASSERT(thd->current_stmt_binlog_row_based && mysql_bin_log.is_open()); + DBUG_ASSERT(mysql_bin_log.is_open()); DBUG_PRINT("enter", ("event=%p", event)); int error= 0; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 285a1e72f6f..8cea6023cf7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2649,7 +2649,12 @@ int THD::binlog_delete_row(TABLE* table, bool is_trans, int THD::binlog_flush_pending_rows_event(bool stmt_end) { DBUG_ENTER("THD::binlog_flush_pending_rows_event"); - if (!current_stmt_binlog_row_based || !mysql_bin_log.is_open()) + /* + We shall flush the pending event even if we are not in row-based + mode: it might be the case that we left row-based mode before + flushing anything (e.g., if we have explicitly locked tables). + */ + if (!mysql_bin_log.is_open()) DBUG_RETURN(0); /* @@ -2715,6 +2720,21 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, DBUG_PRINT("enter", ("qtype=%d, query='%s'", qtype, query)); DBUG_ASSERT(query && mysql_bin_log.is_open()); + /* + If we are not in prelocked mode, mysql_unlock_tables() will be + called after this binlog_query(), so we have to flush the pending + rows event with the STMT_END_F set to unlock all tables at the + slave side as well. + + If we are in prelocked mode, the flushing will be done inside the + top-most close_thread_tables(). + */ +#ifdef HAVE_ROW_BASED_REPLICATION + if (this->prelocked_mode == NON_PRELOCKED) + if (int error= binlog_flush_pending_rows_event(TRUE)) + DBUG_RETURN(error); +#endif /*HAVE_ROW_BASED_REPLICATION*/ + switch (qtype) { case THD::MYSQL_QUERY_TYPE: /* @@ -2728,25 +2748,7 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype, case THD::ROW_QUERY_TYPE: #ifdef HAVE_ROW_BASED_REPLICATION if (current_stmt_binlog_row_based) - { - /* - If thd->lock is set, then we are not inside a stored function. - In that case, mysql_unlock_tables() will be called after this - binlog_query(), so we have to flush the pending rows event - with the STMT_END_F set to unlock all tables at the slave side - as well. - - We will not flush the pending event, if thd->lock is NULL. - This means that we are inside a stored function or trigger, so - the flushing will be done inside the top-most - close_thread_tables(). - */ -#ifdef HAVE_ROW_BASED_REPLICATION - if (this->lock) - DBUG_RETURN(binlog_flush_pending_rows_event(TRUE)); -#endif /*HAVE_ROW_BASED_REPLICATION*/ DBUG_RETURN(0); - } #endif /* Otherwise, we fall through */ case THD::STMT_QUERY_TYPE: From aca18bf1113e02e0a77e166d75447c4fd8beab5a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 17 Aug 2006 09:31:46 +0200 Subject: [PATCH 08/37] BUG#20863 (if binlog format is changed between update and unlock of table, wrong binlog): Post-merge fixes. mysql-test/r/rpl_switch_stm_row_mixed.result: Result change mysql-test/t/rpl_switch_stm_row_mixed.test: Fixing test --- mysql-test/r/rpl_switch_stm_row_mixed.result | 368 +++++++++++++++++-- mysql-test/t/rpl_switch_stm_row_mixed.test | 4 + 2 files changed, 345 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/rpl_switch_stm_row_mixed.result b/mysql-test/r/rpl_switch_stm_row_mixed.result index cb31301bcd3..f0afc6bf34d 100644 --- a/mysql-test/r/rpl_switch_stm_row_mixed.result +++ b/mysql-test/r/rpl_switch_stm_row_mixed.result @@ -336,26 +336,6 @@ count(*) select count(*) from t5; count(*) 58 -SET SESSION BINLOG_FORMAT=STATEMENT; -CREATE TABLE t11 (song VARCHAR(255)); -LOCK TABLES t11 WRITE; -SET SESSION BINLOG_FORMAT=ROW; -INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); -SET SESSION BINLOG_FORMAT=STATEMENT; -INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); -UNLOCK TABLES; -SELECT * FROM t11; -song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict -song Careful With That Axe, Eugene -USE mysqltest1; -SELECT * FROM t11; -song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict -song Careful With That Axe, Eugene -SET SESSION BINLOG_FORMAT=MIXED; -CREATE TABLE t12 (data LONG); -LOCK TABLES t12 WRITE; -INSERT INTO t12 VALUES(UUID()); -UNLOCK TABLES; select count(*) from t11; count(*) 8 @@ -380,6 +360,28 @@ count(*) select count(*) from t16; count(*) 3 +DROP TABLE IF EXISTS t11; +SET SESSION BINLOG_FORMAT=STATEMENT; +CREATE TABLE t11 (song VARCHAR(255)); +LOCK TABLES t11 WRITE; +SET SESSION BINLOG_FORMAT=ROW; +INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); +SET SESSION BINLOG_FORMAT=STATEMENT; +INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); +UNLOCK TABLES; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +USE mysqltest1; +SELECT * FROM t11; +song Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict +song Careful With That Axe, Eugene +DROP TABLE IF EXISTS t12; +SET SESSION BINLOG_FORMAT=MIXED; +CREATE TABLE t12 (data LONG); +LOCK TABLES t12 WRITE; +INSERT INTO t12 VALUES(UUID()); +UNLOCK TABLES; show binlog events from 102; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # drop database if exists mysqltest1 @@ -485,13 +487,6 @@ master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t11 (song VARCHAR(255)) -master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F -master-bin.000001 # Query 1 # use `mysqltest1`; INSERT INTO t11 VALUES('Careful With That Axe, Eugene') -master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t12 (data LONG) -master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t12) -master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) @@ -688,4 +683,323 @@ master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t16) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Query 1 # use `mysqltest1`; insert into t16 values("try_66_") +master-bin.000001 # Query 1 # use `mysqltest1`; DROP TABLE IF EXISTS t11 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t11 (song VARCHAR(255)) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; INSERT INTO t11 VALUES('Careful With That Axe, Eugene') +master-bin.000001 # Query 1 # use `mysqltest1`; DROP TABLE IF EXISTS t12 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t12 (data LONG) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t12) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +show binlog events from 102; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # drop database if exists mysqltest1 +master-bin.000001 # Query 1 # create database mysqltest1 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t1 (a varchar(100)) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_8_") +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F375F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_9_") +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F375F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("for_10_") +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_11_" +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_13_") +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F31325F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_14_") +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F31325F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("for_15_") +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_16_" +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values("work_18_") +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F31375F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_21_" +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # User var 1 # @`string`=_latin1 0x656D657267656E63795F31375F COLLATE latin1_swedish_ci +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select @'string' +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_24_" +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t2` ( + `rpad(UUID(),100,' ')` varchar(100) CHARACTER SET utf8 NOT NULL DEFAULT '' +) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t3` ( + `1` varbinary(108) NOT NULL DEFAULT '' +) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t3) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t4` ( + `a` varchar(100) DEFAULT NULL +) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t4) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; create table t5 select * from t1 where 3 in (select 1 union select 2 union select curdate() union select 3) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t5) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo() +begin +insert into t1 values("work_25_"); +insert into t1 values(concat("for_26_",UUID())); +insert into t1 select "yesterday_27_"; +end +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo2() +begin +insert into t1 values(concat("emergency_28_",UUID())); +insert into t1 values("work_29_"); +insert into t1 values(concat("for_30_",UUID())); +set session binlog_format=row; # accepted for stored procs +insert into t1 values("more work_31_"); +set session binlog_format=mixed; +end +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo3() returns bigint unsigned +begin +set session binlog_format=row; # rejected for stored funcs +insert into t1 values("alarm"); +return 100; +end +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` procedure foo4(x varchar(100)) +begin +insert into t1 values(concat("work_250_",x)); +insert into t1 select "yesterday_270_"; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',_latin1'hello'))) +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_270_" +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(concat("work_250_", NAME_CONST('x',_latin1'world'))) +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 select "yesterday_270_" +master-bin.000001 # Query 1 # use `mysqltest1`; drop function foo3 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo3() returns bigint unsigned +begin +insert into t1 values("foo3_32_"); +call foo(); +return 100; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo4() returns bigint unsigned +begin +insert into t2 select foo3(); +return 100; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo5() returns bigint unsigned +begin +insert into t2 select UUID(); +return 100; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function foo6(x varchar(100)) returns bigint unsigned +begin +insert into t2 select x; +return 100; +end +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `foo6`(_latin1'foo6_1_') +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select uuid() +master-bin.000001 # Query 1 # use `mysqltest1`; create table t11 (data varchar(255)) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11') +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11') +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t11 select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='mysqltest1' and TABLE_NAME IN ('v1','t11') +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger t11_bi before insert on t11 for each row +begin +set NEW.data = concat(NEW.data,UUID()); +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; create table t20 select * from t1 +master-bin.000001 # Query 1 # use `mysqltest1`; create table t21 select * from t2 +master-bin.000001 # Query 1 # use `mysqltest1`; create table t22 select * from t3 +master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1,t2,t3 +master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int primary key auto_increment, b varchar(100)) +master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 (a int primary key auto_increment, b varchar(100)) +master-bin.000001 # Query 1 # use `mysqltest1`; create table t3 (b varchar(100)) +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function f (x varchar(100)) returns int deterministic +begin +insert into t1 values(null,x); +insert into t2 values(null,x); +return 1; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Intvar 1 # INSERT_ID=3 +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(null,"try_44_") +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; create table t12 select * from t1 +master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1 +master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int, b varchar(100), key(a)) +master-bin.000001 # Intvar 1 # INSERT_ID=4 +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `f`(_latin1'try_45_') +master-bin.000001 # Query 1 # use `mysqltest1`; create table t13 select * from t1 +master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1 +master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int primary key auto_increment, b varchar(100)) +master-bin.000001 # Query 1 # use `mysqltest1`; drop function f +master-bin.000001 # Query 1 # use `mysqltest1`; create table t14 (unique (a)) select * from t2 +master-bin.000001 # Query 1 # use `mysqltest1`; truncate table t2 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function f1 (x varchar(100)) returns int deterministic +begin +insert into t1 values(null,x); +return 1; +end +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function f2 (x varchar(100)) returns int deterministic +begin +insert into t2 values(null,x); +return 1; +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t3) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; drop function f2 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` function f2 (x varchar(100)) returns int deterministic +begin +declare y int; +insert into t1 values(null,x); +set y = (select count(*) from t2); +return y; +end +master-bin.000001 # Intvar 1 # INSERT_ID=4 +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `f1`(_latin1'try_53_') +master-bin.000001 # Intvar 1 # INSERT_ID=5 +master-bin.000001 # Query 1 # use `mysqltest1`; SELECT `f2`(_latin1'try_54_') +master-bin.000001 # Query 1 # use `mysqltest1`; drop function f2 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger t1_bi before insert on t1 for each row +begin +insert into t2 values(null,"try_55_"); +end +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t1) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) +master-bin.000001 # Write_rows 1 # table_id: # +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; alter table t1 modify a int, drop primary key +master-bin.000001 # Intvar 1 # INSERT_ID=5 +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(null,"try_57_") +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t16` ( + `UUID()` varchar(36) CHARACTER SET utf8 NOT NULL DEFAULT '' +) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t16) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t16) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; insert into t16 values("try_66_") +master-bin.000001 # Query 1 # use `mysqltest1`; DROP TABLE IF EXISTS t11 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t11 (song VARCHAR(255)) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t11) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Query 1 # use `mysqltest1`; INSERT INTO t11 VALUES('Careful With That Axe, Eugene') +master-bin.000001 # Query 1 # use `mysqltest1`; DROP TABLE IF EXISTS t12 +master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE t12 (data LONG) +master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t12) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F drop database mysqltest1; diff --git a/mysql-test/t/rpl_switch_stm_row_mixed.test b/mysql-test/t/rpl_switch_stm_row_mixed.test index 4cef32161ed..4066794d519 100644 --- a/mysql-test/t/rpl_switch_stm_row_mixed.test +++ b/mysql-test/t/rpl_switch_stm_row_mixed.test @@ -464,12 +464,15 @@ if ($you_want_to_test_UDF) select count(*) from t9; } +sync_slave_with_master; + # # Bug#20863 If binlog format is changed between update and unlock of # tables, wrong binlog # connection master; +DROP TABLE IF EXISTS t11; SET SESSION BINLOG_FORMAT=STATEMENT; CREATE TABLE t11 (song VARCHAR(255)); LOCK TABLES t11 WRITE; @@ -485,6 +488,7 @@ USE mysqltest1; --query_vertical SELECT * FROM t11 connection master; +DROP TABLE IF EXISTS t12; SET SESSION BINLOG_FORMAT=MIXED; CREATE TABLE t12 (data LONG); LOCK TABLES t12 WRITE; From f17a35a94826905a549ac05ca224e18d852edff4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Aug 2006 10:36:11 +0200 Subject: [PATCH 09/37] WL#3259 (RBR with more columns on slave than on master): Post-merge fixes. mysql-test/r/rpl_row_tabledefs_3innodb.result: Result change mysql-test/t/disabled.def: Disabling test that appear to be fixed in other clones sql/field.cc: Post-merge fix sql/log_event.cc: Changes to unpack_row(): - Documentation - New parameter, the write/read set - R/W set now 0-indexed instead of 1-indexed - Removed column value printing Changes to replace_record(): - Documentation - Removed column value printing Removed unused function print_column_values() --- mysql-test/r/rpl_row_tabledefs_3innodb.result | 8 +- mysql-test/t/disabled.def | 1 + sql/field.cc | 1 + sql/log_event.cc | 105 +++++++++--------- 4 files changed, 59 insertions(+), 56 deletions(-) diff --git a/mysql-test/r/rpl_row_tabledefs_3innodb.result b/mysql-test/r/rpl_row_tabledefs_3innodb.result index 17f41850bc7..0c1b25ec7fc 100644 --- a/mysql-test/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/r/rpl_row_tabledefs_3innodb.result @@ -151,7 +151,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns Skip_Counter 0 Exec_Master_Log_Pos # @@ -189,7 +189,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -227,7 +227,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -265,7 +265,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index a3bedbaa22d..f1322fcb699 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -36,6 +36,7 @@ rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever rpl_sp : BUG#16456 2006-02-16 jmiller +rpl_sp_effects : BUG#19862 2006-08-22 mats Bug appear to be fixed rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case sp-goto : BUG#18949 2006-02-16 jmiller GOTO is currently is disabled - will be fixed in the future mysqldump : BUG#18078 2006-03-10 lars diff --git a/sql/field.cc b/sql/field.cc index 1fe74d5320f..340f33f1e01 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1255,6 +1255,7 @@ void Field::hash(ulong *nr, ulong *nr2) CHARSET_INFO *cs= charset(); cs->coll->hash_sort(cs, (uchar*) ptr, len, nr, nr2); } +} my_size_t Field::do_last_null_byte() const diff --git a/sql/log_event.cc b/sql/log_event.cc index 4ccd808befc..2a8fd085eee 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5293,21 +5293,39 @@ int Rows_log_event::do_add_row_data(byte *const row_data, /* Unpack a row into a record. - The row is assumed to only consist of the fields for which the - bitset represented by 'arr' and 'bits'; the other parts of the - record are left alone. + SYNOPSIS + unpack_row() + rli Relay log info + table Table to unpack into + colcnt Number of columns to read from record + record Record where the data should be unpacked + row Packed row data + cols Pointer to columns data to fill in + row_end Pointer to variable that will hold the value of the + one-after-end position for the row + master_reclength + Pointer to variable that will hold the length of the + record on the master side + rw_set Pointer to bitmap that holds either the read_set or the + write_set of the table - At most 'colcnt' columns are read: if the table is larger than that, - the remaining fields are not filled in. + DESCRIPTION + + The row is assumed to only consist of the fields for which the + bitset represented by 'arr' and 'bits'; the other parts of the + record are left alone. + + At most 'colcnt' columns are read: if the table is larger than + that, the remaining fields are not filled in. */ static int unpack_row(RELAY_LOG_INFO *rli, TABLE *table, uint const colcnt, byte *record, char const *row, MY_BITMAP const *cols, - char const **row_end, ulong *master_reclength) + char const **row_end, ulong *master_reclength, + MY_BITMAP* const rw_set) { DBUG_ASSERT(record && row); - MY_BITMAP *write_set= table->write_set; my_ptrdiff_t const offset= record - (byte*) table->record[0]; my_size_t master_null_bytes= table->s->null_bytes; @@ -5326,7 +5344,7 @@ unpack_row(RELAY_LOG_INFO *rli, memcpy(record, row, master_null_bytes); // [1] int error= 0; - bitmap_set_all(write_set); + bitmap_set_all(rw_set); Field **const begin_ptr = table->field; Field **field_ptr; @@ -5339,11 +5357,12 @@ unpack_row(RELAY_LOG_INFO *rli, if (bitmap_is_set(cols, field_ptr - begin_ptr)) { - /* Field...::unpack() cannot return 0 */ ptr= f->unpack(f->ptr + offset, ptr); + /* Field...::unpack() cannot return 0 */ + DBUG_ASSERT(ptr != NULL); } else - bitmap_clear_bit(write_set, (field_ptr - begin_ptr) + 1); + bitmap_clear_bit(rw_set, field_ptr - begin_ptr); } *row_end = ptr; @@ -6102,27 +6121,6 @@ void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info) } #endif -#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) -#ifndef DBUG_OFF -static void -print_column_values(char const *text, THD *thd, TABLE *table) -{ - THD *old_thd= table->in_use; - if (table->in_use == NULL) - table->in_use= thd; - for (Field **fptr= table->field ; *fptr ; ++fptr) - { - char buf[MAX_FIELD_WIDTH]; - String str(buf, sizeof(buf), system_charset_info); - (*fptr)->val_str(&str); - DBUG_PRINT("info", ("%s for column %d is '%s'", - text, fptr - table->field, str.c_ptr())); - } - table->in_use= old_thd; -} -#endif -#endif - /************************************************************************** Write_rows_log_event member functions **************************************************************************/ @@ -6219,10 +6217,9 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, int error; error= unpack_row(rli, table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength); -#ifndef DBUG_OFF - print_column_values("Unpacked value", thd, table); -#endif + row_start, &m_cols, row_end, &m_master_reclength, + table->write_set); + bitmap_copy(table->read_set, table->write_set); return error; } @@ -6345,17 +6342,22 @@ copy_extra_record_fields(TABLE *table, /* Replace the provided record in the database. - Similar to how it is done in mysql_insert(), we first - try to do a ha_write_row() and of that fails due to - duplicated keys (or indices), we do an ha_update_row() - or a ha_delete_row() instead. + SYNOPSIS + replace_record() + thd Thread context for writing the record. + table Table to which record should be written. + master_reclength + Offset to first column that is not present on the master, + alternatively the length of the record on the master + side. - @param thd Thread context for writing the record. - @param table Table to which record should be written. - @param master_reclength - Offset to first column that is not present on the master, - alternatively the length of the record on the master side. - @return Error code on failure, 0 on success. + RETURN VALUE + Error code on failure, 0 on success. + + DESCRIPTION + Similar to how it is done in mysql_insert(), we first try to do + a ha_write_row() and of that fails due to duplicated keys (or + indices), we do an ha_update_row() or a ha_delete_row() instead. */ static int replace_record(THD *thd, TABLE *table, @@ -6369,10 +6371,6 @@ replace_record(THD *thd, TABLE *table, int keynum; auto_afree_ptr key(NULL); -#ifndef DBUG_OFF - print_column_values("Starting write value", thd, table); -#endif - while ((error= table->file->ha_write_row(table->record[0]))) { if ((keynum= table->file->get_dup_key(error)) < 0) @@ -6766,7 +6764,8 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, error= unpack_row(rli, table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength); + row_start, &m_cols, row_end, &m_master_reclength, + table->read_set); /* If we will access rows using the random access method, m_key will be set to NULL, so we do not need to make a key copy in that case. @@ -6908,12 +6907,14 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, /* record[0] is the before image for the update */ error= unpack_row(rli, table, m_width, table->record[0], - row_start, &m_cols, row_end, &m_master_reclength); + row_start, &m_cols, row_end, &m_master_reclength, + table->read_set); row_start = *row_end; /* m_after_image is the after image for the update */ error= unpack_row(rli, table, m_width, m_after_image, - row_start, &m_cols, row_end, &m_master_reclength); + row_start, &m_cols, row_end, &m_master_reclength, + table->write_set); /* If we will access rows using the random access method, m_key will From 0220e4ff877daba889983117fbf2b065ad50b36e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Aug 2006 13:53:16 +0200 Subject: [PATCH 10/37] mytap-changes.patch unittest/Makefile.am: Import patch mytap-changes.patch unittest/README.txt: Import patch mytap-changes.patch unittest/examples/Makefile.am: Import patch mytap-changes.patch unittest/mytap/tap.c: Import patch mytap-changes.patch unittest/mytap/tap.h: Import patch mytap-changes.patch --- unittest/Makefile.am | 7 +++-- unittest/README.txt | 7 ++++- unittest/examples/Makefile.am | 2 +- unittest/mytap/tap.c | 50 +++++++++++++++++++++++++++++++++-- unittest/mytap/tap.h | 27 ++++++++++++++++--- 5 files changed, 81 insertions(+), 12 deletions(-) diff --git a/unittest/Makefile.am b/unittest/Makefile.am index ca3291efde0..6cca1165cfe 100644 --- a/unittest/Makefile.am +++ b/unittest/Makefile.am @@ -6,10 +6,9 @@ CLEANFILES = unit unittests = mytap mysys -test: unit - ./unit run $(unittests) +test: + perl unit.pl run $(unittests) unit: $(srcdir)/unit.pl - cp $(srcdir)/unit.pl $@ - chmod 700 $@ + install $(srcdir)/unit.pl $@ diff --git a/unittest/README.txt b/unittest/README.txt index 0d8bb9025d8..cefa8753f8f 100644 --- a/unittest/README.txt +++ b/unittest/README.txt @@ -9,7 +9,9 @@ mytap Source for the MyTAP library mysys Tests for mysys components bitmap-t.c Unit test for MY_BITMAP base64-t.c Unit test for base64 encoding functions -examples Example unit tests +examples Example unit tests. + core-t.c Example of raising a signal in the middle of the test + THIS TEST WILL STOP ALL FURTHER TESTING! simple-t.c Example of a standard TAP unit test skip-t.c Example where some test points are skipped skip_all-t.c Example of a test where the entire test is skipped @@ -24,6 +26,9 @@ To make and execute all unit tests in the directory: make test +Observe that the tests in the examples/ directory are just various +examples of tests and are not expected to pass. + Adding unit tests ----------------- diff --git a/unittest/examples/Makefile.am b/unittest/examples/Makefile.am index f3c70b654a1..8aefb351220 100644 --- a/unittest/examples/Makefile.am +++ b/unittest/examples/Makefile.am @@ -5,5 +5,5 @@ AM_LDFLAGS = -L$(top_builddir)/unittest/mytap LDADD = -lmytap -noinst_PROGRAMS = simple-t skip-t todo-t skip_all-t no_plan-t +noinst_PROGRAMS = simple-t skip-t todo-t skip_all-t no_plan-t core-t diff --git a/unittest/mytap/tap.c b/unittest/mytap/tap.c index d3f5013b4c9..17ec51863d9 100644 --- a/unittest/mytap/tap.c +++ b/unittest/mytap/tap.c @@ -20,10 +20,13 @@ #include "tap.h" +#include "my_config.h" + #include #include #include #include +#include /** Test data structure. @@ -70,7 +73,7 @@ emit_tap(int pass, char const *fmt, va_list ap) /** Emit a TAP directive. - TAP directives are comments after a have the form + TAP directives are comments after that have the form: @code ok 1 # skip reason for skipping @@ -96,6 +99,25 @@ emit_endl() fprintf(tapout, "\n"); } +static void +handle_core_signal(int signo) +{ + BAIL_OUT("Signal %d thrown", signo); +} + +void +BAIL_OUT(char const *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + fprintf(tapout, "Bail out! "); + vfprintf(tapout, fmt, ap); + emit_endl(); + va_end(ap); + exit(255); +} + + void diag(char const *fmt, ...) { @@ -103,14 +125,38 @@ diag(char const *fmt, ...) va_start(ap, fmt); fprintf(tapout, "# "); vfprintf(tapout, fmt, ap); - fprintf(tapout, "\n"); + emit_endl(); va_end(ap); } +typedef struct signal_entry { + int signo; + void (*handler)(int); +} signal_entry; + +static signal_entry install_signal[]= { + { SIGQUIT, handle_core_signal }, + { SIGILL, handle_core_signal }, + { SIGABRT, handle_core_signal }, + { SIGFPE, handle_core_signal }, + { SIGSEGV, handle_core_signal }, + { SIGBUS, handle_core_signal }, + { SIGXCPU, handle_core_signal }, + { SIGXFSZ, handle_core_signal }, + { SIGSYS, handle_core_signal }, + { SIGTRAP, handle_core_signal } +}; void plan(int const count) { + /* + Install signal handler + */ + size_t i; + for (i= 0; i < sizeof(install_signal)/sizeof(*install_signal); ++i) + signal(install_signal[i].signo, install_signal[i].handler); + g_test.plan= count; switch (count) { diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h index cc1d0926012..5e24c1c8c99 100644 --- a/unittest/mytap/tap.h +++ b/unittest/mytap/tap.h @@ -21,8 +21,6 @@ #ifndef TAP_H #define TAP_H -#include "my_global.h" - /* @defgroup MyTAP MySQL support for performing unit tests according to TAP. @@ -67,6 +65,10 @@ extern "C" { it was called with NO_PLAN, i.e., the test plan will be printed after all the test lines. + The plan() function will install signal handlers for all signals + that generate a core, so if you want to override these signals, do + it after you have called the plan() function. + @param count The planned number of tests to run. */ void plan(int count); @@ -130,10 +132,9 @@ void skip(int how_many, char const *reason, ...) for (i = 0 ; i < 2 ; ++i) ok(duck[i] == paddling, "is duck %d paddling?", i); } + @endcode @see skip - - @endcode */ #define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \ if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else @@ -146,6 +147,24 @@ void skip(int how_many, char const *reason, ...) void diag(char const *fmt, ...) __attribute__((format(printf,1,2))); +/** + Print a bail out message. + + A bail out message can be issued when no further testing can be + done, e.g., when there are missing dependencies. + + The test will exit with status 255. This function does not return. + + @note A bail out message is printed if a signal that generates a + core is raised. + + @param fmt Bail out message in printf() format. +*/ + +void BAIL_OUT(char const *fmt, ...) + __attribute__((noreturn, format(printf,1,2))); + + /** Print summary report and return exit status. From ac03e433646ed99e14f2c49ecd3204934e799b8c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Aug 2006 16:11:22 +0200 Subject: [PATCH 11/37] Adding missing file unittest/examples/core-t.c: BitKeeper file /users/mkindahl/mysql-5.1-clone/unittest/examples/core-t.c --- unittest/examples/core-t.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 unittest/examples/core-t.c diff --git a/unittest/examples/core-t.c b/unittest/examples/core-t.c new file mode 100644 index 00000000000..3572d72868b --- /dev/null +++ b/unittest/examples/core-t.c @@ -0,0 +1,19 @@ + +#include "my_config.h" + +#include +#include + +/* + This is a simple test to demonstrate what happens if a signal that + generates a core is raised. + + Note that this test will stop all further testing! + */ + +int main() { + plan(3); + ok(1, "First test"); + abort(); + return exit_status(); +} From 92bbbaa4b07385cb689ac5e3d49207f810964846 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 25 Aug 2006 16:50:01 +0200 Subject: [PATCH 12/37] BUG#21833 (Prepare_commit_mutex not locked and unlocked under same condition): Adding condition to ensure that mutex are locked and unlocked under same condition. sql/ha_innodb.cc: Adding condition to release and aquire mutex under same conditions. --- sql/ha_innodb.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 00a92e05ffb..d39f87ee3ec 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -7387,7 +7387,9 @@ innobase_xa_prepare( int error = 0; trx_t* trx = check_trx_exists(thd); - if (thd->lex->sql_command != SQLCOM_XA_PREPARE) { + if (thd->lex->sql_command != SQLCOM_XA_PREPARE && + (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) + { /* For ibbackup to work the order of transactions in binlog and InnoDB must be the same. Consider the situation From 1b8dad2b58ba132a65d559f5756d06fe65fa929f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Aug 2006 22:23:56 +0200 Subject: [PATCH 13/37] Various fixes to make MyTAP build on all platforms. unittest/Makefile.am: Not installing unit.pl any more. Adding test-verbose target to see the TAP output (for debugging). unittest/mytap/tap.h: Including portability file. Whitespace changes. Code sample for BAIL_OUT() function. --- unittest/Makefile.am | 6 ++---- unittest/mytap/tap.h | 28 +++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/unittest/Makefile.am b/unittest/Makefile.am index 6cca1165cfe..f2f7fc0bf7d 100644 --- a/unittest/Makefile.am +++ b/unittest/Makefile.am @@ -1,6 +1,5 @@ SUBDIRS = mytap . mysys examples -noinst_SCRIPTS = unit EXTRA_DIST = unit.pl CLEANFILES = unit @@ -9,6 +8,5 @@ unittests = mytap mysys test: perl unit.pl run $(unittests) -unit: $(srcdir)/unit.pl - install $(srcdir)/unit.pl $@ - +test-verbose: + HARNESS_VERBOSE=1 perl unit.pl run $(unittests) diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h index 5e24c1c8c99..51b8c7df04d 100644 --- a/unittest/mytap/tap.h +++ b/unittest/mytap/tap.h @@ -21,9 +21,11 @@ #ifndef TAP_H #define TAP_H -/* - @defgroup MyTAP MySQL support for performing unit tests according to TAP. +#include "my_global.h" +/* + @defgroup MyTAP MySQL support for performing unit tests according to + the Test Anything Protocol (TAP). */ #define NO_PLAN (0) @@ -34,6 +36,7 @@ @internal We are using the "typedef struct X { ... } X" idiom to create class/struct X both in C and C++. */ + typedef struct TEST_DATA { /** Number of tests that is planned to execute. @@ -71,6 +74,7 @@ extern "C" { @param count The planned number of tests to run. */ + void plan(int count); @@ -89,9 +93,11 @@ void plan(int count); @param fmt Format string in printf() format. NULL is allowed, in which case nothing is printed. */ + void ok(int pass, char const *fmt, ...) __attribute__((format(printf,2,3))); + /** Skip a determined number of tests. @@ -116,6 +122,7 @@ void ok(int pass, char const *fmt, ...) @param how_many Number of tests that are to be skipped. @param reason A reason for skipping the tests */ + void skip(int how_many, char const *reason, ...) __attribute__((format(printf,2,3))); @@ -136,17 +143,21 @@ void skip(int how_many, char const *reason, ...) @see skip */ + #define SKIP_BLOCK_IF(SKIP_IF_TRUE, COUNT, REASON) \ if (SKIP_IF_TRUE) skip((COUNT),(REASON)); else + /** Print a diagnostics message. @param fmt Diagnostics message in printf() format. */ + void diag(char const *fmt, ...) __attribute__((format(printf,1,2))); + /** Print a bail out message. @@ -155,6 +166,10 @@ void diag(char const *fmt, ...) The test will exit with status 255. This function does not return. + @code + BAIL_OUT("Lost connection to server %s", server_name); + @endcode + @note A bail out message is printed if a signal that generates a core is raised. @@ -180,6 +195,7 @@ void BAIL_OUT(char const *fmt, ...) @returns EXIT_SUCCESS if all tests passed, EXIT_FAILURE if one or more tests failed. */ + int exit_status(void); @@ -190,9 +206,11 @@ int exit_status(void); automatically call exit(), so there is no need to have checks around it. */ + void skip_all(char const *reason, ...) __attribute__((noreturn, format(printf, 1, 2))); + /** Start section of tests that are not yet ready. @@ -213,14 +231,18 @@ void skip_all(char const *reason, ...) @param message Message that will be printed before the todo tests. */ + void todo_start(char const *message, ...) - __attribute__((format (printf, 1, 2))); + __attribute__((format(printf, 1, 2))); + /** End a section of tests that are not yet ready. */ + void todo_end(); + #ifdef __cplusplus } #endif From 930e542f448ee823482cf0de9bc042ef524c902b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Aug 2006 10:22:43 +0300 Subject: [PATCH 14/37] Changes made according to HLD/LLD. The following is an excerption from the WL. 1. Change so that MIXED is default format 1.1 to change the default for command line --binlog-format 1.2 to alter global_system_variables.binlog_format calculation basing on command line --binlog-format parameter and its default. 2. Change test suite so that more testing is done by MIXED format. 2.1 to check if there are test cases requiring --binlog-foramt=statement via `source include/have_binlog_format_statement.inc' and affected by altering the latter to be "mixed". 2.2 to check the content of such vulnerable cases to find if extending to the mixed does not modify results. In that case simply substitute source arguments as explained. 2.3 if a test in mixed mode deals with features triggering row-binlogging then if necessary we can switch explicitly to statement mode or create another test to run with non-recommended STATEMENT mode Particullarily, extracting INSERT DELAYED binlogging subtest for statement mode is performed, and the snippet is moved into a separate test file. Note that since now all three modes verify this use case through 3 different tests. No changes in item 3 of HLD appeared to be needed. mysql-test/extra/binlog_tests/binlog.test: Moving INSERT DELAYED verification section into separate file. The latter is sourced from two different files: the current one and a newly created for STATEMENT mode check. mysql-test/extra/rpl_tests/rpl_loaddata.test: require mixed_or_statement mysql-test/extra/rpl_tests/rpl_stm_000001.test: require mixed_or_statement mysql-test/extra/rpl_tests/rpl_stm_charset.test: require mixed_or_statement mysql-test/r/binlog_stm_binlog.result: new result to correspond to MIXED mode. mysql-test/r/rpl_rbr_to_sbr.result: result changed mysql-test/t/archive.test: require mixed_or_statement mysql-test/t/binlog_stm_binlog.test: require exclusive mixed format because of INSERT DELAYED. mysql-test/t/binlog_stm_blackhole.test: require mixed_or_statement mysql-test/t/binlog_stm_ctype_cp932.test: require mixed_or_statement mysql-test/t/binlog_stm_ctype_ucs.test: require mixed_or_statement mysql-test/t/binlog_stm_drop_tmp_tbl.test: require mixed_or_statement mysql-test/t/binlog_stm_innodb_stat.test: require mixed_or_statement mysql-test/t/binlog_stm_insert_select.test: require mixed_or_statement mysql-test/t/binlog_stm_mix_innodb_myisam.test: require mixed_or_statement mysql-test/t/create_select_tmp.test: require mixed_or_statement mysql-test/t/ctype_cp932_binlog_stm.test: require mixed_or_statement mysql-test/t/date_formats.test: MIXED case appended to the replace instruction mysql-test/t/mysqlbinlog.test: require mixed_or_statement mysql-test/t/mysqlbinlog2.test: require mixed_or_statement mysql-test/t/ndb_multi.test: require mixed_or_statement mysql-test/t/rpl000013.test: require mixed_or_statement mysql-test/t/rpl_heap.test: require mixed_or_statement mysql-test/t/rpl_loaddata_s.test: require mixed_or_statement mysql-test/t/rpl_mixed_ddl_dml.test: require mixed_or_statement mysql-test/t/rpl_rbr_to_sbr.test: Rather meaningless line is discarded. The test does not loose anything without it and without considering the WL. mysql-test/t/rpl_rewrt_db.test: require mixed_or_statement mysql-test/t/rpl_rotate_logs.test: require mixed_or_statement mysql-test/t/rpl_stm_EE_err2.test: require mixed_or_statement mysql-test/t/rpl_stm_flsh_tbls.test: require mixed_or_statement mysql-test/t/rpl_stm_log.test: require mixed_or_statement mysql-test/t/rpl_stm_max_relay_size.test: require mixed_or_statement mysql-test/t/rpl_stm_multi_query.test: require mixed_or_statement mysql-test/t/rpl_stm_mystery22.test: require mixed_or_statement mysql-test/t/rpl_stm_no_op.test: require mixed_or_statement mysql-test/t/rpl_stm_reset_slave.test: require mixed_or_statement mysql-test/t/rpl_stm_until.test: require mixed_or_statement mysql-test/t/rpl_temp_table.test: require mixed_or_statement mysql-test/t/rpl_trigger.test: require mixed_or_statement mysql-test/t/rpl_trunc_temp.test: require mixed_or_statement mysql-test/t/user_var-binlog.test: require mixed_or_statement sql/mysqld.cc: Implementation of making BINLOG_FORMAT_MIXED to be the default of global_system_variables.binlog_format. Not in the case of embedded. mysql-test/extra/binlog_tests/binlog_insert_delayed.test: Snippend sourced from two tests to verify INSERT DELAYED in all three binlog formats. mysql-test/include/have_binlog_format_mixed.inc: Part of exclusive MIXED format requirement mysql-test/include/have_binlog_format_mixed_or_statement.inc: requirement to have mixed or statement. Most of the tests with STATEMENT format indeed are tolerant to MIXED format to yield the same result files. There are few exception because of features triggering RBR events when MIXED format. mysql-test/r/binlog_statement_insert_delayed.result: BitKeeper file /home/elkin/MySQL/TEAM/FIXES/5.1/wl3368_mixed_default/mysql-test/r/binlog_statement_insert_delayed.result mysql-test/r/have_binlog_format_mixed.require: Exclusive MIXED format mysql-test/t/binlog_statement_insert_delayed.test: BitKeeper file /home/elkin/MySQL/TEAM/FIXES/5.1/wl3368_mixed_default/mysql-test/t/binlog_statement_insert_delayed.test --- mysql-test/extra/binlog_tests/binlog.test | 22 +------------------ .../binlog_tests/binlog_insert_delayed.test | 22 +++++++++++++++++++ mysql-test/extra/rpl_tests/rpl_loaddata.test | 2 +- .../extra/rpl_tests/rpl_stm_000001.test | 2 +- .../extra/rpl_tests/rpl_stm_charset.test | 2 +- .../include/have_binlog_format_mixed.inc | 4 ++++ .../have_binlog_format_mixed_or_statement.inc | 5 +++++ .../r/binlog_statement_insert_delayed.result | 18 +++++++++++++++ mysql-test/r/binlog_stm_binlog.result | 10 +++++---- mysql-test/r/have_binlog_format_mixed.require | 2 ++ mysql-test/r/rpl_rbr_to_sbr.result | 3 --- mysql-test/t/archive.test | 2 +- .../t/binlog_statement_insert_delayed.test | 6 +++++ mysql-test/t/binlog_stm_binlog.test | 2 +- mysql-test/t/binlog_stm_blackhole.test | 2 +- mysql-test/t/binlog_stm_ctype_cp932.test | 2 +- mysql-test/t/binlog_stm_ctype_ucs.test | 2 +- mysql-test/t/binlog_stm_drop_tmp_tbl.test | 2 +- mysql-test/t/binlog_stm_innodb_stat.test | 2 +- mysql-test/t/binlog_stm_insert_select.test | 2 +- .../t/binlog_stm_mix_innodb_myisam.test | 2 +- mysql-test/t/create_select_tmp.test | 2 +- mysql-test/t/ctype_cp932_binlog_stm.test | 2 +- mysql-test/t/date_formats.test | 6 ++--- mysql-test/t/mysqlbinlog.test | 2 +- mysql-test/t/mysqlbinlog2.test | 2 +- mysql-test/t/ndb_multi.test | 2 +- mysql-test/t/rpl000013.test | 2 +- mysql-test/t/rpl_heap.test | 2 +- mysql-test/t/rpl_loaddata_s.test | 2 +- mysql-test/t/rpl_mixed_ddl_dml.test | 2 +- mysql-test/t/rpl_rbr_to_sbr.test | 3 +-- mysql-test/t/rpl_rewrt_db.test | 2 +- mysql-test/t/rpl_rotate_logs.test | 2 +- mysql-test/t/rpl_stm_EE_err2.test | 2 +- mysql-test/t/rpl_stm_flsh_tbls.test | 2 +- mysql-test/t/rpl_stm_log.test | 2 +- mysql-test/t/rpl_stm_max_relay_size.test | 2 +- mysql-test/t/rpl_stm_multi_query.test | 2 +- mysql-test/t/rpl_stm_mystery22.test | 2 +- mysql-test/t/rpl_stm_no_op.test | 2 +- mysql-test/t/rpl_stm_reset_slave.test | 2 +- mysql-test/t/rpl_stm_until.test | 2 +- mysql-test/t/rpl_temp_table.test | 2 +- mysql-test/t/rpl_trigger.test | 2 +- mysql-test/t/rpl_trunc_temp.test | 2 +- mysql-test/t/user_var-binlog.test | 2 +- sql/mysqld.cc | 12 +++++++++- 48 files changed, 115 insertions(+), 70 deletions(-) create mode 100644 mysql-test/extra/binlog_tests/binlog_insert_delayed.test create mode 100644 mysql-test/include/have_binlog_format_mixed.inc create mode 100644 mysql-test/include/have_binlog_format_mixed_or_statement.inc create mode 100644 mysql-test/r/binlog_statement_insert_delayed.result create mode 100644 mysql-test/r/have_binlog_format_mixed.require create mode 100644 mysql-test/t/binlog_statement_insert_delayed.test diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 993b3fbf634..af7320a49f6 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -60,24 +60,4 @@ insert into t1 values(null); select * from t1; drop table t1; -# Test of binlogging of INSERT_ID with INSERT DELAYED -create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; -# First, avoid BUG#20627: -set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; -# Verify that only one INSERT_ID event is binlogged. -insert delayed into t1 values (207); - -# We use sleeps between statements, that's the only way to get a -# repeatable binlog in a normal test run and under Valgrind. -# It may be that the "binlog missing rows" of BUG#20821 shows up -# here. -sleep 2; -insert delayed into t1 values (null); -sleep 2; -insert delayed into t1 values (300); -sleep 2; # time for the delayed queries to reach disk -select * from t1; ---replace_column 2 # 5 # ---replace_regex /table_id: [0-9]+/table_id: #/ -show binlog events from 102; -drop table t1; +-- source extra/binlog_tests/binlog_insert_delayed.test diff --git a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test new file mode 100644 index 00000000000..596bb1d5772 --- /dev/null +++ b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test @@ -0,0 +1,22 @@ +# Test of binlogging of INSERT_ID with INSERT DELAYED +create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; +# First, avoid BUG#20627: +set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; +# Verify that only one INSERT_ID event is binlogged. +# Note, that because of WL#3368 mixed mode binlog records RBR events for the delayed +insert delayed into t1 values (207); + +# We use sleeps between statements, that's the only way to get a +# repeatable binlog in a normal test run and under Valgrind. +# It may be that the "binlog missing rows" of BUG#20821 shows up +# here. +sleep 2; +insert delayed into t1 values (null); +sleep 2; +insert delayed into t1 values (300); +sleep 2; # time for the delayed queries to reach disk +select * from t1; +--replace_column 2 # 5 # +--replace_regex /table_id: [0-9]+/table_id: #/ +show binlog events from 102; +drop table t1; diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 08e89c20973..e58908ec7e9 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc # See if replication of a "LOAD DATA in an autoincrement column" # Honours autoincrement values diff --git a/mysql-test/extra/rpl_tests/rpl_stm_000001.test b/mysql-test/extra/rpl_tests/rpl_stm_000001.test index 443ed27053a..8673ae31305 100644 --- a/mysql-test/extra/rpl_tests/rpl_stm_000001.test +++ b/mysql-test/extra/rpl_tests/rpl_stm_000001.test @@ -1,4 +1,4 @@ --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc create table t1 (word char(20) not null); diff --git a/mysql-test/extra/rpl_tests/rpl_stm_charset.test b/mysql-test/extra/rpl_tests/rpl_stm_charset.test index d29a82cfd31..10b4310127f 100644 --- a/mysql-test/extra/rpl_tests/rpl_stm_charset.test +++ b/mysql-test/extra/rpl_tests/rpl_stm_charset.test @@ -2,7 +2,7 @@ # This test will fail if the server/client does not support enough charsets. # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc source include/master-slave.inc; --disable_warnings diff --git a/mysql-test/include/have_binlog_format_mixed.inc b/mysql-test/include/have_binlog_format_mixed.inc new file mode 100644 index 00000000000..fc5ca61c5a0 --- /dev/null +++ b/mysql-test/include/have_binlog_format_mixed.inc @@ -0,0 +1,4 @@ +-- require r/have_binlog_format_mixed.require +disable_query_log; +show variables like "binlog_format"; +enable_query_log; diff --git a/mysql-test/include/have_binlog_format_mixed_or_statement.inc b/mysql-test/include/have_binlog_format_mixed_or_statement.inc new file mode 100644 index 00000000000..8ee6f2cc030 --- /dev/null +++ b/mysql-test/include/have_binlog_format_mixed_or_statement.inc @@ -0,0 +1,5 @@ +--require r/have_binlog_format_statement.require +--disable_query_log +--replace_result MIXED STATEMENT +show variables like "binlog_format"; +--enable_query_log diff --git a/mysql-test/r/binlog_statement_insert_delayed.result b/mysql-test/r/binlog_statement_insert_delayed.result new file mode 100644 index 00000000000..bae01f7dc5d --- /dev/null +++ b/mysql-test/r/binlog_statement_insert_delayed.result @@ -0,0 +1,18 @@ +create table t1 (a int not null auto_increment, primary key (a)) engine=myisam; +set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; +insert delayed into t1 values (207); +insert delayed into t1 values (null); +insert delayed into t1 values (300); +select * from t1; +a +207 +208 +300 +show binlog events from 102; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam +master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207) +master-bin.000001 # Intvar 1 # INSERT_ID=208 +master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null) +master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300) +drop table t1; diff --git a/mysql-test/r/binlog_stm_binlog.result b/mysql-test/r/binlog_stm_binlog.result index 4e23db4828f..b175089f585 100644 --- a/mysql-test/r/binlog_stm_binlog.result +++ b/mysql-test/r/binlog_stm_binlog.result @@ -172,8 +172,10 @@ master-bin.000001 # Intvar 1 # INSERT_ID=127 master-bin.000001 # Query 1 # use `test`; insert into t1 values(null) master-bin.000001 # Query 1 # use `test`; drop table t1 master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam -master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207) -master-bin.000001 # Intvar 1 # INSERT_ID=208 -master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null) -master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300) +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F drop table t1; diff --git a/mysql-test/r/have_binlog_format_mixed.require b/mysql-test/r/have_binlog_format_mixed.require new file mode 100644 index 00000000000..4b752cbb314 --- /dev/null +++ b/mysql-test/r/have_binlog_format_mixed.require @@ -0,0 +1,2 @@ +Variable_name Value +binlog_format MIXED diff --git a/mysql-test/r/rpl_rbr_to_sbr.result b/mysql-test/r/rpl_rbr_to_sbr.result index c5a672ee13b..4b2d129c732 100644 --- a/mysql-test/r/rpl_rbr_to_sbr.result +++ b/mysql-test/r/rpl_rbr_to_sbr.result @@ -5,9 +5,6 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; SET BINLOG_FORMAT=MIXED; -SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT; -@@GLOBAL.BINLOG_FORMAT @@SESSION.BINLOG_FORMAT -STATEMENT MIXED SET GLOBAL BINLOG_FORMAT=MIXED; SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT; @@GLOBAL.BINLOG_FORMAT @@SESSION.BINLOG_FORMAT diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 294e7730e07..0dccd8f111a 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -3,7 +3,7 @@ # Taken FROM the select test # -- source include/have_archive.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc --disable_warnings drop table if exists t1,t2,t3; diff --git a/mysql-test/t/binlog_statement_insert_delayed.test b/mysql-test/t/binlog_statement_insert_delayed.test new file mode 100644 index 00000000000..3b2c547a901 --- /dev/null +++ b/mysql-test/t/binlog_statement_insert_delayed.test @@ -0,0 +1,6 @@ +# This test is to verify replication with INSERT DELAY through +# unrecommended STATEMENT binlog format + +-- source include/not_embedded.inc +-- source include/have_binlog_format_statement.inc +-- source extra/binlog_tests/binlog_insert_delayed.test diff --git a/mysql-test/t/binlog_stm_binlog.test b/mysql-test/t/binlog_stm_binlog.test index f22e7e45aea..280b7a3aef9 100644 --- a/mysql-test/t/binlog_stm_binlog.test +++ b/mysql-test/t/binlog_stm_binlog.test @@ -13,6 +13,6 @@ drop table t1; # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/not_embedded.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed.inc -- source extra/binlog_tests/binlog.test diff --git a/mysql-test/t/binlog_stm_blackhole.test b/mysql-test/t/binlog_stm_blackhole.test index 6047d8ca2fc..02ba2be095b 100644 --- a/mysql-test/t/binlog_stm_blackhole.test +++ b/mysql-test/t/binlog_stm_blackhole.test @@ -2,5 +2,5 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/not_embedded.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/blackhole.test diff --git a/mysql-test/t/binlog_stm_ctype_cp932.test b/mysql-test/t/binlog_stm_ctype_cp932.test index 436f95a2453..c0791d81445 100644 --- a/mysql-test/t/binlog_stm_ctype_cp932.test +++ b/mysql-test/t/binlog_stm_ctype_cp932.test @@ -2,5 +2,5 @@ # For both statement and row based bin logs 9/19/2005 [jbm] -- source include/not_embedded.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/ctype_cp932.test diff --git a/mysql-test/t/binlog_stm_ctype_ucs.test b/mysql-test/t/binlog_stm_ctype_ucs.test index a32ac3155c7..c8cd7e06398 100644 --- a/mysql-test/t/binlog_stm_ctype_ucs.test +++ b/mysql-test/t/binlog_stm_ctype_ucs.test @@ -1,6 +1,6 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/ctype_ucs_binlog.test diff --git a/mysql-test/t/binlog_stm_drop_tmp_tbl.test b/mysql-test/t/binlog_stm_drop_tmp_tbl.test index e8acd00c779..6017f272d01 100644 --- a/mysql-test/t/binlog_stm_drop_tmp_tbl.test +++ b/mysql-test/t/binlog_stm_drop_tmp_tbl.test @@ -1,5 +1,5 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/drop_temp_table.test diff --git a/mysql-test/t/binlog_stm_innodb_stat.test b/mysql-test/t/binlog_stm_innodb_stat.test index c6017246e6d..a08039c4a41 100644 --- a/mysql-test/t/binlog_stm_innodb_stat.test +++ b/mysql-test/t/binlog_stm_innodb_stat.test @@ -1,5 +1,5 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/innodb_stat.test diff --git a/mysql-test/t/binlog_stm_insert_select.test b/mysql-test/t/binlog_stm_insert_select.test index 06792990a55..3aefa1e6cf7 100644 --- a/mysql-test/t/binlog_stm_insert_select.test +++ b/mysql-test/t/binlog_stm_insert_select.test @@ -1,5 +1,5 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/insert_select-binlog.test diff --git a/mysql-test/t/binlog_stm_mix_innodb_myisam.test b/mysql-test/t/binlog_stm_mix_innodb_myisam.test index 829cf50fe1e..cb6516a3a2f 100644 --- a/mysql-test/t/binlog_stm_mix_innodb_myisam.test +++ b/mysql-test/t/binlog_stm_mix_innodb_myisam.test @@ -1,7 +1,7 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 9/19/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/mix_innodb_myisam_binlog.test # This piece below cannot be put into diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test index 144bccc5871..ba9898b7752 100644 --- a/mysql-test/t/create_select_tmp.test +++ b/mysql-test/t/create_select_tmp.test @@ -6,7 +6,7 @@ # inconsistency between binlog and the internal list of temp tables. # This does not work for RBR yet. ---source include/have_binlog_format_statement.inc +--source include/have_binlog_format_mixed_or_statement.inc -- source include/have_innodb.inc --disable_warnings diff --git a/mysql-test/t/ctype_cp932_binlog_stm.test b/mysql-test/t/ctype_cp932_binlog_stm.test index 7a0ac671417..6b591fbe5f5 100644 --- a/mysql-test/t/ctype_cp932_binlog_stm.test +++ b/mysql-test/t/ctype_cp932_binlog_stm.test @@ -1,7 +1,7 @@ # This is a wrapper for binlog.test so that the same test case can be used # For both statement and row based bin logs 11/07/2005 [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/binlog_tests/ctype_cp932_binlog.test # diff --git a/mysql-test/t/date_formats.test b/mysql-test/t/date_formats.test index 6898cd5802d..c19ebeb2e28 100644 --- a/mysql-test/t/date_formats.test +++ b/mysql-test/t/date_formats.test @@ -6,9 +6,9 @@ drop table if exists t1; --enable_warnings ---replace_result ROW STATEMENT +--replace_result ROW STATEMENT MIXED SHOW GLOBAL VARIABLES LIKE "%_format%"; ---replace_result ROW STATEMENT +--replace_result ROW STATEMENT MIXED SHOW SESSION VARIABLES LIKE "%_format%"; # @@ -36,7 +36,7 @@ set datetime_format= '%H:%i:%s.%f %m-%d-%Y'; set datetime_format= '%h:%i:%s %p %Y-%m-%d'; set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d'; ---replace_result ROW STATEMENT +--replace_result ROW STATEMENT MIXED SHOW SESSION VARIABLES LIKE "%format"; --error 1231 diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index ceba78bf762..b1ee39479b9 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -1,6 +1,6 @@ # We are using .opt file since we need small binlog size # TODO: Need to look at making a row based version once the new row based client is completed. [jbm] --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc # Embedded server doesn't support binlogging -- source include/not_embedded.inc diff --git a/mysql-test/t/mysqlbinlog2.test b/mysql-test/t/mysqlbinlog2.test index 91da502da02..69cd5d90453 100644 --- a/mysql-test/t/mysqlbinlog2.test +++ b/mysql-test/t/mysqlbinlog2.test @@ -2,7 +2,7 @@ # and a few others. # TODO: Need to look at making row based version once new binlog client is complete. --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc # Embedded server doesn't support binlogging -- source include/not_embedded.inc diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test index 36018e6c679..df2cc9c1d8b 100644 --- a/mysql-test/t/ndb_multi.test +++ b/mysql-test/t/ndb_multi.test @@ -1,7 +1,7 @@ -- source include/have_ndb.inc -- source include/have_multi_ndb.inc -- source include/not_embedded.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc --disable_warnings connection server2; diff --git a/mysql-test/t/rpl000013.test b/mysql-test/t/rpl000013.test index c681e76cf51..69a102e84ce 100644 --- a/mysql-test/t/rpl000013.test +++ b/mysql-test/t/rpl000013.test @@ -7,7 +7,7 @@ # in row-based, it hangs waiting for an offset which is never # reached (the "sync_with_master 1"), logically. ---source include/have_binlog_format_statement.inc +--source include/have_binlog_format_mixed_or_statement.inc source include/master-slave.inc; save_master_pos; connection slave; diff --git a/mysql-test/t/rpl_heap.test b/mysql-test/t/rpl_heap.test index b35983ad4d7..b8972ee9e78 100644 --- a/mysql-test/t/rpl_heap.test +++ b/mysql-test/t/rpl_heap.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc # You must run this test with --manager. diff --git a/mysql-test/t/rpl_loaddata_s.test b/mysql-test/t/rpl_loaddata_s.test index 72a5d1a8ec1..2c94c8ef953 100644 --- a/mysql-test/t/rpl_loaddata_s.test +++ b/mysql-test/t/rpl_loaddata_s.test @@ -2,7 +2,7 @@ # replicated LOAD DATA INFILE correctly when it has binlog_*_db rules. # This is for BUG#1100 (LOAD DATA INFILE was half-logged). --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc connection slave; diff --git a/mysql-test/t/rpl_mixed_ddl_dml.test b/mysql-test/t/rpl_mixed_ddl_dml.test index 5b9ed6898b8..6a1f81abed3 100644 --- a/mysql-test/t/rpl_mixed_ddl_dml.test +++ b/mysql-test/t/rpl_mixed_ddl_dml.test @@ -1,7 +1,7 @@ # Mixed DDL-DML (CREATE ... SELECT ...) statements can only be # replicated properly in statement-based replication. # Currently statement based due to bug 12345 ---source include/have_binlog_format_statement.inc +--source include/have_binlog_format_mixed_or_statement.inc source include/master-slave.inc; diff --git a/mysql-test/t/rpl_rbr_to_sbr.test b/mysql-test/t/rpl_rbr_to_sbr.test index c10199f8ff5..83a9b08c344 100644 --- a/mysql-test/t/rpl_rbr_to_sbr.test +++ b/mysql-test/t/rpl_rbr_to_sbr.test @@ -1,12 +1,11 @@ -- source include/have_row_based.inc --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc # Test that the slave temporarily switches to ROW when seeing binrow # events when it is in STATEMENT or MIXED mode SET BINLOG_FORMAT=MIXED; -SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT; SET GLOBAL BINLOG_FORMAT=MIXED; SELECT @@GLOBAL.BINLOG_FORMAT, @@SESSION.BINLOG_FORMAT; diff --git a/mysql-test/t/rpl_rewrt_db.test b/mysql-test/t/rpl_rewrt_db.test index 8acc05f6ff5..52f04e073dd 100644 --- a/mysql-test/t/rpl_rewrt_db.test +++ b/mysql-test/t/rpl_rewrt_db.test @@ -1,5 +1,5 @@ # TBF - difference in row level logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc --disable_warnings diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index a5c8a87c74d..2249dff1449 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -13,7 +13,7 @@ # - Test creating a duplicate key error and recover from it # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc connect (master,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); --disable_warnings diff --git a/mysql-test/t/rpl_stm_EE_err2.test b/mysql-test/t/rpl_stm_EE_err2.test index dbcc66686ec..face651b9a1 100644 --- a/mysql-test/t/rpl_stm_EE_err2.test +++ b/mysql-test/t/rpl_stm_EE_err2.test @@ -3,6 +3,6 @@ # Date: 2006-01-11 # Purpose: Engine Wrapper for rpl_stm_EE_err2.test ############################## --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc let $engine_type=myisam; -- source extra/rpl_tests/rpl_stm_EE_err2.test diff --git a/mysql-test/t/rpl_stm_flsh_tbls.test b/mysql-test/t/rpl_stm_flsh_tbls.test index 3a6102de279..43a5234ccc7 100644 --- a/mysql-test/t/rpl_stm_flsh_tbls.test +++ b/mysql-test/t/rpl_stm_flsh_tbls.test @@ -1,5 +1,5 @@ # depends on the binlog output ---source include/have_binlog_format_statement.inc +--source include/have_binlog_format_mixed_or_statement.inc let $rename_event_pos= 652; -- source extra/rpl_tests/rpl_flsh_tbls.test diff --git a/mysql-test/t/rpl_stm_log.test b/mysql-test/t/rpl_stm_log.test index d11e1fd8ac1..5a1e0facc83 100644 --- a/mysql-test/t/rpl_stm_log.test +++ b/mysql-test/t/rpl_stm_log.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc let $engine_type=MyISAM; -- source extra/rpl_tests/rpl_log.test diff --git a/mysql-test/t/rpl_stm_max_relay_size.test b/mysql-test/t/rpl_stm_max_relay_size.test index 50008533388..950aa8b322a 100644 --- a/mysql-test/t/rpl_stm_max_relay_size.test +++ b/mysql-test/t/rpl_stm_max_relay_size.test @@ -4,7 +4,7 @@ # Test of manual relay log rotation with FLUSH LOGS. # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/rpl_tests/rpl_max_relay_size.test # End of 4.1 tests diff --git a/mysql-test/t/rpl_stm_multi_query.test b/mysql-test/t/rpl_stm_multi_query.test index 97c322ac780..c39d1fad015 100644 --- a/mysql-test/t/rpl_stm_multi_query.test +++ b/mysql-test/t/rpl_stm_multi_query.test @@ -4,7 +4,7 @@ # one binlog event containing all queries) # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/rpl_tests/rpl_multi_query.test diff --git a/mysql-test/t/rpl_stm_mystery22.test b/mysql-test/t/rpl_stm_mystery22.test index a43f2610350..017593fdfba 100644 --- a/mysql-test/t/rpl_stm_mystery22.test +++ b/mysql-test/t/rpl_stm_mystery22.test @@ -15,7 +15,7 @@ #should proceed in a correct way. ################################# --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc # first, cause a duplicate key problem on the slave diff --git a/mysql-test/t/rpl_stm_no_op.test b/mysql-test/t/rpl_stm_no_op.test index f82bbd8cd55..66dc89bd712 100644 --- a/mysql-test/t/rpl_stm_no_op.test +++ b/mysql-test/t/rpl_stm_no_op.test @@ -4,7 +4,7 @@ # case. So this test is meaningul only in statement-based (and if it was # enabled in row-based, it would fail as expected). --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc source include/master-slave.inc; diff --git a/mysql-test/t/rpl_stm_reset_slave.test b/mysql-test/t/rpl_stm_reset_slave.test index 282033bf6d1..6a99d4e1613 100644 --- a/mysql-test/t/rpl_stm_reset_slave.test +++ b/mysql-test/t/rpl_stm_reset_slave.test @@ -1,5 +1,5 @@ # TBF - difference in row level logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source extra/rpl_tests/rpl_reset_slave.test # End of 4.1 tests diff --git a/mysql-test/t/rpl_stm_until.test b/mysql-test/t/rpl_stm_until.test index 9a4e4471fe1..f42965c0eb0 100644 --- a/mysql-test/t/rpl_stm_until.test +++ b/mysql-test/t/rpl_stm_until.test @@ -1,4 +1,4 @@ --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc # Test is dependent on binlog positions diff --git a/mysql-test/t/rpl_temp_table.test b/mysql-test/t/rpl_temp_table.test index c29fa8e676d..9b73961aeea 100644 --- a/mysql-test/t/rpl_temp_table.test +++ b/mysql-test/t/rpl_temp_table.test @@ -1,7 +1,7 @@ # drop table t1 t2 t3 are included int master-slave.inc # meaningful only in statement-based: --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc -- source include/master-slave.inc diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test index 591941c19eb..0f87475ff07 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/t/rpl_trigger.test @@ -2,7 +2,7 @@ # Test of triggers with replication # Adding statement include due to Bug 12574 # TODO: Remove statement include once 12574 is patched ---source include/have_binlog_format_statement.inc +--source include/have_binlog_format_mixed_or_statement.inc --source include/master-slave.inc --disable_warnings diff --git a/mysql-test/t/rpl_trunc_temp.test b/mysql-test/t/rpl_trunc_temp.test index 56f858dc9a2..28bcb0c06c3 100644 --- a/mysql-test/t/rpl_trunc_temp.test +++ b/mysql-test/t/rpl_trunc_temp.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc source include/master-slave.inc; diff --git a/mysql-test/t/user_var-binlog.test b/mysql-test/t/user_var-binlog.test index 7f1561b925b..6615e48ca42 100644 --- a/mysql-test/t/user_var-binlog.test +++ b/mysql-test/t/user_var-binlog.test @@ -1,5 +1,5 @@ # Requires statement logging --- source include/have_binlog_format_statement.inc +-- source include/have_binlog_format_mixed_or_statement.inc # TODO: Create row based version once $MYSQL_BINLOG has new RB version # Embedded server does not support binlogging --source include/not_embedded.inc diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7561943d197..8f02c0565ff 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3135,7 +3135,11 @@ with --log-bin instead."); global_system_variables.binlog_format= BINLOG_FORMAT_ROW; else #endif +#if defined(HAVE_ROW_BASED_REPLICATION) + global_system_variables.binlog_format= BINLOG_FORMAT_MIXED; +#else global_system_variables.binlog_format= BINLOG_FORMAT_STMT; +#endif } /* Check that we have not let the format to unspecified at this point */ @@ -4936,7 +4940,13 @@ Disable with --skip-bdb (will save memory).", "supports only statement-based binary logging, so only 'statement' is " "a legal value." #endif - , 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + , 0, 0, 0, GET_STR, REQUIRED_ARG, +#ifdef HAVE_ROW_BASED_REPLICATION + BINLOG_FORMAT_MIXED +#else + BINLOG_FORMAT_STMT +#endif + , 0, 0, 0, 0, 0 }, {"binlog-do-db", OPT_BINLOG_DO_DB, "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, From 207202aafa211447e79514f060393c780b768ce6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Aug 2006 14:10:53 +0200 Subject: [PATCH 15/37] Changes to make unit tests work on OS X and AIX unittest/unit.pl: Removing reliance on Straps, since it's to unstable. --- unittest/unit.pl | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/unittest/unit.pl b/unittest/unit.pl index 3092a874192..28ebb44846d 100644 --- a/unittest/unit.pl +++ b/unittest/unit.pl @@ -1,19 +1,5 @@ #!/usr/bin/perl -# Override _command_line in the standard Perl test harness to prevent -# it from using "perl" to run the test scripts. -package MySQL::Straps; - -use base qw(Test::Harness::Straps); - -use strict; - -sub _command_line { - return $_[1] -} - -package main; - use Test::Harness qw(&runtests $verbose); use File::Find; @@ -37,9 +23,6 @@ unit - Run unit tests in directory my $cmd = shift; -# $Test::Harness::Verbose = 1; -# $Test::Harness::Debug = 1; - if (defined $cmd && exists $dispatch{$cmd}) { $dispatch{$cmd}->(@ARGV); } else { @@ -95,14 +78,7 @@ sub run_cmd (@) { if (@files > 0) { # Removing the first './' from the file names foreach (@files) { s!^\./!! } - - # Install the strap above instead of the default strap. Since - # we are replacing the straps under the feet of Test::Harness, - # we need to do some basic initializations in the new straps. - $Test::Harness::Strap = MySQL::Straps->new; - $Test::Harness::Strap->{callback} = \&Test::Harness::strap_callback - if defined &Test::Harness::strap_callback; - + $ENV{'HARNESS_PERL_SWITCHES'} .= q" -e 'exec @ARGV'"; runtests @files; } } From 4da5da9d7cb71c8693514832970d4b03045eaf4e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 30 Aug 2006 21:43:05 +0300 Subject: [PATCH 16/37] WL#3368 mixed format as default Two minor fixes: 1. to make make test executes with mixed; 2. proper isolation of binlog_statement_insert_delayed from others through reset master cleaning up binlog todo: adapt this technique to other restarting for binlog tests Makefile.am: Binlog format switches to MIXED. A new Makefile target test-binlog-statement is introduced for checking tests requiring exclusive STATEMENT format. mysql-test/t/binlog_statement_insert_delayed.test: cheapest method to clean up binlog after previous tests --- Makefile.am | 6 +++++- mysql-test/t/binlog_statement_insert_delayed.test | 3 +++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 8a575b3c365..bcffe546e7e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -118,7 +118,7 @@ test-unit: test-ps: cd mysql-test ; \ - ./mysql-test-run.pl $(force) --ps-protocol --mysqld=--binlog-format=statement + ./mysql-test-run.pl $(force) --ps-protocol --mysqld=--binlog-format=mixed test-nr: cd mysql-test ; \ @@ -129,6 +129,10 @@ test-pr: ./mysql-test-run.pl $(force) --ps-protocol --mysqld=--binlog-format=row test-ns: + cd mysql-test ; \ + ./mysql-test-run.pl $(force) --mysqld=--binlog-format=mixed + +test-binlog-statement: cd mysql-test ; \ ./mysql-test-run.pl $(force) --mysqld=--binlog-format=statement diff --git a/mysql-test/t/binlog_statement_insert_delayed.test b/mysql-test/t/binlog_statement_insert_delayed.test index 3b2c547a901..9b78296236f 100644 --- a/mysql-test/t/binlog_statement_insert_delayed.test +++ b/mysql-test/t/binlog_statement_insert_delayed.test @@ -3,4 +3,7 @@ -- source include/not_embedded.inc -- source include/have_binlog_format_statement.inc +-- disable_query_log +reset master; # get rid of previous tests binlog +-- enable_query_log -- source extra/binlog_tests/binlog_insert_delayed.test From 9c09d53312ef05386d24d885e50d9536379d69c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Aug 2006 02:00:40 +0300 Subject: [PATCH 17/37] BUG#18822 LOAD DATA FROM MASTER corrupts data there is a bunch of dups. It has been decided to declare this feature as deprecated. sql/sql_yacc.yy: deprecation macro --- sql/sql_yacc.yy | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 162b4183c84..bce9aed79fc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4800,14 +4800,16 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING_sys LOAD TABLE_SYM table_ident FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; + WARN_DEPRECATED("LOAD TABLE FROM MASTER", "mysqldump or future BACKUP/RESTORE DATABASE facility"); if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING)) YYABORT; - + } | LOAD DATA_SYM FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; + WARN_DEPRECATED("LOAD DATA FROM MASTER", "mysqldump or future BACKUP/RESTORE DATABASE facility"); }; opt_local: From d247c70d265b4714a5e0468f570903efb6eaa589 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Sep 2006 17:45:27 +0200 Subject: [PATCH 18/37] BUG#17620: Row-based replication fails when query cache enabled on slave Invalidating query cache when processing rows for a statement on the slave. mysql-test/r/rpl_row_basic_11bugs.result: Result file change mysql-test/t/rpl_row_basic_11bugs.test: Adding test to trigger failure sql/log_event.cc: Adding code to invalidate the query cache just after opening the tables for processing the rows of one statement. --- mysql-test/r/rpl_row_basic_11bugs.result | 40 ++++++++++++++++++++++++ mysql-test/t/rpl_row_basic_11bugs.test | 40 ++++++++++++++++++++++++ sql/log_event.cc | 6 ++++ 3 files changed, 86 insertions(+) diff --git a/mysql-test/r/rpl_row_basic_11bugs.result b/mysql-test/r/rpl_row_basic_11bugs.result index e8be537816e..d768797717b 100644 --- a/mysql-test/r/rpl_row_basic_11bugs.result +++ b/mysql-test/r/rpl_row_basic_11bugs.result @@ -60,3 +60,43 @@ master-bin.000001 4 Format_desc 1 102 Server ver: SERVER_VERSION, Binlog ver: 4 master-bin.000001 102 Query 1 188 use `test`; CREATE TABLE t1 (a INT) master-bin.000001 188 Table_map 1 227 table_id: # (test.t1) master-bin.000001 227 Write_rows 1 266 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; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +start slave; +**** On Slave **** +SET GLOBAL QUERY_CACHE_SIZE=0; +**** On Master **** +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); +**** On Slave **** +SET GLOBAL QUERY_CACHE_SIZE=16*1024*1024; +**** On Master **** +INSERT INTO t1 VALUES (4),(5),(6); +**** On Slave **** +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +6 +**** On Master **** +INSERT INTO t1 VALUES (7),(8),(9); +**** On Slave **** +SELECT * FROM t1; +a +1 +2 +3 +4 +5 +6 +7 +8 +9 +DROP TABLE t1; diff --git a/mysql-test/t/rpl_row_basic_11bugs.test b/mysql-test/t/rpl_row_basic_11bugs.test index af7e9af4005..e636824284d 100644 --- a/mysql-test/t/rpl_row_basic_11bugs.test +++ b/mysql-test/t/rpl_row_basic_11bugs.test @@ -54,3 +54,43 @@ UPDATE t1 SET a=99 WHERE a = 0; --replace_result $SERVER_VERSION SERVER_VERSION --replace_regex /table_id: [0-9]+/table_id: #/ SHOW BINLOG EVENTS; + +DROP TABLE t1; + +# BUG#17620: Replicate (Row Based) Fails when Query Cache enabled on +# slave +--echo ================ Test for BUG#17620 ================ +--disable_query_log +--source include/master-slave-reset.inc +--enable_query_log + +--echo **** On Slave **** +connection slave; +SET GLOBAL QUERY_CACHE_SIZE=0; + +--echo **** On Master **** +connection master; +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2),(3); + +--echo **** On Slave **** +sync_slave_with_master; +SET GLOBAL QUERY_CACHE_SIZE=16*1024*1024; + +--echo **** On Master **** +connection master; +INSERT INTO t1 VALUES (4),(5),(6); + +--echo **** On Slave **** +sync_slave_with_master; +SELECT * FROM t1; + +--echo **** On Master **** +connection master; +INSERT INTO t1 VALUES (7),(8),(9); + +--echo **** On Slave **** +sync_slave_with_master; +SELECT * FROM t1; + +DROP TABLE t1; diff --git a/sql/log_event.cc b/sql/log_event.cc index ebd90446a7e..d5da1468b14 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5425,6 +5425,9 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) /* When the open and locking succeeded, we add all the tables to the table map and remove them from tables to lock. + + We also invalidate the query cache for all the tables, since + they will now be changed. */ TABLE_LIST *ptr; @@ -5433,6 +5436,9 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) rli->m_table_map.set_table(ptr->table_id, ptr->table); rli->touching_table(ptr->db, ptr->table_name, ptr->table_id); } +#ifdef HAVE_QUERY_CACHE + query_cache.invalidate_locked_for_write(rli->tables_to_lock); +#endif rli->clear_tables_to_lock(); } From a6a1aba27a4ed67c9b147b86a09ace30abaf51a7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Sep 2006 18:01:42 +0200 Subject: [PATCH 19/37] Removing sleeps; rpl_row_basic_8partition falls from 2 minutes 15 seconds to less than a second. The sleeps used to be necessary but not anymore as NDB has been fixed wrt sync_slave_with_master. mysql-test/include/rpl_multi_engine3.inc: Sleeps are not necessary anymore because NDB has been fixed wrt sync_slave_with_master. --- mysql-test/include/rpl_multi_engine3.inc | 3 --- 1 file changed, 3 deletions(-) diff --git a/mysql-test/include/rpl_multi_engine3.inc b/mysql-test/include/rpl_multi_engine3.inc index 5d8f7e46409..e1a80df336c 100644 --- a/mysql-test/include/rpl_multi_engine3.inc +++ b/mysql-test/include/rpl_multi_engine3.inc @@ -28,7 +28,6 @@ INSERT INTO t1 VALUES(412,1,'Testing MySQL databases is a cool ', select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id; sync_slave_with_master; ---sleep 5 --echo --- Select from t1 on slave --- select id,hex(b1),vc,bc,d,f,total,y,t from t1 order by id; @@ -44,7 +43,6 @@ SELECT id,hex(b1),vc,bc,d,f,total,y,t FROM t1 WHERE id = 412; # into the binlog other wise we will miss the update. sync_slave_with_master; ---sleep 5 --echo --- Check Update on slave --- SELECT id,hex(b1),vc,bc,d,f,total,y,t FROM t1 WHERE id = 412; @@ -56,7 +54,6 @@ DELETE FROM t1 WHERE id = 42; SELECT COUNT(*) FROM t1; sync_slave_with_master; ---sleep 5 --echo --- Show current count on slave for t1 --- SELECT COUNT(*) FROM t1; From de6b79933cf683b260b03a0b9ed135186fbe708c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Sep 2006 10:20:14 +0200 Subject: [PATCH 20/37] Patches to fix problems on Windows sql/log_event.cc: Adding cast since byte is unsigned char on Windows sql/rpl_utility.cc: Adding missing return statement. --- sql/log_event.cc | 2 +- sql/rpl_utility.cc | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 2a8fd085eee..0f2bf10212b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5369,7 +5369,7 @@ unpack_row(RELAY_LOG_INFO *rli, if (master_reclength) { if (*field_ptr) - *master_reclength = (*field_ptr)->ptr - table->record[0]; + *master_reclength = (*field_ptr)->ptr - (char*) table->record[0]; else *master_reclength = table->s->reclength; } diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index fc706178aa3..5405d022223 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -96,6 +96,8 @@ field_length_from_packed(enum_field_types const field_type, length= ~0UL; // NYI break; } + + return length; } /********************************************************************* From cb7025e86be57969c9f45a15ac4d1250584cf644 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Sep 2006 10:19:11 +0200 Subject: [PATCH 21/37] WL#3259 (More columns on slave than on master): Adding files to CMakeLists.txt sql/CMakeLists.txt: Adding rpl_utility.cc --- sql/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 95073b95ad6..8ca38e7b924 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -53,7 +53,7 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc time.cc tztime.cc uniques.cc unireg.cc item_xmlfunc.cc rpl_tblmap.cc sql_binlog.cc event_scheduler.cc event_timed.cc sql_tablespace.cc events.cc ../sql-common/my_user.c - partition_info.cc rpl_injector.cc sql_locale.cc + partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h ${PROJECT_SOURCE_DIR}/include/mysqld_error.h From 70bb923a37257aa6a33abca49d60ed2dd005c65d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Sep 2006 14:45:40 +0200 Subject: [PATCH 22/37] Fix WARN_DEPRECATED for 5.0 (it is in 5.1 we should have the extra arguments) --- sql/sql_yacc.yy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index fbde9e2884f..375f49b1120 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6873,7 +6873,7 @@ load: LOAD DATA_SYM YYABORT; } lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; - WARN_DEPRECATED(yythd, "5.2", "LOAD TABLE FROM MASTER", + WARN_DEPRECATED("LOAD TABLE FROM MASTER", "mysqldump or future " "BACKUP/RESTORE DATABASE facility"); if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING)) @@ -6914,7 +6914,7 @@ load_data: FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; - WARN_DEPRECATED(yythd, "5.2", "LOAD DATA FROM MASTER", + WARN_DEPRECATED("LOAD DATA FROM MASTER", "mysqldump or future " "BACKUP/RESTORE DATABASE facility"); }; From da9298988f4b6d980b0b818e5fdf62d86e08e771 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 11 Sep 2006 19:45:09 +0200 Subject: [PATCH 23/37] manual merge sql/sql_yacc.yy: Manual merge --- sql/sql_yacc.yy | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 87657d5f4a6..93a23873c73 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8744,9 +8744,6 @@ load: LOAD DATA_SYM YYABORT; } lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; - WARN_DEPRECATED("LOAD TABLE FROM MASTER", - "mysqldump or future " - "BACKUP/RESTORE DATABASE facility"); if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING)) YYABORT; }; @@ -8785,7 +8782,7 @@ load_data: FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_DATA; - WARN_DEPRECATED("LOAD DATA FROM MASTER", + WARN_DEPRECATED(yythd, "5.2", "LOAD DATA FROM MASTER", "mysqldump or future " "BACKUP/RESTORE DATABASE facility"); }; From 76fa1d4381586ca55ddfb9869c04a0ef794a92a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 12 Sep 2006 15:42:13 +0200 Subject: [PATCH 24/37] Fixing problems I identified in my auto_increment work pushed in July (as part of the auto_increment cleanup of WL#3146; let's not be sad, that monster push still removed serious bugs): one problem with INSERT DELAYED (unexpected interval releases), one with stored functions (wrong auto_inc binlogging). These bugs were not released. mysql-test/extra/binlog_tests/binlog_insert_delayed.test: more tests of binlogging of INSERT DELAYED: with multi-row INSERTs. I identified why sleeps are needed to get a repeatable row-based binlogged: because without sleeps rows sometimes get groupped and so generate different row based events. mysql-test/extra/rpl_tests/rpl_foreign_key.test: don't forget to drop tables on slave too, otherwise it leaves an orphan innodb table leading to rpl_insert_id failing sometimes (like in pushbuild "sapsrv2 -max"). mysql-test/extra/rpl_tests/rpl_insert_id.test: testing that if some statement does not update any row, it does not pollute the auto_inc binlog variables of the next statement; the test has to use stored procedures because with plain statements, mysql_reset_thd_for_next_command() does the resetting (and thus there is no problem); mysql_reset_thd_for_next_command() is not called inside routines. mysql-test/r/binlog_row_binlog.result: result additions mysql-test/r/binlog_statement_insert_delayed.result: result additions mysql-test/r/binlog_stm_binlog.result: result additions mysql-test/r/rpl_insert_id.result: result additions mysql-test/r/rpl_loaddata.result: With the change to log.cc reverted, the result changes and is better: the change to log.cc had caused some INSERT_ID events to disappear though they were necessary (but testsuite could not catch that because it's single-threaded). mysql-test/r/rpl_ndb_insert_ignore.result: NDB is now like other engines regarding INSERT IGNORE: autoincrement values which caused a duplicate key are re-used for next row, not lost. rpl_ndb_insert_ignore.result is now identical to rpl_insert_ignore.result. sql/log.cc: LOAD DATA INFILE is binlogged as several events, and the last of them must have the auto_inc id. So it's wrong to reset the auto_inc id after every binlog write (because then it's lost after the first event of LOAD DATA INFILE and so missing for the last one)/ Another problem: MYSQL_LOG::write() is not always called (for example if no row was updated), so we were missing reset in some cases. sql/sp_head.cc: SELECT func1(),func2() generates two binlog events, so needs to clear auto_increment binlog variables after each binlog event (it would be more natural to clear them in the log write code, but LOAD DATA INFILE would suffer from this see the cset comment for log.cc). Without the clearing, the problem is: > exec func1() >> call cleanup_after_query() (which does not clear our vars here) >> binlog SELECT func1() < > exec func2() and so SELECT func2() is binlogged with the auto_inc of SELECT func1(). sql/sql_class.cc: after every statement we should clear auto_inc variables used for binlogging, except if this was a function/trigger (in which case it may be "INSERT SELECT func()", where the cleanup_after_query() executed in func() should not reset the auto_inc binlog variables as they'll be necessary when binlogging the INSERT SELECT later). sql/sql_insert.cc: - as INSERT DELAYED uses the same TABLE object as the delayed_insert system thread, we should not call ha_release_auto_increment() from INSERT DELAYED (and btw it's logical as we reserve nothing as we don't perform the insert). Calling the function caused us to release values being used by the delayed_insert thread. So I do the call only if this is a non-DELAYED INSERT. - Assuming two INSERT DELAYED which get grouped by the delayed_insert thread, the second may use values reserved by the first, which is ok per se, but is a problem in statement-based binlogging: the 2nd INSERT gets binlogged with the "interval start" value of the first INSERT (=> duplicate error in slave). - no reason to ha_release_auto_increment() after every inserted row in INSERT SELECT; more efficient to do it only when the statement ends sql/sql_parse.cc: a comment --- .../binlog_tests/binlog_insert_delayed.test | 12 ++++++--- .../extra/rpl_tests/rpl_foreign_key.test | 2 +- mysql-test/extra/rpl_tests/rpl_insert_id.test | 26 ++++++++++++++++-- mysql-test/r/binlog_row_binlog.result | 18 +++++++++++++ .../r/binlog_statement_insert_delayed.result | 14 ++++++++++ mysql-test/r/binlog_stm_binlog.result | 18 +++++++++++++ mysql-test/r/rpl_insert_id.result | 27 ++++++++++++++++++- mysql-test/r/rpl_loaddata.result | 6 ++--- mysql-test/r/rpl_ndb_insert_ignore.result | 8 +++--- sql/log.cc | 3 --- sql/sp_head.cc | 13 ++++++++- sql/sql_class.cc | 6 +++++ sql/sql_insert.cc | 21 ++++++++++++--- sql/sql_parse.cc | 9 +++++-- 14 files changed, 160 insertions(+), 23 deletions(-) diff --git a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test index 596bb1d5772..6f504fded96 100644 --- a/mysql-test/extra/binlog_tests/binlog_insert_delayed.test +++ b/mysql-test/extra/binlog_tests/binlog_insert_delayed.test @@ -7,14 +7,20 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; insert delayed into t1 values (207); # We use sleeps between statements, that's the only way to get a -# repeatable binlog in a normal test run and under Valgrind. -# It may be that the "binlog missing rows" of BUG#20821 shows up -# here. +# repeatable binlog in a normal test run and under Valgrind. The +# reason is that without sleeps, rows of different INSERT DELAYEDs +# sometimes group together and sometimes not, so the table may be +# unlocked/relocked causing a different number of table map log +# events. sleep 2; insert delayed into t1 values (null); sleep 2; insert delayed into t1 values (300); sleep 2; # time for the delayed queries to reach disk +insert delayed into t1 values (null),(null),(null),(null); +sleep 2; +insert delayed into t1 values (null),(null),(400),(null); +sleep 2; select * from t1; --replace_column 2 # 5 # --replace_regex /table_id: [0-9]+/table_id: #/ diff --git a/mysql-test/extra/rpl_tests/rpl_foreign_key.test b/mysql-test/extra/rpl_tests/rpl_foreign_key.test index d5589d4b5ea..0f4cd856db6 100644 --- a/mysql-test/extra/rpl_tests/rpl_foreign_key.test +++ b/mysql-test/extra/rpl_tests/rpl_foreign_key.test @@ -31,4 +31,4 @@ connection master; SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS t1,t2,t3; SET FOREIGN_KEY_CHECKS=1; - +sync_slave_with_master; diff --git a/mysql-test/extra/rpl_tests/rpl_insert_id.test b/mysql-test/extra/rpl_tests/rpl_insert_id.test index 79f8c39e152..88e864967de 100644 --- a/mysql-test/extra/rpl_tests/rpl_insert_id.test +++ b/mysql-test/extra/rpl_tests/rpl_insert_id.test @@ -289,8 +289,30 @@ select * from t1; select * from t2; connection master; -drop table t1, t2; +drop table t1; drop function insid; -sync_slave_with_master; +truncate table t2; +create table t1 (n int primary key auto_increment not null, +b int, unique(b)); +delimiter |; +create procedure foo() +begin + insert into t1 values(null,10); + insert ignore into t1 values(null,10); + insert ignore into t1 values(null,10); + insert into t2 values(null,3); +end| +delimiter ;| +call foo(); +select * from t1; +select * from t2; +sync_slave_with_master; +select * from t1; +select * from t2; + +connection master; +drop table t1, t2; +drop procedure foo; +sync_slave_with_master; diff --git a/mysql-test/r/binlog_row_binlog.result b/mysql-test/r/binlog_row_binlog.result index 28f2284d3d2..8d5025f7602 100644 --- a/mysql-test/r/binlog_row_binlog.result +++ b/mysql-test/r/binlog_row_binlog.result @@ -250,11 +250,21 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; insert delayed into t1 values (207); insert delayed into t1 values (null); insert delayed into t1 values (300); +insert delayed into t1 values (null),(null),(null),(null); +insert delayed into t1 values (null),(null),(400),(null); select * from t1; a 207 208 300 +301 +302 +303 +304 +305 +306 +400 +401 show binlog events from 102; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key) @@ -268,4 +278,12 @@ master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F drop table t1; diff --git a/mysql-test/r/binlog_statement_insert_delayed.result b/mysql-test/r/binlog_statement_insert_delayed.result index bae01f7dc5d..3cf6ba14e02 100644 --- a/mysql-test/r/binlog_statement_insert_delayed.result +++ b/mysql-test/r/binlog_statement_insert_delayed.result @@ -3,11 +3,21 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; insert delayed into t1 values (207); insert delayed into t1 values (null); insert delayed into t1 values (300); +insert delayed into t1 values (null),(null),(null),(null); +insert delayed into t1 values (null),(null),(400),(null); select * from t1; a 207 208 300 +301 +302 +303 +304 +305 +306 +400 +401 show binlog events from 102; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1 (a int not null auto_increment, primary key (a)) engine=myisam @@ -15,4 +25,8 @@ master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (207) master-bin.000001 # Intvar 1 # INSERT_ID=208 master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null) master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (300) +master-bin.000001 # Intvar 1 # INSERT_ID=301 +master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(null),(null) +master-bin.000001 # Intvar 1 # INSERT_ID=305 +master-bin.000001 # Query 1 # use `test`; insert delayed into t1 values (null),(null),(400),(null) drop table t1; diff --git a/mysql-test/r/binlog_stm_binlog.result b/mysql-test/r/binlog_stm_binlog.result index 171a3c11f07..6589392fe79 100644 --- a/mysql-test/r/binlog_stm_binlog.result +++ b/mysql-test/r/binlog_stm_binlog.result @@ -160,11 +160,21 @@ set @@session.auto_increment_increment=1, @@session.auto_increment_offset=1; insert delayed into t1 values (207); insert delayed into t1 values (null); insert delayed into t1 values (300); +insert delayed into t1 values (null),(null),(null),(null); +insert delayed into t1 values (null),(null),(400),(null); select * from t1; a 207 208 300 +301 +302 +303 +304 +305 +306 +400 +401 show binlog events from 102; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1 (id tinyint auto_increment primary key) @@ -178,4 +188,12 @@ master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Table_map 1 # table_id: # (test.t1) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F +master-bin.000001 # Table_map 1 # table_id: # (test.t1) +master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F drop table t1; diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result index 3c33fe1be2b..19518e8745c 100644 --- a/mysql-test/r/rpl_insert_id.result +++ b/mysql-test/r/rpl_insert_id.result @@ -267,5 +267,30 @@ select * from t2; id last_id 4 0 8 0 -drop table t1, t2; +drop table t1; drop function insid; +truncate table t2; +create table t1 (n int primary key auto_increment not null, +b int, unique(b)); +create procedure foo() +begin +insert into t1 values(null,10); +insert ignore into t1 values(null,10); +insert ignore into t1 values(null,10); +insert into t2 values(null,3); +end| +call foo(); +select * from t1; +n b +1 10 +select * from t2; +id last_id +1 3 +select * from t1; +n b +1 10 +select * from t2; +id last_id +1 3 +drop table t1, t2; +drop procedure foo; diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index c22815186d1..cae11e98caa 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -28,7 +28,7 @@ day id category name 2003-03-22 2416 a bbbbb show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -slave-bin.000001 1248 +slave-bin.000001 1276 drop table t1; drop table t2; drop table t3; @@ -39,7 +39,7 @@ set global sql_slave_skip_counter=1; start slave; 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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1765 # # master-bin.000001 Yes Yes # 0 0 1765 # None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1793 # # master-bin.000001 Yes Yes # 0 0 1793 # None 0 No # set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -49,7 +49,7 @@ change master to master_user='test'; change master to master_user='root'; 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 -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1800 # # master-bin.000001 No No # 0 0 1800 # None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1828 # # master-bin.000001 No No # 0 0 1828 # None 0 No # set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; diff --git a/mysql-test/r/rpl_ndb_insert_ignore.result b/mysql-test/r/rpl_ndb_insert_ignore.result index 4d55328a5d7..030845e89e2 100644 --- a/mysql-test/r/rpl_ndb_insert_ignore.result +++ b/mysql-test/r/rpl_ndb_insert_ignore.result @@ -30,16 +30,16 @@ a b 2 2 3 3 4 4 -7 5 -10 6 +5 5 +6 6 SELECT * FROM t1 ORDER BY a; a b 1 1 2 2 3 3 4 4 -7 5 -10 6 +5 5 +6 6 drop table t1; CREATE TABLE t1 ( a int unsigned not null auto_increment primary key, diff --git a/sql/log.cc b/sql/log.cc index 0336a11d3ad..d15a23de51e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3416,9 +3416,6 @@ bool MYSQL_BIN_LOG::write(Log_event *event_info) } } } - /* Forget those values, for next binlogger: */ - thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; - thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty(); } /* diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fc4aa5e26d6..f9c4cc8c68f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -794,7 +794,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b) This set is produced by tracking user variable reads during statement execution. - Fo SPs, this has the following implications: + For SPs, this has the following implications: 1) thd->user_var_events may contain events from several SP statements and needs to be valid after exection of these statements was finished. In order to achieve that, we @@ -807,6 +807,14 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b) reset_dynamic(&thd->user_var_events); calls in several different places. (TODO cosider moving this into mysql_bin_log.write() function) + + 4.2 Auto_increment storage in binlog + + As we may write two statements to binlog from one single logical statement + (case of "SELECT func1(),func2()": it is binlogged as "SELECT func1()" and + then "SELECT func2()"), we need to reset auto_increment binlog variables + after each binlogged SELECT. Otherwise, the auto_increment value of the + first SELECT would be used for the second too. */ @@ -1526,6 +1534,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, "failed to reflect this change in the binary log"); } reset_dynamic(&thd->user_var_events); + /* Forget those values, in case more function calls are binlogged: */ + thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; + thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty(); } } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 838d91f9c31..35b527584dc 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -634,6 +634,12 @@ bool THD::store_globals() void THD::cleanup_after_query() { + if (!in_sub_stmt) /* stored functions and triggers are a special case */ + { + /* Forget those values, for next binlogger: */ + stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; + auto_inc_intervals_in_cur_stmt_for_binlog.empty(); + } if (first_successful_insert_id_in_cur_stmt > 0) { /* set what LAST_INSERT_ID() will return */ diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 92cad471cf2..8b51ccef9f9 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -563,7 +563,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, free_underlaid_joins(thd, &thd->lex->select_lex); joins_freed= TRUE; - table->file->ha_release_auto_increment(); /* Now all rows are inserted. Time to update logs and sends response to @@ -582,6 +581,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, else #endif { + /* + Do not do this release if this is a delayed insert, it would steal + auto_inc values from the delayed_insert thread as they share TABLE. + */ + table->file->ha_release_auto_increment(); if (!thd->prelocked_mode && table->file->ha_end_bulk_insert() && !error) { table->file->print_error(my_errno,MYF(0)); @@ -2106,6 +2110,16 @@ bool delayed_insert::handle_inserts(void) thd.start_time=row->start_time; thd.query_start_used=row->query_start_used; + /* + To get the exact auto_inc interval to store in the binlog we must not + use values from the previous interval (of the previous rows). + */ + bool log_query= (row->log_query && row->query.str != NULL); + if (log_query) + { + table->file->ha_release_auto_increment(); + thd.auto_inc_intervals_in_cur_stmt_for_binlog.empty(); + } thd.first_successful_insert_id_in_prev_stmt= row->first_successful_insert_id_in_prev_stmt; thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt= @@ -2146,7 +2160,7 @@ bool delayed_insert::handle_inserts(void) table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE); } - if (row->log_query && row->query.str != NULL && mysql_bin_log.is_open()) + if (log_query && mysql_bin_log.is_open()) { /* If the query has several rows to insert, only the first row will come @@ -2542,7 +2556,6 @@ bool select_insert::send_data(List &values) table->next_number_field->reset(); } } - table->file->ha_release_auto_increment(); DBUG_RETURN(error); } @@ -2616,6 +2629,7 @@ void select_insert::send_error(uint errcode,const char *err) } } ha_rollback_stmt(thd); + table->file->ha_release_auto_increment(); DBUG_VOID_RETURN; } @@ -2666,6 +2680,7 @@ bool select_insert::send_eof() } if ((error2=ha_autocommit_or_rollback(thd,error)) && ! error) error=error2; + table->file->ha_release_auto_increment(); if (error) { table->file->print_error(error,MYF(0)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2aceccd1c92..0bee8fa0c53 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5861,9 +5861,14 @@ void mysql_reset_thd_for_next_command(THD *thd) DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */ thd->free_list= 0; thd->select_number= 1; + /* + Those two lines below are theoretically unneeded as + THD::cleanup_after_query() should take care of this already. + */ thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty(); - thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= - thd->query_start_used= 0; + thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; + + thd->query_start_used= 0; thd->is_fatal_error= thd->time_zone_used= 0; thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | SERVER_QUERY_NO_INDEX_USED | From 3936ce19d20e085cb5317d2fc024ee6818e4bbf4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 13 Sep 2006 19:25:12 +0200 Subject: [PATCH 25/37] WL#3259 (RBR with more columns on slave than master): Incorporating changes from review. Fixing one bug that surfaced. mysql-test/extra/rpl_tests/rpl_row_tabledefs.test: Adding tests that UPDATE and DELETE does not generate an error. mysql-test/r/rpl_row_tabledefs_2myisam.result: Result change. mysql-test/r/rpl_row_tabledefs_3innodb.result: Result change. mysql-test/t/disabled.def: Enabling rpl_sp_effects (even though it gives a result mismatch currently). sql/field.cc: Using constant to denote undefined last null byte. sql/field.h: Using constant to denote undefined last null byte. Adding documentation. sql/log_event.cc: Not generating error for non-NULL no-DEFAULT columns when updating or deleting row. Better documentation and comments. sql/rpl_utility.cc: Moving documentation to header file. sql/rpl_utility.h: Documenting class and members. --- .../extra/rpl_tests/rpl_row_tabledefs.test | 68 ++++++++++- mysql-test/r/rpl_row_tabledefs_2myisam.result | 105 ++++++++++++++++- mysql-test/r/rpl_row_tabledefs_3innodb.result | 97 ++++++++++++++- mysql-test/t/disabled.def | 1 - sql/field.cc | 10 +- sql/field.h | 31 ++++- sql/log_event.cc | 110 ++++++++++++------ sql/rpl_utility.cc | 5 - sql/rpl_utility.h | 76 +++++++++++- 9 files changed, 441 insertions(+), 62 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index b17103d8396..1d39a2c3efd 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -25,6 +25,8 @@ eval CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE=$engine_type; eval CREATE TABLE t4 (a INT) ENGINE=$engine_type; eval CREATE TABLE t5 (a INT, b INT, c INT) ENGINE=$engine_type; eval CREATE TABLE t6 (a INT, b INT, c INT) ENGINE=$engine_type; +eval CREATE TABLE t7 (a INT NOT NULL) ENGINE=$engine_type; +eval CREATE TABLE t8 (a INT NOT NULL) ENGINE=$engine_type; # Table used to detect that slave is running eval CREATE TABLE t9 (a INT) ENGINE=$engine_type; @@ -53,6 +55,17 @@ ALTER TABLE t5 MODIFY b FLOAT; # ... change the type of the last column of table 't6' ALTER TABLE t6 MODIFY c FLOAT; +# ... add one byte worth of null bytes to the table on the slave +ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT, + ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT; + +# ... add 8 columns that are nullable: t8 will not be entirely +# nullable and have no null bits (just an X bit) +ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, + ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, + ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, + ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; + # Insert some values for tables on slave side. These should not be # modified when the row from the master is applied. INSERT INTO t1_int VALUES (2, 4, 4711); @@ -90,7 +103,7 @@ SELECT a,b,x FROM t1_int; SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit; SELECT a,b,x FROM t1_char; -# Each of these should generate an error and stop the slave +# Each of these inserts should generate an error and stop the slave connection master; INSERT INTO t9 VALUES (2); @@ -162,9 +175,60 @@ wait_for_slave_to_stop; SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; +connection master; +INSERT INTO t9 VALUES (6); +sync_slave_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 7 # 8 # 9 # 22 # 23 # 33 # +--query_vertical SHOW SLAVE STATUS + +# Testing some tables extra field that can be null and cannot be null +# (but have default values) + +connection master; +INSERT INTO t7 VALUES (1),(2),(3); +INSERT INTO t8 VALUES (1),(2),(3); +SELECT * FROM t7; +SELECT * FROM t8; +sync_slave_with_master; +SELECT * FROM t7; +SELECT * FROM t8; + +# We will now try to update and then delete a row on the master where +# the extra field on the slave does not have a default value. This +# update should not generate an error even though there is no default +# for the extra column. + +--echo **** On Master **** +connection master; +TRUNCATE t1_nodef; +SET SQL_LOG_BIN=0; +INSERT INTO t1_nodef VALUES (1,2); +INSERT INTO t1_nodef VALUES (2,4); +SET SQL_LOG_BIN=1; +--echo **** On Slave **** +connection slave; +INSERT INTO t1_nodef VALUES (1,2,3); +INSERT INTO t1_nodef VALUES (2,4,6); +--echo **** On Master **** +connection master; +UPDATE t1_nodef SET b=2*b WHERE a=1; +SELECT * FROM t1_nodef; +--echo **** On Slave **** +sync_slave_with_master; +SELECT * FROM t1_nodef; +--echo **** On Master **** +connection master; +DELETE FROM t1_nodef WHERE a=2; +SELECT * FROM t1_nodef; +--echo **** On Slave **** +sync_slave_with_master; +SELECT * FROM t1_nodef; + +--echo **** Cleanup **** connection master; --disable_warnings DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; -DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings sync_slave_with_master; diff --git a/mysql-test/r/rpl_row_tabledefs_2myisam.result b/mysql-test/r/rpl_row_tabledefs_2myisam.result index 37559b0412a..ae792a5dc2a 100644 --- a/mysql-test/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/r/rpl_row_tabledefs_2myisam.result @@ -16,6 +16,8 @@ CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='MyISAM'; CREATE TABLE t4 (a INT) ENGINE='MyISAM'; CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='MyISAM'; CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='MyISAM'; +CREATE TABLE t7 (a INT NOT NULL) ENGINE='MyISAM'; +CREATE TABLE t8 (a INT NOT NULL) ENGINE='MyISAM'; CREATE TABLE t9 (a INT) ENGINE='MyISAM'; ALTER TABLE t1_int ADD x INT DEFAULT 42; ALTER TABLE t1_bit @@ -28,6 +30,12 @@ ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t6 MODIFY c FLOAT; +ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT, +ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT; +ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, +ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, +ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, +ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -151,7 +159,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns Skip_Counter 0 Exec_Master_Log_Pos # @@ -189,7 +197,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -227,7 +235,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -265,7 +273,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -282,5 +290,92 @@ Master_SSL_Key Seconds_Behind_Master # SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; +INSERT INTO t9 VALUES (6); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +INSERT INTO t7 VALUES (1),(2),(3); +INSERT INTO t8 VALUES (1),(2),(3); +SELECT * FROM t7; +a +1 +2 +3 +SELECT * FROM t8; +a +1 +2 +3 +SELECT * FROM t7; +a e1 e2 e3 e4 e5 e6 e7 e8 +1 NULL NULL NULL NULL NULL NULL NULL NULL +2 NULL NULL NULL NULL NULL NULL NULL NULL +3 NULL NULL NULL NULL NULL NULL NULL NULL +SELECT * FROM t8; +a e1 e2 e3 e4 e5 e6 e7 e8 +1 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 +3 0 0 0 0 0 0 0 0 +**** On Master **** +TRUNCATE t1_nodef; +SET SQL_LOG_BIN=0; +INSERT INTO t1_nodef VALUES (1,2); +INSERT INTO t1_nodef VALUES (2,4); +SET SQL_LOG_BIN=1; +**** On Slave **** +INSERT INTO t1_nodef VALUES (1,2,3); +INSERT INTO t1_nodef VALUES (2,4,6); +**** On Master **** +UPDATE t1_nodef SET b=2*b WHERE a=1; +SELECT * FROM t1_nodef; +a b +1 4 +2 4 +**** On Slave **** +SELECT * FROM t1_nodef; +a b x +1 4 3 +2 4 6 +**** On Master **** +DELETE FROM t1_nodef WHERE a=2; +SELECT * FROM t1_nodef; +a b +1 4 +**** On Slave **** +SELECT * FROM t1_nodef; +a b x +1 4 3 +**** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; -DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/r/rpl_row_tabledefs_3innodb.result b/mysql-test/r/rpl_row_tabledefs_3innodb.result index 0c1b25ec7fc..b7f0b7b15e2 100644 --- a/mysql-test/r/rpl_row_tabledefs_3innodb.result +++ b/mysql-test/r/rpl_row_tabledefs_3innodb.result @@ -16,6 +16,8 @@ CREATE TABLE t3 (a INT PRIMARY KEY, b INT) ENGINE='InnoDB'; CREATE TABLE t4 (a INT) ENGINE='InnoDB'; CREATE TABLE t5 (a INT, b INT, c INT) ENGINE='InnoDB'; CREATE TABLE t6 (a INT, b INT, c INT) ENGINE='InnoDB'; +CREATE TABLE t7 (a INT NOT NULL) ENGINE='InnoDB'; +CREATE TABLE t8 (a INT NOT NULL) ENGINE='InnoDB'; CREATE TABLE t9 (a INT) ENGINE='InnoDB'; ALTER TABLE t1_int ADD x INT DEFAULT 42; ALTER TABLE t1_bit @@ -28,6 +30,12 @@ ALTER TABLE t2 DROP b; ALTER TABLE t4 MODIFY a FLOAT; ALTER TABLE t5 MODIFY b FLOAT; ALTER TABLE t6 MODIFY c FLOAT; +ALTER TABLE t7 ADD e1 INT, ADD e2 INT, ADD e3 INT, ADD e4 INT, +ADD e5 INT, ADD e6 INT, ADD e7 INT, ADD e8 INT; +ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, +ADD e3 INT NOT NULL DEFAULT 0, ADD e4 INT NOT NULL DEFAULT 0, +ADD e5 INT NOT NULL DEFAULT 0, ADD e6 INT NOT NULL DEFAULT 0, +ADD e7 INT NOT NULL DEFAULT 0, ADD e8 INT NOT NULL DEFAULT 0; INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -282,5 +290,92 @@ Master_SSL_Key Seconds_Behind_Master # SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; +INSERT INTO t9 VALUES (6); +SHOW SLAVE STATUS; +Slave_IO_State # +Master_Host 127.0.0.1 +Master_User root +Master_Port MASTER_PORT +Connect_Retry 1 +Master_Log_File master-bin.000001 +Read_Master_Log_Pos # +Relay_Log_File # +Relay_Log_Pos # +Relay_Master_Log_File master-bin.000001 +Slave_IO_Running Yes +Slave_SQL_Running Yes +Replicate_Do_DB +Replicate_Ignore_DB +Replicate_Do_Table +Replicate_Ignore_Table +Replicate_Wild_Do_Table +Replicate_Wild_Ignore_Table +Last_Errno 0 +Last_Error +Skip_Counter 0 +Exec_Master_Log_Pos # +Relay_Log_Space # +Until_Condition None +Until_Log_File +Until_Log_Pos 0 +Master_SSL_Allowed No +Master_SSL_CA_File +Master_SSL_CA_Path +Master_SSL_Cert +Master_SSL_Cipher +Master_SSL_Key +Seconds_Behind_Master # +INSERT INTO t7 VALUES (1),(2),(3); +INSERT INTO t8 VALUES (1),(2),(3); +SELECT * FROM t7; +a +1 +2 +3 +SELECT * FROM t8; +a +1 +2 +3 +SELECT * FROM t7; +a e1 e2 e3 e4 e5 e6 e7 e8 +1 NULL NULL NULL NULL NULL NULL NULL NULL +2 NULL NULL NULL NULL NULL NULL NULL NULL +3 NULL NULL NULL NULL NULL NULL NULL NULL +SELECT * FROM t8; +a e1 e2 e3 e4 e5 e6 e7 e8 +1 0 0 0 0 0 0 0 0 +2 0 0 0 0 0 0 0 0 +3 0 0 0 0 0 0 0 0 +**** On Master **** +TRUNCATE t1_nodef; +SET SQL_LOG_BIN=0; +INSERT INTO t1_nodef VALUES (1,2); +INSERT INTO t1_nodef VALUES (2,4); +SET SQL_LOG_BIN=1; +**** On Slave **** +INSERT INTO t1_nodef VALUES (1,2,3); +INSERT INTO t1_nodef VALUES (2,4,6); +**** On Master **** +UPDATE t1_nodef SET b=2*b WHERE a=1; +SELECT * FROM t1_nodef; +a b +1 4 +2 4 +**** On Slave **** +SELECT * FROM t1_nodef; +a b x +1 4 3 +2 4 6 +**** On Master **** +DELETE FROM t1_nodef WHERE a=2; +SELECT * FROM t1_nodef; +a b +1 4 +**** On Slave **** +SELECT * FROM t1_nodef; +a b x +1 4 3 +**** Cleanup **** DROP TABLE IF EXISTS t1_int,t1_bit,t1_char,t1_nodef; -DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t9; +DROP TABLE IF EXISTS t2,t3,t4,t5,t6,t7,t8,t9; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index f1322fcb699..a3bedbaa22d 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -36,7 +36,6 @@ rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever rpl_sp : BUG#16456 2006-02-16 jmiller -rpl_sp_effects : BUG#19862 2006-08-22 mats Bug appear to be fixed rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case sp-goto : BUG#18949 2006-02-16 jmiller GOTO is currently is disabled - will be fixed in the future mysqldump : BUG#18078 2006-03-10 lars diff --git a/sql/field.cc b/sql/field.cc index 340f33f1e01..479a562aaac 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1261,7 +1261,10 @@ my_size_t Field::do_last_null_byte() const { DBUG_ASSERT(null_ptr == NULL || (byte*) null_ptr >= table->record[0]); - return null_ptr ? (byte*) null_ptr - table->record[0] + 1 : 0; + if (null_ptr) + return (byte*) null_ptr - table->record[0] + 1; + else + return LAST_NULL_BYTE_UNDEF; } @@ -8196,7 +8199,10 @@ Field_bit::do_last_null_byte() const else result= bit_ptr; - return result ? (byte*) result - table->record[0] + 1 : 0; + if (result) + return (byte*) result - table->record[0] + 1; + else + return LAST_NULL_BYTE_UNDEF; } Field *Field_bit::new_key_field(MEM_ROOT *root, diff --git a/sql/field.h b/sql/field.h index 51b624b799f..26a9cd0b465 100644 --- a/sql/field.h +++ b/sql/field.h @@ -208,10 +208,24 @@ public: inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; } inline bool real_maybe_null(void) { return null_ptr != 0; } + enum { + LAST_NULL_BYTE_UNDEF= 0 + }; + /* - Return a pointer to the last byte of the null bytes where the - field conceptually is placed. In the case that the field does not - use any bits of the null bytes, a null pointer is returned. + Find the position of the last null byte for the field. + + SYNOPSIS + last_null_byte() + + DESCRIPTION + Return a pointer to the last byte of the null bytes where the + field conceptually is placed. + + RETURN VALUE + The position of the last null byte relative to the beginning of + the record. If the field does not use any bits of the null + bytes, the value 0 (LAST_NULL_BYTE_UNDEF) is returned. */ my_size_t last_null_byte() const { my_size_t bytes= do_last_null_byte(); @@ -384,6 +398,17 @@ public: friend class Item_func_group_concat; private: + /* + Primitive for implementing last_null_byte(). + + SYNOPSIS + do_last_null_byte() + + DESCRIPTION + Primitive for the implementation of the last_null_byte() + function. This represents the inheritance interface and can be + overridden by subclasses. + */ virtual my_size_t do_last_null_byte() const; }; diff --git a/sql/log_event.cc b/sql/log_event.cc index ceacc1eade7..ebfaa4bfff3 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5304,7 +5304,7 @@ int Rows_log_event::do_add_row_data(byte *const row_data, row_end Pointer to variable that will hold the value of the one-after-end position for the row master_reclength - Pointer to variable that will hold the length of the + Pointer to variable that will be set to the length of the record on the master side rw_set Pointer to bitmap that holds either the read_set or the write_set of the table @@ -5317,13 +5317,22 @@ int Rows_log_event::do_add_row_data(byte *const row_data, At most 'colcnt' columns are read: if the table is larger than that, the remaining fields are not filled in. + + RETURN VALUE + + Error code, or zero if no error. The following error codes can + be returned: + + ER_NO_DEFAULT_FOR_FIELD + Returned if one of the fields existing on the slave but not on + the master does not have a default value (and isn't nullable) */ static int unpack_row(RELAY_LOG_INFO *rli, TABLE *table, uint const colcnt, byte *record, char const *row, MY_BITMAP const *cols, char const **row_end, ulong *master_reclength, - MY_BITMAP* const rw_set) + MY_BITMAP* const rw_set, Log_event_type const event_type) { DBUG_ASSERT(record && row); my_ptrdiff_t const offset= record - (byte*) table->record[0]; @@ -5334,10 +5343,20 @@ unpack_row(RELAY_LOG_INFO *rli, Field **fptr= &table->field[colcnt-1]; do master_null_bytes= (*fptr)->last_null_byte(); - while (master_null_bytes == 0 && fptr-- > table->field); + while (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF && + fptr-- > table->field); - if (master_null_bytes == 0) - master_null_bytes= table->s->null_bytes; + /* + If master_null_bytes is LAST_NULL_BYTE_UNDEF (0) at this time, + there were no nullable fields nor BIT fields at all in the + columns that are common to the master and the slave. In that + case, there is only one null byte holding the X bit. + + OBSERVE! There might still be nullable columns following the + common columns, so table->s->null_bytes might be greater than 1. + */ + if (master_null_bytes == Field::LAST_NULL_BYTE_UNDEF) + master_null_bytes= 1; } DBUG_ASSERT(master_null_bytes <= table->s->null_bytes); @@ -5348,31 +5367,29 @@ unpack_row(RELAY_LOG_INFO *rli, Field **const begin_ptr = table->field; Field **field_ptr; + char const *ptr= row + master_null_bytes; + Field **const end_ptr= begin_ptr + colcnt; + for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr) { - char const *ptr= row + master_null_bytes; - Field **const end_ptr= begin_ptr + colcnt; - for (field_ptr= begin_ptr ; field_ptr < end_ptr ; ++field_ptr) - { - Field *const f= *field_ptr; + Field *const f= *field_ptr; - if (bitmap_is_set(cols, field_ptr - begin_ptr)) - { - ptr= f->unpack(f->ptr + offset, ptr); - /* Field...::unpack() cannot return 0 */ - DBUG_ASSERT(ptr != NULL); - } - else - bitmap_clear_bit(rw_set, field_ptr - begin_ptr); - } - - *row_end = ptr; - if (master_reclength) + if (bitmap_is_set(cols, field_ptr - begin_ptr)) { - if (*field_ptr) - *master_reclength = (*field_ptr)->ptr - (char*) table->record[0]; - else - *master_reclength = table->s->reclength; + ptr= f->unpack(f->ptr + offset, ptr); + /* Field...::unpack() cannot return 0 */ + DBUG_ASSERT(ptr != NULL); } + else + bitmap_clear_bit(rw_set, field_ptr - begin_ptr); + } + + *row_end = ptr; + if (master_reclength) + { + if (*field_ptr) + *master_reclength = (*field_ptr)->ptr - (char*) table->record[0]; + else + *master_reclength = table->s->reclength; } /* @@ -5381,16 +5398,26 @@ unpack_row(RELAY_LOG_INFO *rli, it was not there already. We iterate over all remaining columns, even if there were an error, to get as many error messages as possible. We are still able to return a pointer to the next row, - so wedo that. + so redo that. + + This generation of error messages is only relevant when inserting + new rows. */ for ( ; *field_ptr ; ++field_ptr) { - if ((*field_ptr)->flags & (NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG)) + uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG; + + DBUG_PRINT("debug", ("flags = 0x%x, mask = 0x%x, flags & mask = 0x%x", + (*field_ptr)->flags, mask, + (*field_ptr)->flags & mask)); + + if (event_type == WRITE_ROWS_EVENT && + ((*field_ptr)->flags & mask) == mask) { - slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD, + slave_print_msg(ERROR_LEVEL, rli, ER_NO_DEFAULT_FOR_FIELD, "Field `%s` of table `%s`.`%s` " "has no default value and cannot be NULL", - (*field_ptr)->field_name, table->s->db.str, + (*field_ptr)->field_name, table->s->db.str, table->s->table_name.str); error = ER_NO_DEFAULT_FOR_FIELD; } @@ -5562,8 +5589,8 @@ int Rows_log_event::exec_event(st_relay_log_info *rli) { char const *row_end= NULL; if ((error= do_prepare_row(thd, rli, table, row_start, &row_end))) - break; // We should to the after-row operation even in the - // case of error + break; // We should perform the after-row operation even in + // the case of error DBUG_ASSERT(row_end != NULL); // cannot happen DBUG_ASSERT(row_end <= (const char*)m_rows_end); @@ -6224,7 +6251,7 @@ int Write_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, error= unpack_row(rli, table, m_width, table->record[0], row_start, &m_cols, row_end, &m_master_reclength, - table->write_set); + table->write_set, WRITE_ROWS_EVENT); bitmap_copy(table->read_set, table->write_set); return error; } @@ -6285,10 +6312,17 @@ copy_extra_record_fields(TABLE *table, my_size_t master_reclength, my_ptrdiff_t master_fields) { - DBUG_PRINT("info", ("Copying to %p from field %d at offset %u to field %d at offset %u", - table->record[0], + DBUG_PRINT("info", ("Copying to %p " + "from field %d at offset %u " + "to field %d at offset %u", + table->record[0], master_fields, master_reclength, table->s->fields, table->s->reclength)); + /* + Copying the extra fields of the slave that does not exist on + master into record[0] (which are basically the default values). + */ + DBUG_ASSERT(master_reclength <= table->s->reclength); if (master_reclength < table->s->reclength) bmove_align(table->record[0] + master_reclength, table->record[1] + master_reclength, @@ -6771,7 +6805,7 @@ int Delete_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, error= unpack_row(rli, table, m_width, table->record[0], row_start, &m_cols, row_end, &m_master_reclength, - table->read_set); + table->read_set, DELETE_ROWS_EVENT); /* If we will access rows using the random access method, m_key will be set to NULL, so we do not need to make a key copy in that case. @@ -6914,13 +6948,13 @@ int Update_rows_log_event::do_prepare_row(THD *thd, RELAY_LOG_INFO *rli, error= unpack_row(rli, table, m_width, table->record[0], row_start, &m_cols, row_end, &m_master_reclength, - table->read_set); + table->read_set, UPDATE_ROWS_EVENT); row_start = *row_end; /* m_after_image is the after image for the update */ error= unpack_row(rli, table, m_width, m_after_image, row_start, &m_cols, row_end, &m_master_reclength, - table->write_set); + table->write_set, UPDATE_ROWS_EVENT); /* If we will access rows using the random access method, m_key will diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 5405d022223..c80b6dc3f69 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -107,11 +107,6 @@ field_length_from_packed(enum_field_types const field_type, /* Is the definition compatible with a table? - Compare the definition with a table to see if it is compatible with - it. A table definition is compatible with a table if - - the columns types of the table definition is a (not necessarily - proper) prefix of the column type of the table, or - - the other way around */ int table_def::compatible_with(RELAY_LOG_INFO *rli, TABLE *table) diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 0ac3c10eec6..df0b0cd2ee1 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -32,29 +32,95 @@ field_length_from_packed(enum_field_types const field_type, RESPONSIBILITIES - - Extract table definition data from the table map event + - Extract and decode table definition data from the table map event - Check if table definition in table map is compatible with table definition on slave + + DESCRIPTION + + Currently, the only field type data available is an array of the + type operators that are present in the table map event. + + TODO + + Add type operands to this structure to allow detection of + difference between, e.g., BIT(5) and BIT(10). */ class table_def { public: + /* + Convenience declaration of the type of the field type data in a + table map event. + */ typedef unsigned char field_type; - table_def(field_type *t, my_size_t s) - : m_type(t), m_size(s) + /* + Constructor. + + SYNOPSIS + table_def() + types Array of types + size Number of elements in array 'types' + */ + table_def(field_type *types, my_size_t size) + : m_type(types), m_size(size) { } + /* + Return the number of fields there is type data for. + + SYNOPSIS + size() + + RETURN VALUE + The number of fields that there is type data for. + */ my_size_t size() const { return m_size; } + + /* + Return a representation of the type data for one field. + + SYNOPSIS + type() + i Field index to return data for + + RETURN VALUE + + Will return a representation of the type data for field + 'i'. Currently, only the type identifier is returned. + */ field_type type(my_ptrdiff_t i) const { return m_type[i]; } + /* + Decide if the table definition is compatible with a table. + + SYNOPSIS + compatible_with() + rli Pointer to relay log info + table Pointer to table to compare with. + + DESCRIPTION + + Compare the definition with a table to see if it is compatible + with it. A table definition is compatible with a table if: + + - the columns types of the table definition is a (not + necessarily proper) prefix of the column type of the table, or + + - the other way around + + RETURN VALUE + 1 if the table definition is not compatible with 'table' + 0 if the table definition is compatible with 'table' + */ int compatible_with(RELAY_LOG_INFO *rli, TABLE *table) const; private: - my_size_t m_size; - field_type *m_type; + my_size_t m_size; // Number of elements in the types array + field_type *m_type; // Array of type descriptors }; #endif /* RPL_UTILITY_H */ From 63387829420571ab82debaa32267d195f31e0db6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 03:37:40 +0400 Subject: [PATCH 26/37] WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. mysql-test/r/information_schema.result: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Fixed test cases result (changes are due to the new tables added). mysql-test/r/information_schema_db.result: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Fixed test cases result (changes are due to the new tables added). mysql-test/r/status.result: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Fixed results for added testcases. mysql-test/r/variables.result: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Fixed results for added test cases. mysql-test/t/status.test: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Added test cases. mysql-test/t/variables.test: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Added test cases. sql/sql_show.cc: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Implementation of the new I_S tables. Also, show_status_array(): argument 'ucase_names' is added (true means that all variable names are to be converted to upper case). sql/table.h: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Implementation of the new I_S tables. --- mysql-test/r/information_schema.result | 16 +- mysql-test/r/information_schema_db.result | 4 + mysql-test/r/status.result | 23 +++ mysql-test/r/variables.result | 151 ++++++++++++++ mysql-test/t/status.test | 7 + mysql-test/t/variables.test | 50 +++++ sql/sql_show.cc | 233 +++++++++++++++++++++- sql/table.h | 4 + 8 files changed, 479 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 077fa0f2376..9ba55e42326 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -46,6 +46,8 @@ COLUMN_PRIVILEGES ENGINES EVENTS FILES +GLOBAL_STATUS +GLOBAL_VARIABLES KEY_COLUMN_USAGE PARTITIONS PLUGINS @@ -54,6 +56,8 @@ REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES +SESSION_STATUS +SESSION_VARIABLES STATISTICS TABLES TABLE_CONSTRAINTS @@ -758,6 +762,7 @@ table_schema table_name column_name information_schema COLUMNS COLUMN_TYPE information_schema EVENTS EVENT_DEFINITION information_schema EVENTS SQL_MODE +information_schema GLOBAL_VARIABLES VARIABLE_VALUE information_schema PARTITIONS PARTITION_EXPRESSION information_schema PARTITIONS SUBPARTITION_EXPRESSION information_schema PARTITIONS PARTITION_DESCRIPTION @@ -765,6 +770,7 @@ information_schema PLUGINS PLUGIN_DESCRIPTION information_schema PROCESSLIST INFO information_schema ROUTINES ROUTINE_DEFINITION information_schema ROUTINES SQL_MODE +information_schema SESSION_VARIABLES VARIABLE_VALUE information_schema TRIGGERS ACTION_CONDITION information_schema TRIGGERS ACTION_STATEMENT information_schema TRIGGERS SQL_MODE @@ -847,7 +853,7 @@ delete from mysql.db where user='mysqltest_4'; flush privileges; SELECT table_schema, count(*) FROM information_schema.TABLES where TABLE_SCHEMA!='cluster' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 23 +information_schema 27 mysql 21 create table t1 (i int, j int); create trigger trg1 before insert on t1 for each row @@ -1240,6 +1246,8 @@ COLUMN_PRIVILEGES TABLE_SCHEMA ENGINES ENGINE EVENTS EVENT_SCHEMA FILES TABLE_SCHEMA +GLOBAL_STATUS VARIABLE_NAME +GLOBAL_VARIABLES VARIABLE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME @@ -1248,6 +1256,8 @@ REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA ROUTINES ROUTINE_SCHEMA SCHEMATA SCHEMA_NAME SCHEMA_PRIVILEGES TABLE_SCHEMA +SESSION_STATUS VARIABLE_NAME +SESSION_VARIABLES VARIABLE_NAME STATISTICS TABLE_SCHEMA TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA @@ -1278,6 +1288,8 @@ COLUMN_PRIVILEGES TABLE_SCHEMA ENGINES ENGINE EVENTS EVENT_SCHEMA FILES TABLE_SCHEMA +GLOBAL_STATUS VARIABLE_NAME +GLOBAL_VARIABLES VARIABLE_NAME KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME @@ -1286,6 +1298,8 @@ REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA ROUTINES ROUTINE_SCHEMA SCHEMATA SCHEMA_NAME SCHEMA_PRIVILEGES TABLE_SCHEMA +SESSION_STATUS VARIABLE_NAME +SESSION_VARIABLES VARIABLE_NAME STATISTICS TABLE_SCHEMA TABLES TABLE_SCHEMA TABLE_CONSTRAINTS CONSTRAINT_SCHEMA diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result index faba5e8d83c..db14b7b6600 100644 --- a/mysql-test/r/information_schema_db.result +++ b/mysql-test/r/information_schema_db.result @@ -13,6 +13,8 @@ COLUMN_PRIVILEGES ENGINES EVENTS FILES +GLOBAL_STATUS +GLOBAL_VARIABLES KEY_COLUMN_USAGE PARTITIONS PLUGINS @@ -21,6 +23,8 @@ REFERENTIAL_CONSTRAINTS ROUTINES SCHEMATA SCHEMA_PRIVILEGES +SESSION_STATUS +SESSION_VARIABLES STATISTICS TABLES TABLE_CONSTRAINTS diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index 83c6a6f5288..48a1d80dc7e 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -3,6 +3,10 @@ show status like 'Table_lock%'; Variable_name Value Table_locks_immediate 0 Table_locks_waited 0 +select * from information_schema.session_status where variable_name like 'Table_lock%'; +VARIABLE_NAME VARIABLE_VALUE +TABLE_LOCKS_IMMEDIATE 0.0000000 +TABLE_LOCKS_WAITED 0.0000000 SET SQL_LOG_BIN=0; drop table if exists t1; create table t1(n int) engine=myisam; @@ -16,6 +20,10 @@ show status like 'Table_lock%'; Variable_name Value Table_locks_immediate 3 Table_locks_waited 1 +select * from information_schema.session_status where variable_name like 'Table_lock%'; +VARIABLE_NAME VARIABLE_VALUE +TABLE_LOCKS_IMMEDIATE 3.0000000 +TABLE_LOCKS_WAITED 1.0000000 drop table t1; select 1; 1 @@ -53,21 +61,36 @@ FLUSH STATUS; SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 2 +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; +VARIABLE_NAME VARIABLE_VALUE +MAX_USED_CONNECTIONS 2.0000000 SET @save_thread_cache_size=@@thread_cache_size; SET GLOBAL thread_cache_size=3; SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 4 +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; +VARIABLE_NAME VARIABLE_VALUE +MAX_USED_CONNECTIONS 4.0000000 FLUSH STATUS; SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 3 +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; +VARIABLE_NAME VARIABLE_VALUE +MAX_USED_CONNECTIONS 3.0000000 SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 4 +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; +VARIABLE_NAME VARIABLE_VALUE +MAX_USED_CONNECTIONS 4.0000000 SHOW STATUS LIKE 'max_used_connections'; Variable_name Value Max_used_connections 5 +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; +VARIABLE_NAME VARIABLE_VALUE +MAX_USED_CONNECTIONS 5.0000000 SET GLOBAL thread_cache_size=@save_thread_cache_size; show status like 'com_show_status'; Variable_name Value diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 3b6bfc60a80..5526ca8634f 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -103,21 +103,36 @@ set max_join_size=100; show variables like 'max_join_size'; Variable_name Value max_join_size 100 +select * from information_schema.session_variables where variable_name like 'max_join_size'; +VARIABLE_NAME VARIABLE_VALUE +MAX_JOIN_SIZE 100 show global variables like 'max_join_size'; Variable_name Value max_join_size 10 +select * from information_schema.global_variables where variable_name like 'max_join_size'; +VARIABLE_NAME VARIABLE_VALUE +MAX_JOIN_SIZE 10 set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; Variable_name Value max_join_size 2000 +select * from information_schema.global_variables where variable_name like 'max_join_size'; +VARIABLE_NAME VARIABLE_VALUE +MAX_JOIN_SIZE 2000 set max_join_size=DEFAULT; show variables like 'max_join_size'; Variable_name Value max_join_size 2000 +select * from information_schema.session_variables where variable_name like 'max_join_size'; +VARIABLE_NAME VARIABLE_VALUE +MAX_JOIN_SIZE 2000 set GLOBAL max_join_size=DEFAULT; show global variables like 'max_join_size'; Variable_name Value max_join_size HA_POS_ERROR +select * from information_schema.global_variables where variable_name like 'max_join_size'; +VARIABLE_NAME VARIABLE_VALUE +MAX_JOIN_SIZE HA_POS_ERROR set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; @@local.max_join_size @@global.max_join_size @@ -149,14 +164,23 @@ set global concurrent_insert=2; show variables like 'concurrent_insert'; Variable_name Value concurrent_insert 2 +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; +VARIABLE_NAME VARIABLE_VALUE +CONCURRENT_INSERT 2 set global concurrent_insert=1; show variables like 'concurrent_insert'; Variable_name Value concurrent_insert 1 +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; +VARIABLE_NAME VARIABLE_VALUE +CONCURRENT_INSERT 1 set global concurrent_insert=0; show variables like 'concurrent_insert'; Variable_name Value concurrent_insert 0 +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; +VARIABLE_NAME VARIABLE_VALUE +CONCURRENT_INSERT 0 set global concurrent_insert=DEFAULT; select @@concurrent_insert; @@concurrent_insert @@ -165,26 +189,44 @@ set global timed_mutexes=ON; show variables like 'timed_mutexes'; Variable_name Value timed_mutexes ON +select * from information_schema.session_variables where variable_name like 'timed_mutexes'; +VARIABLE_NAME VARIABLE_VALUE +TIMED_MUTEXES ON set global timed_mutexes=0; show variables like 'timed_mutexes'; Variable_name Value timed_mutexes OFF +select * from information_schema.session_variables where variable_name like 'timed_mutexes'; +VARIABLE_NAME VARIABLE_VALUE +TIMED_MUTEXES OFF set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="MERGE"; show local variables like 'storage_engine'; Variable_name Value storage_engine MEMORY +select * from information_schema.session_variables where variable_name like 'storage_engine'; +VARIABLE_NAME VARIABLE_VALUE +STORAGE_ENGINE MEMORY show global variables like 'storage_engine'; Variable_name Value storage_engine MRG_MYISAM +select * from information_schema.global_variables where variable_name like 'storage_engine'; +VARIABLE_NAME VARIABLE_VALUE +STORAGE_ENGINE MRG_MYISAM set GLOBAL query_cache_size=100000; set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; Variable_name Value myisam_max_sort_file_size 1048576 +select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; +VARIABLE_NAME VARIABLE_VALUE +MYISAM_MAX_SORT_FILE_SIZE 1048576 set GLOBAL myisam_max_sort_file_size=default; show variables like 'myisam_max_sort_file_size'; Variable_name Value myisam_max_sort_file_size FILE_SIZE +select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; +VARIABLE_NAME VARIABLE_VALUE +MYISAM_MAX_SORT_FILE_SIZE FILE_SIZE set global net_retry_count=10, session net_retry_count=10; set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300; set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600; @@ -194,12 +236,24 @@ net_buffer_length 1024 net_read_timeout 300 net_retry_count 10 net_write_timeout 200 +select * from information_schema.global_variables where variable_name like 'net_%'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 1024 +NET_READ_TIMEOUT 300 +NET_RETRY_COUNT 10 +NET_WRITE_TIMEOUT 200 show session variables like 'net_%'; Variable_name Value net_buffer_length 2048 net_read_timeout 600 net_retry_count 10 net_write_timeout 500 +select * from information_schema.session_variables where variable_name like 'net_%'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 2048 +NET_READ_TIMEOUT 600 +NET_RETRY_COUNT 10 +NET_WRITE_TIMEOUT 500 set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000; show global variables like 'net_%'; Variable_name Value @@ -207,24 +261,45 @@ net_buffer_length 1024 net_read_timeout 900 net_retry_count 10 net_write_timeout 1000 +select * from information_schema.global_variables where variable_name like 'net_%'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 1024 +NET_READ_TIMEOUT 900 +NET_RETRY_COUNT 10 +NET_WRITE_TIMEOUT 1000 show session variables like 'net_%'; Variable_name Value net_buffer_length 7168 net_read_timeout 600 net_retry_count 10 net_write_timeout 500 +select * from information_schema.session_variables where variable_name like 'net_%'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 7168 +NET_READ_TIMEOUT 600 +NET_RETRY_COUNT 10 +NET_WRITE_TIMEOUT 500 set net_buffer_length=1; show variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1024 +select * from information_schema.session_variables where variable_name like 'net_buffer_length'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 1024 set net_buffer_length=2000000000; show variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1048576 +select * from information_schema.session_variables where variable_name like 'net_buffer_length'; +VARIABLE_NAME VARIABLE_VALUE +NET_BUFFER_LENGTH 1048576 set character set cp1251_koi8; show variables like "character_set_client"; Variable_name Value character_set_client cp1251 +select * from information_schema.session_variables where variable_name like 'character_set_client'; +VARIABLE_NAME VARIABLE_VALUE +CHARACTER_SET_CLIENT cp1251 select @@timestamp>0; @@timestamp>0 1 @@ -239,6 +314,13 @@ query_prealloc_size 8192 range_alloc_block_size 2048 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 +select * from information_schema.session_variables where variable_name like '%alloc%'; +VARIABLE_NAME VARIABLE_VALUE +QUERY_ALLOC_BLOCK_SIZE 8192 +QUERY_PREALLOC_SIZE 8192 +RANGE_ALLOC_BLOCK_SIZE 2048 +TRANSACTION_ALLOC_BLOCK_SIZE 8192 +TRANSACTION_PREALLOC_SIZE 4096 set @@range_alloc_block_size=1024*16; set @@query_alloc_block_size=1024*17+2; set @@query_prealloc_size=1024*18; @@ -254,6 +336,13 @@ query_prealloc_size 18432 range_alloc_block_size 16384 transaction_alloc_block_size 19456 transaction_prealloc_size 20480 +select * from information_schema.session_variables where variable_name like '%alloc%'; +VARIABLE_NAME VARIABLE_VALUE +QUERY_ALLOC_BLOCK_SIZE 17408 +QUERY_PREALLOC_SIZE 18432 +RANGE_ALLOC_BLOCK_SIZE 16384 +TRANSACTION_ALLOC_BLOCK_SIZE 19456 +TRANSACTION_PREALLOC_SIZE 20480 set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; @@ -264,6 +353,13 @@ query_prealloc_size 8192 range_alloc_block_size 2048 transaction_alloc_block_size 8192 transaction_prealloc_size 4096 +select * from information_schema.session_variables where variable_name like '%alloc%'; +VARIABLE_NAME VARIABLE_VALUE +QUERY_ALLOC_BLOCK_SIZE 8192 +QUERY_PREALLOC_SIZE 8192 +RANGE_ALLOC_BLOCK_SIZE 2048 +TRANSACTION_ALLOC_BLOCK_SIZE 8192 +TRANSACTION_PREALLOC_SIZE 4096 SELECT @@version LIKE 'non-existent'; @@version LIKE 'non-existent' 0 @@ -485,6 +581,9 @@ set global myisam_max_sort_file_size=4294967296; show global variables like 'myisam_max_sort_file_size'; Variable_name Value myisam_max_sort_file_size MAX_FILE_SIZE +select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; +VARIABLE_NAME VARIABLE_VALUE +MYISAM_MAX_SORT_FILE_SIZE MAX_FILE_SIZE set global myisam_max_sort_file_size=default; select @@global.max_user_connections,@@local.max_join_size; @@global.max_user_connections @@local.max_join_size @@ -524,18 +623,30 @@ set @tstlw = @@log_warnings; show global variables like 'log_warnings'; Variable_name Value log_warnings 1 +select * from information_schema.global_variables where variable_name like 'log_warnings'; +VARIABLE_NAME VARIABLE_VALUE +LOG_WARNINGS 1 set global log_warnings = 0; show global variables like 'log_warnings'; Variable_name Value log_warnings 0 +select * from information_schema.global_variables where variable_name like 'log_warnings'; +VARIABLE_NAME VARIABLE_VALUE +LOG_WARNINGS 0 set global log_warnings = 42; show global variables like 'log_warnings'; Variable_name Value log_warnings 42 +select * from information_schema.global_variables where variable_name like 'log_warnings'; +VARIABLE_NAME VARIABLE_VALUE +LOG_WARNINGS 42 set global log_warnings = @tstlw; show global variables like 'log_warnings'; Variable_name Value log_warnings 1 +select * from information_schema.global_variables where variable_name like 'log_warnings'; +VARIABLE_NAME VARIABLE_VALUE +LOG_WARNINGS 1 create table t1 ( c1 tinyint, c2 smallint, @@ -567,10 +678,16 @@ SET GLOBAL MYISAM_DATA_POINTER_SIZE= 7; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; Variable_name Value myisam_data_pointer_size 7 +SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'MYISAM_DATA_POINTER_SIZE'; +VARIABLE_NAME VARIABLE_VALUE +MYISAM_DATA_POINTER_SIZE 7 SET GLOBAL table_open_cache=-1; SHOW VARIABLES LIKE 'table_open_cache'; Variable_name Value table_open_cache 1 +SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'table_open_cache'; +VARIABLE_NAME VARIABLE_VALUE +TABLE_OPEN_CACHE 1 SET GLOBAL table_open_cache=DEFAULT; set character_set_results=NULL; select ifnull(@@character_set_results,"really null"); @@ -639,21 +756,36 @@ set @@sql_big_selects = 1; show variables like 'sql_big_selects'; Variable_name Value sql_big_selects ON +select * from information_schema.session_variables where variable_name like 'sql_big_selects'; +VARIABLE_NAME VARIABLE_VALUE +SQL_BIG_SELECTS ON set @@sql_big_selects = @old_sql_big_selects; set @@sql_notes = 0, @@sql_warnings = 0; show variables like 'sql_notes'; Variable_name Value sql_notes OFF +select * from information_schema.session_variables where variable_name like 'sql_notes'; +VARIABLE_NAME VARIABLE_VALUE +SQL_NOTES OFF show variables like 'sql_warnings'; Variable_name Value sql_warnings OFF +select * from information_schema.session_variables where variable_name like 'sql_warnings'; +VARIABLE_NAME VARIABLE_VALUE +SQL_WARNINGS OFF set @@sql_notes = 1, @@sql_warnings = 1; show variables like 'sql_notes'; Variable_name Value sql_notes ON +select * from information_schema.session_variables where variable_name like 'sql_notes'; +VARIABLE_NAME VARIABLE_VALUE +SQL_NOTES ON show variables like 'sql_warnings'; Variable_name Value sql_warnings ON +select * from information_schema.session_variables where variable_name like 'sql_warnings'; +VARIABLE_NAME VARIABLE_VALUE +SQL_WARNINGS ON select @@system_time_zone; @@system_time_zone # @@ -667,12 +799,21 @@ select @@basedir, @@datadir, @@tmpdir; show variables like 'basedir'; Variable_name Value basedir # +select * from information_schema.session_variables where variable_name like 'basedir'; +VARIABLE_NAME VARIABLE_VALUE +BASEDIR # show variables like 'datadir'; Variable_name Value datadir # +select * from information_schema.session_variables where variable_name like 'datadir'; +VARIABLE_NAME VARIABLE_VALUE +DATADIR # show variables like 'tmpdir'; Variable_name Value tmpdir # +select * from information_schema.session_variables where variable_name like 'tmpdir'; +VARIABLE_NAME VARIABLE_VALUE +TMPDIR # select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; @@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key # # # # # @@ -683,12 +824,22 @@ ssl_capath # ssl_cert # ssl_cipher # ssl_key # +select * from information_schema.session_variables where variable_name like 'ssl%'; +VARIABLE_NAME VARIABLE_VALUE +SSL_CA # +SSL_CAPATH # +SSL_CERT # +SSL_CIPHER # +SSL_KEY # select @@log_queries_not_using_indexes; @@log_queries_not_using_indexes 0 show variables like 'log_queries_not_using_indexes'; Variable_name Value log_queries_not_using_indexes OFF +select * from information_schema.session_variables where variable_name like 'log_queries_not_using_indexes'; +VARIABLE_NAME VARIABLE_VALUE +LOG_QUERIES_NOT_USING_INDEXES OFF End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test index 55f9d95adc5..2afcd49962c 100644 --- a/mysql-test/t/status.test +++ b/mysql-test/t/status.test @@ -13,6 +13,7 @@ connect (con2,localhost,root,,); flush status; show status like 'Table_lock%'; +select * from information_schema.session_status where variable_name like 'Table_lock%'; connection con1; SET SQL_LOG_BIN=0; --disable_warnings @@ -34,6 +35,7 @@ unlock tables; connection con1; reap; show status like 'Table_lock%'; +select * from information_schema.session_status where variable_name like 'Table_lock%'; drop table t1; disconnect con2; @@ -102,6 +104,7 @@ while ($wait_more) # Prerequisite. SHOW STATUS LIKE 'max_used_connections'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; # Save original setting. SET @save_thread_cache_size=@@thread_cache_size; @@ -115,6 +118,7 @@ disconnect con2; # Check that max_used_connections still reflects maximum value. SHOW STATUS LIKE 'max_used_connections'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; # Check that after flush max_used_connections equals to current number # of connections. First wait for previous disconnect to finish. @@ -138,15 +142,18 @@ while ($wait_more) --enable_result_log # Check that we don't count disconnected thread any longer. SHOW STATUS LIKE 'max_used_connections'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; # Check that max_used_connections is updated when cached thread is # reused... connect (con2,localhost,root,,); SHOW STATUS LIKE 'max_used_connections'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; # ...and when new thread is created. connect (con3,localhost,root,,); SHOW STATUS LIKE 'max_used_connections'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME LIKE 'max_used_connections'; # Restore original setting. connection default; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 771a4ad3ed3..a33f1f72b8a 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -83,16 +83,24 @@ drop table t1; set GLOBAL max_join_size=10; set max_join_size=100; show variables like 'max_join_size'; +select * from information_schema.session_variables where variable_name like 'max_join_size'; --replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show global variables like 'max_join_size'; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR +select * from information_schema.global_variables where variable_name like 'max_join_size'; set GLOBAL max_join_size=2000; show global variables like 'max_join_size'; +select * from information_schema.global_variables where variable_name like 'max_join_size'; set max_join_size=DEFAULT; --replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show variables like 'max_join_size'; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR +select * from information_schema.session_variables where variable_name like 'max_join_size'; set GLOBAL max_join_size=DEFAULT; --replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR show global variables like 'max_join_size'; +--replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR +select * from information_schema.global_variables where variable_name like 'max_join_size'; set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; select @@identity, length(@@version)>0; @@ -106,50 +114,68 @@ set big_tables=OFF, big_tables=ON, big_tables=0, big_tables=1, big_tables="OFF", set global concurrent_insert=2; show variables like 'concurrent_insert'; +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; set global concurrent_insert=1; show variables like 'concurrent_insert'; +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; set global concurrent_insert=0; show variables like 'concurrent_insert'; +select * from information_schema.session_variables where variable_name like 'concurrent_insert'; set global concurrent_insert=DEFAULT; select @@concurrent_insert; set global timed_mutexes=ON; show variables like 'timed_mutexes'; +select * from information_schema.session_variables where variable_name like 'timed_mutexes'; set global timed_mutexes=0; show variables like 'timed_mutexes'; +select * from information_schema.session_variables where variable_name like 'timed_mutexes'; set storage_engine=MYISAM, storage_engine="HEAP", global storage_engine="MERGE"; show local variables like 'storage_engine'; +select * from information_schema.session_variables where variable_name like 'storage_engine'; show global variables like 'storage_engine'; +select * from information_schema.global_variables where variable_name like 'storage_engine'; set GLOBAL query_cache_size=100000; set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; +select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set GLOBAL myisam_max_sort_file_size=default; --replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE show variables like 'myisam_max_sort_file_size'; +--replace_result 2147483647 FILE_SIZE 9223372036854775807 FILE_SIZE +select * from information_schema.session_variables where variable_name like 'myisam_max_sort_file_size'; set global net_retry_count=10, session net_retry_count=10; set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300; set session net_buffer_length=2048, net_write_timeout=500, net_read_timeout=600; show global variables like 'net_%'; +select * from information_schema.global_variables where variable_name like 'net_%'; show session variables like 'net_%'; +select * from information_schema.session_variables where variable_name like 'net_%'; set session net_buffer_length=8000, global net_read_timeout=900, net_write_timeout=1000; show global variables like 'net_%'; +select * from information_schema.global_variables where variable_name like 'net_%'; show session variables like 'net_%'; +select * from information_schema.session_variables where variable_name like 'net_%'; set net_buffer_length=1; show variables like 'net_buffer_length'; +select * from information_schema.session_variables where variable_name like 'net_buffer_length'; set net_buffer_length=2000000000; show variables like 'net_buffer_length'; +select * from information_schema.session_variables where variable_name like 'net_buffer_length'; set character set cp1251_koi8; show variables like "character_set_client"; +select * from information_schema.session_variables where variable_name like 'character_set_client'; select @@timestamp>0; set @@rand_seed1=10000000,@@rand_seed2=1000000; select ROUND(RAND(),5); show variables like '%alloc%'; +select * from information_schema.session_variables where variable_name like '%alloc%'; set @@range_alloc_block_size=1024*16; set @@query_alloc_block_size=1024*17+2; set @@query_prealloc_size=1024*18; @@ -157,10 +183,12 @@ set @@transaction_alloc_block_size=1024*20-1; set @@transaction_prealloc_size=1024*21-1; select @@query_alloc_block_size; show variables like '%alloc%'; +select * from information_schema.session_variables where variable_name like '%alloc%'; set @@range_alloc_block_size=default; set @@query_alloc_block_size=default, @@query_prealloc_size=default; set transaction_alloc_block_size=default, @@transaction_prealloc_size=default; show variables like '%alloc%'; +select * from information_schema.session_variables where variable_name like '%alloc%'; # # Bug #10904 Illegal mix of collations between @@ -363,6 +391,8 @@ set global ft_boolean_syntax = @@init_connect; set global myisam_max_sort_file_size=4294967296; --replace_result 4294967296 MAX_FILE_SIZE 2146435072 MAX_FILE_SIZE show global variables like 'myisam_max_sort_file_size'; +--replace_result 4294967296 MAX_FILE_SIZE 2146435072 MAX_FILE_SIZE +select * from information_schema.global_variables where variable_name like 'myisam_max_sort_file_size'; set global myisam_max_sort_file_size=default; # @@ -398,12 +428,16 @@ SELECT @@global.local.key_buffer_size; # BUG#5135: cannot turn on log_warnings with SET in 4.1 (and 4.0) set @tstlw = @@log_warnings; show global variables like 'log_warnings'; +select * from information_schema.global_variables where variable_name like 'log_warnings'; set global log_warnings = 0; show global variables like 'log_warnings'; +select * from information_schema.global_variables where variable_name like 'log_warnings'; set global log_warnings = 42; show global variables like 'log_warnings'; +select * from information_schema.global_variables where variable_name like 'log_warnings'; set global log_warnings = @tstlw; show global variables like 'log_warnings'; +select * from information_schema.global_variables where variable_name like 'log_warnings'; # # BUG#4788 show create table provides incorrect statement @@ -435,6 +469,7 @@ drop table t1; SET GLOBAL MYISAM_DATA_POINTER_SIZE= 7; SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'MYISAM_DATA_POINTER_SIZE'; # # Bug #6958: negative arguments to integer options wrap around @@ -442,6 +477,7 @@ SHOW VARIABLES LIKE 'MYISAM_DATA_POINTER_SIZE'; SET GLOBAL table_open_cache=-1; SHOW VARIABLES LIKE 'table_open_cache'; +SELECT * FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME LIKE 'table_open_cache'; SET GLOBAL table_open_cache=DEFAULT; # @@ -527,6 +563,7 @@ select @@global.character_set_filesystem; set @old_sql_big_selects = @@sql_big_selects; set @@sql_big_selects = 1; show variables like 'sql_big_selects'; +select * from information_schema.session_variables where variable_name like 'sql_big_selects'; set @@sql_big_selects = @old_sql_big_selects; # @@ -535,10 +572,14 @@ set @@sql_big_selects = @old_sql_big_selects; # set @@sql_notes = 0, @@sql_warnings = 0; show variables like 'sql_notes'; +select * from information_schema.session_variables where variable_name like 'sql_notes'; show variables like 'sql_warnings'; +select * from information_schema.session_variables where variable_name like 'sql_warnings'; set @@sql_notes = 1, @@sql_warnings = 1; show variables like 'sql_notes'; +select * from information_schema.session_variables where variable_name like 'sql_notes'; show variables like 'sql_warnings'; +select * from information_schema.session_variables where variable_name like 'sql_warnings'; # # Bug #12792: @@system_time_zone is not SELECTable. @@ -565,9 +606,15 @@ select @@basedir, @@datadir, @@tmpdir; --replace_column 2 # show variables like 'basedir'; --replace_column 2 # +select * from information_schema.session_variables where variable_name like 'basedir'; +--replace_column 2 # show variables like 'datadir'; --replace_column 2 # +select * from information_schema.session_variables where variable_name like 'datadir'; +--replace_column 2 # show variables like 'tmpdir'; +--replace_column 2 # +select * from information_schema.session_variables where variable_name like 'tmpdir'; # # Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables @@ -577,6 +624,8 @@ show variables like 'tmpdir'; select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key; --replace_column 2 # show variables like 'ssl%'; +--replace_column 2 # +select * from information_schema.session_variables where variable_name like 'ssl%'; # # Bug #19616: make log_queries_not_using_indexes available in SHOW VARIABLES @@ -584,6 +633,7 @@ show variables like 'ssl%'; # select @@log_queries_not_using_indexes; show variables like 'log_queries_not_using_indexes'; +select * from information_schema.session_variables where variable_name like 'log_queries_not_using_indexes'; --echo End of 5.0 tests diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3acc025b84f..14ca547a527 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1994,15 +1994,22 @@ void remove_status_vars(SHOW_VAR *list) } } +inline void make_upper(char *buf) +{ + for (; *buf; buf++) + *buf= my_toupper(system_charset_info, *buf); +} + static bool show_status_array(THD *thd, const char *wild, SHOW_VAR *variables, enum enum_var_type value_type, struct system_status_var *status_var, - const char *prefix, TABLE *table) + const char *prefix, TABLE *table, + bool ucase_names) { char buff[SHOW_VAR_FUNC_BUFF_SIZE], *prefix_end; - /* the variable name should not be longer then 80 characters */ - char name_buffer[80]; + /* the variable name should not be longer than 64 characters */ + char name_buffer[64]; int len; LEX_STRING null_lex_str; SHOW_VAR tmp, *var; @@ -2020,6 +2027,8 @@ static bool show_status_array(THD *thd, const char *wild, { strnmov(prefix_end, variables->name, len); name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ + if (ucase_names) + make_upper(name_buffer); /* if var->type is SHOW_FUNC, call the function. @@ -2031,8 +2040,8 @@ static bool show_status_array(THD *thd, const char *wild, SHOW_TYPE show_type=var->type; if (show_type == SHOW_ARRAY) { - show_status_array(thd, wild, (SHOW_VAR *) var->value, - value_type, status_var, name_buffer, table); + show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type, + status_var, name_buffer, table, ucase_names); } else { @@ -2041,7 +2050,7 @@ static bool show_status_array(THD *thd, const char *wild, { char *value=var->value; const char *pos, *end; // We assign a lot of const's - long nr; + if (show_type == SHOW_SYS) { show_type= ((sys_var*) value)->type(); @@ -2123,6 +2132,7 @@ static bool show_status_array(THD *thd, const char *wild, table->field[0]->store(name_buffer, strlen(name_buffer), system_charset_info); table->field[1]->store(pos, (uint32) (end - pos), system_charset_info); + table->field[1]->set_notnull(); if (schema_table_store_record(thd, table)) DBUG_RETURN(TRUE); } @@ -4563,7 +4573,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond) const char *wild= lex->wild ? lex->wild->ptr() : NullS; pthread_mutex_lock(&LOCK_global_system_variables); res= show_status_array(thd, wild, init_vars, - lex->option_type, 0, "", tables->table); + lex->option_type, 0, "", tables->table, 0); pthread_mutex_unlock(&LOCK_global_system_variables); DBUG_RETURN(res); } @@ -4583,7 +4593,8 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) (SHOW_VAR *)all_status_vars.buffer, OPT_GLOBAL, (lex->option_type == OPT_GLOBAL ? - &tmp: thd->initial_status_var), "",tables->table); + &tmp: thd->initial_status_var), + "", tables->table, 0); pthread_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } @@ -4732,6 +4743,21 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(0); } break; + case MYSQL_TYPE_DECIMAL: + if (!(item= new Item_decimal((longlong) fields_info->value, false))) + { + DBUG_RETURN(0); + } + item->unsigned_flag= (fields_info->field_length/10000)%10; + item->decimals= fields_info->field_length%10; + item->max_length= (fields_info->field_length/100)%100; + if (item->unsigned_flag == 0) + item->max_length+= 1; + if (item->decimals > 0) + item->max_length+= 1; + item->set_name(fields_info->field_name, + strlen(fields_info->field_name), cs); + break; default: /* this should be changed when Item_empty_string is fixed(in 4.1) */ if (!(item= new Item_empty_string("", 0, cs))) @@ -5171,6 +5197,173 @@ int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond) DBUG_RETURN(0); } +int fill_schema_status(THD *thd, SHOW_VAR *variables, + struct system_status_var *status_var, + const char *prefix, TABLE *table) +{ + SHOW_VAR tmp, *var; + SHOW_TYPE show_type; + LEX_STRING null_lex_str; + char buff[SHOW_VAR_FUNC_BUFF_SIZE]; + char name_buf[64], *name_pos; + int name_len; + DBUG_ENTER("fill_schema_status"); + + null_lex_str.str= 0; + null_lex_str.length= 0; + + name_pos= strnmov(name_buf, prefix, sizeof(name_buf) - 1); + if (*prefix) + *name_pos++= '_'; + name_len= name_buf + sizeof(name_buf) - name_pos; + + for (; variables->name; variables++) + { + strnmov(name_pos, variables->name, name_len); + name_buf[sizeof(name_buf) - 1]= 0; + make_upper(name_buf); + + for (var= variables; var->type == SHOW_FUNC; var= &tmp) + ((mysql_show_var_func)(var->value))(thd, &tmp, buff); + + show_type= var->type; + + if (show_type == SHOW_ARRAY) + { + fill_schema_status(thd, (SHOW_VAR*) var->value, + status_var, name_buf, table); + } + else + { + char *value= var->value; + + restore_record(table, s->default_values); + table->field[0]->store(name_buf, strlen(name_buf), system_charset_info); + + if (show_type == SHOW_SYS) + { + show_type= ((sys_var*) value)->type(); + value= (char*) ((sys_var*) value)->value_ptr(thd, OPT_GLOBAL, + &null_lex_str); + } + + switch (show_type) + { + case SHOW_DOUBLE_STATUS: + value= (char*) status_var + (ulong) value; + table->field[1]->store(*(double*) value); + break; + case SHOW_LONG_STATUS: + value= (char*) status_var + (ulong) value; + /* fall through */ + case SHOW_LONG: + case SHOW_LONG_NOFLUSH: /* the difference lies in refresh_status() */ + table->field[1]->store((longlong) *(long*) value, false); + break; + case SHOW_LONGLONG: + table->field[1]->store(*(longlong*) value, false); + break; + case SHOW_HA_ROWS: + table->field[1]->store((longlong) *(ha_rows*) value, false); + break; + case SHOW_BOOL: + table->field[1]->store((longlong) *(bool*) value, false); + break; + case SHOW_MY_BOOL: + table->field[1]->store((longlong) *(my_bool*) value, false); + break; + case SHOW_INT: + table->field[1]->store((longlong) *(uint32*) value, false); + break; + case SHOW_HAVE: /* always displayed as 0 */ + table->field[1]->store((longlong) 0, false); + break; + case SHOW_CHAR_PTR: + value= *(char**) value; + /* fall through */ + case SHOW_CHAR: /* always displayed as 0 */ + table->field[1]->store((longlong) 0, false); + break; + case SHOW_KEY_CACHE_LONG: + value= (char*) dflt_key_cache + (ulong) value; + table->field[1]->store((longlong) *(long*) value, false); + break; + case SHOW_KEY_CACHE_LONGLONG: + value= (char*) dflt_key_cache + (ulong) value; + table->field[1]->store(*(longlong*) value, false); + break; + case SHOW_UNDEF: /* always displayed as 0 */ + table->field[1]->store((longlong) 0, false); + break; + case SHOW_SYS: /* cannot happen */ + default: + DBUG_ASSERT(0); + break; + } + + table->field[1]->set_notnull(); + if (schema_table_store_record(thd, table)) + DBUG_RETURN(1); + } + } + + DBUG_RETURN(0); +} + +int fill_schema_global_status(THD *thd, TABLE_LIST *tables, COND *cond) +{ + STATUS_VAR tmp; + int res= 0; + DBUG_ENTER("fill_schema_global_status"); + + pthread_mutex_lock(&LOCK_status); + calc_sum_of_all_status(&tmp); + res= fill_schema_status(thd, (SHOW_VAR*) all_status_vars.buffer, + &tmp, "", tables->table); + pthread_mutex_unlock(&LOCK_status); + + DBUG_RETURN(res); +} + +int fill_schema_session_status(THD *thd, TABLE_LIST *tables, COND *cond) +{ + int res= 0; + DBUG_ENTER("fill_schema_session_status"); + + pthread_mutex_lock(&LOCK_status); + res= fill_schema_status(thd, (SHOW_VAR*) all_status_vars.buffer, + &thd->status_var, "", tables->table); + pthread_mutex_unlock(&LOCK_status); + + DBUG_RETURN(res); +} + +int fill_schema_global_variables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + int res= 0; + DBUG_ENTER("fill_schema_global_variables"); + + pthread_mutex_lock(&LOCK_global_system_variables); + res= show_status_array(thd, "", init_vars, OPT_GLOBAL, + NULL, "", tables->table, 1); + pthread_mutex_unlock(&LOCK_global_system_variables); + + DBUG_RETURN(res); +} + +int fill_schema_session_variables(THD *thd, TABLE_LIST *tables, COND *cond) +{ + int res= 0; + DBUG_ENTER("fill_schema_session_variables"); + + pthread_mutex_lock(&LOCK_global_system_variables); + res= show_status_array(thd, "", init_vars, OPT_SESSION, + NULL, "", tables->table, 1); + pthread_mutex_unlock(&LOCK_global_system_variables); + + DBUG_RETURN(res); +} + ST_FIELD_INFO schema_fields_info[]= { {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0}, @@ -5523,6 +5716,22 @@ ST_FIELD_INFO variables_fields_info[]= }; +ST_FIELD_INFO status_fields_info[]= +{ + {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"}, + {"VARIABLE_VALUE", 2207, MYSQL_TYPE_DECIMAL, 0, 0, "Value"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + + +ST_FIELD_INFO system_variables_fields_info[]= +{ + {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name"}, + {"VARIABLE_VALUE", 65535, MYSQL_TYPE_STRING, 0, 1, "Value"}, + {0, 0, MYSQL_TYPE_STRING, 0, 0, 0} +}; + + ST_FIELD_INFO processlist_fields_info[]= { {"ID", 4, MYSQL_TYPE_LONG, 0, 0, "Id"}, @@ -5635,6 +5844,10 @@ ST_SCHEMA_TABLE schema_tables[]= fill_schema_events, make_old_format, 0, -1, -1, 0}, {"FILES", files_fields_info, create_schema_table, fill_schema_files, 0, 0, -1, -1, 0}, + {"GLOBAL_STATUS", status_fields_info, create_schema_table, + fill_schema_global_status, make_old_format, 0, -1, -1, 0}, + {"GLOBAL_VARIABLES", system_variables_fields_info, create_schema_table, + fill_schema_global_variables, make_old_format, 0, -1, -1, 0}, {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table, get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0}, {"OPEN_TABLES", open_tables_fields_info, create_schema_table, @@ -5654,6 +5867,10 @@ ST_SCHEMA_TABLE schema_tables[]= fill_schema_shemata, make_schemata_old_format, 0, 1, -1, 0}, {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table, fill_schema_schema_privileges, 0, 0, -1, -1, 0}, + {"SESSION_STATUS", status_fields_info, create_schema_table, + fill_schema_session_status, make_old_format, 0, -1, -1, 0}, + {"SESSION_VARIABLES", system_variables_fields_info, create_schema_table, + fill_schema_session_variables, make_old_format, 0, -1, -1, 0}, {"STATISTICS", stat_fields_info, create_schema_table, get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0}, {"STATUS", variables_fields_info, create_schema_table, fill_status, diff --git a/sql/table.h b/sql/table.h index 3fb7222cb0d..c490c283b72 100644 --- a/sql/table.h +++ b/sql/table.h @@ -474,6 +474,8 @@ enum enum_schema_tables SCH_ENGINES, SCH_EVENTS, SCH_FILES, + SCH_GLOBAL_STATUS, + SCH_GLOBAL_VARIABLES, SCH_KEY_COLUMN_USAGE, SCH_OPEN_TABLES, SCH_PARTITIONS, @@ -483,6 +485,8 @@ enum enum_schema_tables SCH_PROCEDURES, SCH_SCHEMATA, SCH_SCHEMA_PRIVILEGES, + SCH_SESSION_STATUS, + SCH_SESSION_VARIABLES, SCH_STATISTICS, SCH_STATUS, SCH_TABLES, From 336bbb52b1de43fa1ea34d6727e7a0ac2fc9fe73 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 01:37:41 +0200 Subject: [PATCH 27/37] fixes for the my_atomic-t unit test: - compiler warning - detection of pthread_create failure (you will see this message only if you run with "make test-verbose" in unittest; otherwise unit.pl masks all messages from the test but "ok" ones. - the test fails randomly on some machines (I filed it as BUG#22320), on one host it looks like a crash at exit() which a sleep(2) makes disappear. So I add the sleep(2), which can be removed when BUG#22320 is fixed. unittest/mysys/my_atomic-t.c: - fix for compiler warning on 64-bit "cast from pointer to integer of different size". Casting to long and then to int. We'll use intptr instead later. - detect if pthread_create fails. - sleep(2) until BUG#22320 is fixed --- unittest/mysys/my_atomic-t.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index 4e2e496c3b1..fe93b0942ce 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -32,7 +32,7 @@ pthread_handler_t test_atomic_add_handler(void *arg) { int m=*(int *)arg; int32 x; - for (x=((int)(&m)); m ; m--) + for (x=((int)((long)(&m))); m ; m--) { x=x*m+0x87654321; my_atomic_rwlock_wrlock(&rwl); @@ -104,7 +104,7 @@ pthread_handler_t test_atomic_cas_handler(void *arg) { int m=*(int *)arg, ok; int32 x,y; - for (x=((int)(&m)); m ; m--) + for (x=((int)((long)(&m))); m ; m--) { my_atomic_rwlock_wrlock(&rwl); y=my_atomic_load32(&a32); @@ -140,13 +140,21 @@ void test_atomic(const char *test, pthread_handler handler, int n, int m) diag("Testing %s with %d threads, %d iterations... ", test, n, m); for (N=n ; n ; n--) - pthread_create(&t, &thr_attr, handler, &m); + { + if (pthread_create(&t, &thr_attr, handler, &m) != 0) + { + diag("Could not create thread"); + a32= 1; + goto err; + } + } pthread_mutex_lock(&mutex); while (N) pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); now=my_getsystime()-now; +err: ok(a32 == 0, "tested %s in %g secs", test, ((double)now)/1e7); } @@ -170,6 +178,12 @@ int main() test_atomic("my_atomic_swap32", test_atomic_swap_handler, 100,10000); test_atomic("my_atomic_cas32", test_atomic_cas_handler, 100,10000); + /* + workaround until we know why it crashes randomly on some machine + (BUG#22320). + */ + sleep(2); + pthread_mutex_destroy(&mutex); pthread_cond_destroy(&cond); pthread_attr_destroy(&thr_attr); From 5db3eedc5935f263a4d3e89b58ad989b87cc84dd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 05:35:50 +0400 Subject: [PATCH 28/37] WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. mysql-test/r/mysqlshow.result: WL#3247,#3248: Adding [GLOBAL|SESSION]_STATUS and [GLOBAL|SESSION]_VARIABLES tables to INFORMATION_SCHEMA. Fixed test cases result (changes are due to addition of new tables). --- mysql-test/r/mysqlshow.result | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index 60ad5998465..14d8e4f464b 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -87,6 +87,8 @@ Database: information_schema | ENGINES | | EVENTS | | FILES | +| GLOBAL_STATUS | +| GLOBAL_VARIABLES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -95,6 +97,8 @@ Database: information_schema | ROUTINES | | SCHEMATA | | SCHEMA_PRIVILEGES | +| SESSION_STATUS | +| SESSION_VARIABLES | | STATISTICS | | TABLES | | TABLE_CONSTRAINTS | @@ -115,6 +119,8 @@ Database: INFORMATION_SCHEMA | ENGINES | | EVENTS | | FILES | +| GLOBAL_STATUS | +| GLOBAL_VARIABLES | | KEY_COLUMN_USAGE | | PARTITIONS | | PLUGINS | @@ -123,6 +129,8 @@ Database: INFORMATION_SCHEMA | ROUTINES | | SCHEMATA | | SCHEMA_PRIVILEGES | +| SESSION_STATUS | +| SESSION_VARIABLES | | STATISTICS | | TABLES | | TABLE_CONSTRAINTS | From 370f8ec15f738e50c3d1419cc945af2c1a9f6fe5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 03:02:01 +0200 Subject: [PATCH 29/37] Merge fixes, added printout to result file --- mysql-test/r/mysqldump.result | 224 ++++++++++++++++------ mysql-test/t/mysqldump.test | 346 +++++++++++++++++----------------- 2 files changed, 341 insertions(+), 229 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 1f2ea5b0057..207e1529b77 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -22,6 +22,9 @@ INSERT INTO t1 VALUES (1), (2); DROP TABLE t1; +# +# Bug #2005 +# CREATE TABLE t1 (a decimal(64, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), ("0987654321098765432109876543210987654321"); @@ -30,6 +33,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO `t1` VALUES ('1234567890123456789012345678901234567890.00000000000000000000'),('987654321098765432109876543210987654321.00000000000000000000'); DROP TABLE t1; +# +# Bug #2055 +# CREATE TABLE t1 (a double); INSERT INTO t1 VALUES ('-9e999999'); Warnings: @@ -39,6 +45,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO `t1` VALUES (RES); DROP TABLE t1; +# +# Bug #3361 mysqldump quotes DECIMAL values inconsistently +# CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); INSERT INTO t1 VALUES (1.2345, 2.3456); INSERT INTO t1 VALUES ('1.2345', 2.3456); @@ -136,6 +145,9 @@ INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); DROP TABLE t1; +# +# Bug #1707 +# CREATE TABLE t1 (`a"b"` char(2)); INSERT INTO t1 VALUES ("1\""), ("\"2"); @@ -155,6 +167,10 @@ INSERT INTO t1 VALUES ("1\""), ("\"2"); DROP TABLE t1; +# +# Bug #1994 +# Bug #4261 +# CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); @@ -190,6 +206,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #2634 +# CREATE TABLE t1 (a int) ENGINE=MYISAM; INSERT INTO t1 VALUES (1), (2); /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; @@ -239,11 +258,17 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #2592 'mysqldump doesn't quote "tricky" names correctly' +# create table ```a` (i int); CREATE TABLE ```a` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; drop table ```a`; +# +# Bug #2591 "mysqldump quotes names inconsistently" +# create table t1(a int); /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -352,6 +377,9 @@ UNLOCK TABLES; set global sql_mode=''; drop table t1; +# +# Bug #2705 'mysqldump --tab extra output' +# create table t1(a int); insert into t1 values (1),(2),(3); @@ -380,6 +408,9 @@ CREATE TABLE `t1` ( 2 3 drop table t1; +# +# Bug #6101: create database problem +# /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; @@ -432,6 +463,12 @@ USE `mysqldump_test_db`; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop database mysqldump_test_db; +# +# Bug #7020 +# Check that we don't dump in UTF8 in compatible mode by default, +# but use the default compiled values, or the values given in +# --default-character-set=xxx. However, we should dump in UTF8 +# if it is explicitely set. CREATE TABLE t1 (a CHAR(10)); INSERT INTO t1 VALUES (_latin1 'ÄÖÜß'); @@ -465,6 +502,13 @@ UNLOCK TABLES; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; +# +# Bug #8063: make test mysqldump [ fail ] +# We cannot tes this command because its output depends +# on --default-character-set incompiled into "mysqldump" program. +# If the future we can move this command into a separate test with +# checking that "mysqldump" is compiled with "latin1" +# /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; @@ -535,6 +579,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# WL#2319: Exclude Tables from dump +# CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); INSERT INTO t1 VALUES (1),(2),(3); @@ -572,6 +619,9 @@ UNLOCK TABLES; DROP TABLE t1; DROP TABLE t2; +# +# Bug #8830 +# CREATE TABLE t1 (`b` blob); INSERT INTO `t1` VALUES (0x602010000280100005E71A); @@ -606,6 +656,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Test for --insert-ignore +# CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); INSERT INTO t1 VALUES (4),(5),(6); @@ -670,6 +723,10 @@ INSERT DELAYED IGNORE INTO `t1` VALUES (1),(2),(3),(4),(5),(6); /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #10286: mysqldump -c crashes on table that has many fields with +# long names +# create table t1 ( F_c4ca4238a0b923820dcc509a6f75849b int, F_c81e728d9d4c2f636f067f89cc14862c int, @@ -1363,6 +1420,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop table t1; +# +# Test for --add-drop-database +# CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); @@ -1403,6 +1463,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# create database db1; use db1; CREATE TABLE t2 ( @@ -1461,6 +1524,9 @@ DROP TABLE IF EXISTS `v2`; drop table t2; drop view v2; drop database db1; +# +# Bug #10713 mysqldump includes database in create view and referenced tables +# create database db2; use db2; create table t1 (a int); @@ -1488,7 +1554,13 @@ a b 12 meg drop table t1, t2; drop database db1; +# +# Bug #15328 Segmentation fault occured if my.cnf is invalid for escape sequence +# --fields-optionally-enclosed-by=" +# +# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data +# CREATE DATABASE mysqldump_test_db; USE mysqldump_test_db; CREATE TABLE t1 ( a INT ); @@ -1577,6 +1649,11 @@ CREATE TABLE `t2` ( DROP TABLE t1, t2; DROP DATABASE mysqldump_test_db; +# +# Testing with tables and databases that don't exists +# or contains illegal characters +# (Bug #9358 mysqldump crashes if tablename starts with \) +# create database mysqldump_test_db; use mysqldump_test_db; create table t1(a varchar(30) primary key, b int not null); @@ -1615,6 +1692,9 @@ mysqldump: Got error: 1102: Incorrect database name 'mysqld\ump_test_db' when se drop table t1, t2, t3; drop database mysqldump_test_db; use test; +# +# Bug #9657 mysqldump xml ( -x ) does not format NULL fields correctly +# create table t1 (a int(10)); create table t2 (pk int primary key auto_increment, a int(10), b varchar(30), c datetime, d blob, e text); @@ -1671,6 +1751,9 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir drop table t1, t2; +# +# Bug #12123 +# create table t1 (a text character set utf8, b text character set latin1); insert t1 values (0x4F736E616272C3BC636B, 0x4BF66C6E); select * from t1; @@ -1681,6 +1764,9 @@ select * from t1; a b Osnabrück Köln drop table t1; +# +# Bug #19025 mysqldump doesn't correctly dump "auto_increment = [int]" +# create table `t1` ( t1_name varchar(255) default null, t1_id int(10) unsigned not null auto_increment, @@ -1718,7 +1804,12 @@ t1 CREATE TABLE `t1` ( KEY `t1_name` (`t1_name`) ) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 drop table `t1`; -End of 4.1 tests +# +# End of 4.1 tests +# +# +# Dump of view +# create table t1(a int); create view v1 as select * from t1; @@ -1763,6 +1854,9 @@ DROP TABLE IF EXISTS `v1`; drop view v1; drop table t1; +# +# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# create database mysqldump_test_db; use mysqldump_test_db; CREATE TABLE t2 ( @@ -1822,6 +1916,9 @@ drop table t2; drop view v2; drop database mysqldump_test_db; use test; +# +# Bug #9756 +# CREATE TABLE t1 (a char(10)); INSERT INTO t1 VALUES ('\''); @@ -1856,6 +1953,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #10927 mysqldump: Can't reload dump with view that consist of other view +# create table t1(a int, b int, c varchar(30)); insert into t1 values(1, 2, "one"), (2, 4, "two"), (3, 6, "three"); create view v3 as @@ -1933,6 +2033,9 @@ DROP TABLE IF EXISTS `v3`; drop view v1, v2, v3; drop table t1; +# +# Test for dumping triggers +# CREATE TABLE t1 (a int, b bigint default NULL); CREATE TABLE t2 (a int); create trigger trg1 before insert on t1 for each row @@ -2131,8 +2234,14 @@ set @fired:= "No"; end if; end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER root@localhost DROP TABLE t1, t2; +# +# Bugs #9136, #12917: problems with --defaults-extra-file option +# --port=1234 --port=1234 +# +# Bug #12597 +# DROP TABLE IF EXISTS `test1`; Warnings: Note 1051 Unknown table 'test1' @@ -2164,6 +2273,9 @@ a2 DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; +# +# Bug #9056 - mysqldump does not dump routines +# DROP TABLE IF EXISTS t1; DROP FUNCTION IF EXISTS bug9056_func1; DROP FUNCTION IF EXISTS bug9056_func2; @@ -2260,6 +2372,9 @@ DROP PROCEDURE bug9056_proc1; DROP PROCEDURE bug9056_proc2; DROP PROCEDURE `a'b`; drop table t1; +# +# Bug #13052 - mysqldump timestamp reloads broken +# drop table if exists t1; create table t1 (`d` timestamp, unique (`d`)); set time_zone='+00:00'; @@ -2346,6 +2461,9 @@ UNLOCK TABLES; drop table t1; set global time_zone=default; set time_zone=default; +# +# Bug #13146 - ansi quotes break loading of triggers +# DROP TABLE IF EXISTS `t1 test`; DROP TABLE IF EXISTS `t2 test`; CREATE TABLE `t1 test` ( @@ -2409,6 +2527,9 @@ UNLOCK TABLES; DROP TRIGGER `test trig`; DROP TABLE `t1 test`; DROP TABLE `t2 test`; +# +# Bug #12838 mysqldump -x with views exits with error +# drop table if exists t1; create table t1 (a int, b varchar(32), c varchar(32)); insert into t1 values (1, 'first value', 'xxxx'); @@ -2501,6 +2622,10 @@ drop view v2; drop view v0; drop view v1; drop table t1; +# +# Bug #14554 - mysqldump does not separate words "ROW" and "BEGIN" +# for tables with trigger created in the IGNORE_SPACE sql mode. +# SET @old_sql_mode = @@SQL_MODE; SET SQL_MODE = IGNORE_SPACE; CREATE TABLE t1 (a INT); @@ -2556,6 +2681,9 @@ DELIMITER ; DROP TRIGGER tr1; DROP TABLE t1; +# +# Bug #13318: Bad result with empty field and --hex-blob +# create table t1 (a binary(1), b blob); insert into t1 values ('',''); @@ -2623,6 +2751,9 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop table t1; +# +# Bug #18536: wrong table order +# create table t1(a int); create table t2(a int); create table t3(a int); @@ -2661,6 +2792,9 @@ CREATE TABLE `t2` ( drop table t1, t2, t3; End of 4.1 tests +# +# Bug #14871 Invalid view dump output +# create table t1 (a int); insert into t1 values (289), (298), (234), (456), (789); create definer = CURRENT_USER view v1 as select * from t1; @@ -2687,6 +2821,9 @@ a 789 drop table t1; drop view v1, v2, v3, v4, v5; +# +# Bug #16878 dump of trigger +# create table t1 (a int, created datetime); create table t2 (b int, created datetime); create trigger tr1 before insert on t1 for each row set @@ -2709,6 +2846,9 @@ end AFTER # root@localhost drop trigger tr1; drop trigger tr2; drop table t1, t2; +# +# Bug #18462 mysqldump does not dump view structures correctly +# create table t (qty int, price int); insert into t values(3, 50); insert into t values(5, 51); @@ -2728,6 +2868,10 @@ mysqldump { drop view v1; drop view v2; drop table t; +# +# Bug #14857 Reading dump files with single statement stored routines fails. +# fixed by patch for Bug #16878 +# /*!50003 CREATE FUNCTION `f`() RETURNS bigint(20) return 42 */| /*!50003 CREATE PROCEDURE `p`() @@ -2742,6 +2886,9 @@ p CREATE DEFINER=`root`@`localhost` PROCEDURE `p`() select 42 drop function f; drop procedure p; +# +# Bug #17371 Unable to dump a schema with invalid views +# create table t1 ( id serial ); create view v1 as select * from t1; drop table t1; @@ -2751,6 +2898,11 @@ mysqldump { } mysqldump drop view v1; +# +# Bug #17201 Spurious 'DROP DATABASE' in output, +# also confusion between tables and views. +# Example code from Markus Popp +# create database mysqldump_test_db; use mysqldump_test_db; create table t1 (id int); @@ -2811,6 +2963,9 @@ USE `mysqldump_test_db`; drop view v1; drop table t1; drop database mysqldump_test_db; +# +# Bug21014 Segmentation fault of mysqldump on view +# create database mysqldump_tables; use mysqldump_tables; create table basetable ( id serial, tag varchar(64) ); @@ -2844,6 +2999,9 @@ drop view nasishnasifu; drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; +# +# Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps +# create database mysqldump_dba; use mysqldump_dba; create table t1 (f1 int, f2 int); @@ -2875,6 +3033,9 @@ use mysqldump_dbb; drop view v1; drop table t1; drop database mysqldump_dbb; +# +# Bug #21215 mysqldump creating incomplete backups without warning +# use test; create user mysqltest_1@localhost; create table t1(a int, b varchar(34)); @@ -2892,60 +3053,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1; drop table t1; drop user mysqltest_1@localhost; -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_tables` /*!40100 DEFAULT CHARACTER SET latin1 */; - -USE `mysqldump_tables`; -DROP TABLE IF EXISTS `basetable`; -CREATE TABLE `basetable` ( - `id` bigint(20) unsigned NOT NULL auto_increment, - `tag` varchar(64) default NULL, - UNIQUE KEY `id` (`id`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -LOCK TABLES `basetable` WRITE; -/*!40000 ALTER TABLE `basetable` DISABLE KEYS */; -/*!40000 ALTER TABLE `basetable` ENABLE KEYS */; -UNLOCK TABLES; - -CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHARACTER SET latin1 */; - -USE `mysqldump_views`; -DROP TABLE IF EXISTS `nasishnasifu`; -/*!50001 DROP VIEW IF EXISTS `nasishnasifu`*/; -/*!50001 CREATE TABLE `nasishnasifu` ( - `id` bigint(20) unsigned -) */; -/*!50001 DROP TABLE IF EXISTS `nasishnasifu`*/; -/*!50001 DROP VIEW IF EXISTS `nasishnasifu`*/; -/*!50001 CREATE ALGORITHM=UNDEFINED */ -/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */ -/*!50001 VIEW `mysqldump_views`.`nasishnasifu` AS select `mysqldump_tables`.`basetable`.`id` AS `id` from `mysqldump_tables`.`basetable` */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -drop view nasishnasifu; -drop database mysqldump_views; -drop table mysqldump_tables.basetable; -drop database mysqldump_tables; -USE test; +# +# Bug #13926: --order-by-primary fails if PKEY contains quote character +# DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( `a b` INT, @@ -3015,4 +3125,6 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE `t1`; -End of 5.0 tests +# +# End of 5.0 tests +# diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 7d9f0529ab2..735a3d4c789 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -16,9 +16,9 @@ INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --skip-create --skip-comments -X test t1 DROP TABLE t1; -# -# Bug #2005 -# +--echo # +--echo # Bug #2005 +--echo # CREATE TABLE t1 (a decimal(64, 20)); INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), @@ -26,9 +26,9 @@ INSERT INTO t1 VALUES ("1234567890123456789012345678901234567890"), --exec $MYSQL_DUMP --compact test t1 DROP TABLE t1; -# -# Bug #2055 -# +--echo # +--echo # Bug #2055 +--echo # CREATE TABLE t1 (a double); INSERT INTO t1 VALUES ('-9e999999'); @@ -38,9 +38,9 @@ INSERT INTO t1 VALUES ('-9e999999'); --exec $MYSQL_DUMP --compact test t1 DROP TABLE t1; -# -# Bug #3361 mysqldump quotes DECIMAL values inconsistently -# +--echo # +--echo # Bug #3361 mysqldump quotes DECIMAL values inconsistently +--echo # CREATE TABLE t1 (a DECIMAL(10,5), b FLOAT); @@ -69,28 +69,28 @@ INSERT INTO t1 VALUES (1, "test", "tes"), (2, "TEST", "TES"); --exec $MYSQL_DUMP --skip-create --compact -X test t1 DROP TABLE t1; -# -# Bug #1707 -# +--echo # +--echo # Bug #1707 +--echo # CREATE TABLE t1 (`a"b"` char(2)); INSERT INTO t1 VALUES ("1\""), ("\"2"); --exec $MYSQL_DUMP --compact --skip-create -X test t1 DROP TABLE t1; -# -# Bug #1994 -# Bug #4261 -# +--echo # +--echo # Bug #1994 +--echo # Bug #4261 +--echo # CREATE TABLE t1 (a VARCHAR(255)) DEFAULT CHARSET koi8r; INSERT INTO t1 VALUES (_koi8r x'C1C2C3C4C5'), (NULL); --exec $MYSQL_DUMP --skip-comments --skip-extended-insert test t1 DROP TABLE t1; -# -# Bug #2634 -# +--echo # +--echo # Bug #2634 +--echo # CREATE TABLE t1 (a int) ENGINE=MYISAM; INSERT INTO t1 VALUES (1), (2); @@ -98,17 +98,17 @@ INSERT INTO t1 VALUES (1), (2); --exec $MYSQL_DUMP --skip-comments --compatible=mysql323 test t1 DROP TABLE t1; -# -# Bug #2592 'mysqldump doesn't quote "tricky" names correctly' -# +--echo # +--echo # Bug #2592 'mysqldump doesn't quote "tricky" names correctly' +--echo # create table ```a` (i int); --exec $MYSQL_DUMP --compact test drop table ```a`; -# -# Bug #2591 "mysqldump quotes names inconsistently" -# +--echo # +--echo # Bug #2591 "mysqldump quotes names inconsistently" +--echo # create table t1(a int); --exec $MYSQL_DUMP --comments=0 test @@ -119,9 +119,9 @@ set global sql_mode='ANSI_QUOTES'; set global sql_mode=''; drop table t1; -# -# Bug #2705 'mysqldump --tab extra output' -# +--echo # +--echo # Bug #2705 'mysqldump --tab extra output' +--echo # create table t1(a int); insert into t1 values (1),(2),(3); @@ -135,9 +135,9 @@ insert into t1 values (1),(2),(3); --exec rm $MYSQLTEST_VARDIR/tmp/t1.txt drop table t1; -# -# Bug #6101: create database problem -# +--echo # +--echo # Bug #6101: create database problem +--echo # --exec $MYSQL_DUMP --skip-comments --databases test @@ -145,32 +145,33 @@ create database mysqldump_test_db character set latin2 collate latin2_bin; --exec $MYSQL_DUMP --skip-comments --databases mysqldump_test_db drop database mysqldump_test_db; -# -# Bug #7020 -# Check that we don't dump in UTF8 in compatible mode by default, -# but use the default compiled values, or the values given in -# --default-character-set=xxx. However, we should dump in UTF8 -# if it is explicitely set. +--echo # +--echo # Bug #7020 +--echo # Check that we don't dump in UTF8 in compatible mode by default, +--echo # but use the default compiled values, or the values given in +--echo # --default-character-set=xxx. However, we should dump in UTF8 +--echo # if it is explicitely set. CREATE TABLE t1 (a CHAR(10)); INSERT INTO t1 VALUES (_latin1 'ÄÖÜß'); --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments test t1 -# -# Bug#8063: make test mysqldump [ fail ] -# We cannot tes this command because its output depends -# on --default-character-set incompiled into "mysqldump" program. -# If the future we can move this command into a separate test with -# checking that "mysqldump" is compiled with "latin1" -# + +--echo # +--echo # Bug #8063: make test mysqldump [ fail ] +--echo # We cannot tes this command because its output depends +--echo # on --default-character-set incompiled into "mysqldump" program. +--echo # If the future we can move this command into a separate test with +--echo # checking that "mysqldump" is compiled with "latin1" +--echo # #--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --compatible=mysql323 --default-character-set=cp850 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=cp850 --compatible=mysql323 test t1 --exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --skip-comments --default-character-set=utf8 --compatible=mysql323 test t1 DROP TABLE t1; -# -# WL #2319: Exclude Tables from dump -# +--echo # +--echo # WL#2319: Exclude Tables from dump +--echo # CREATE TABLE t1 (a int); CREATE TABLE t2 (a int); @@ -180,18 +181,18 @@ INSERT INTO t2 VALUES (4),(5),(6); DROP TABLE t1; DROP TABLE t2; -# -# Bug #8830 -# +--echo # +--echo # Bug #8830 +--echo # CREATE TABLE t1 (`b` blob); INSERT INTO `t1` VALUES (0x602010000280100005E71A); --exec $MYSQL_DUMP --skip-extended-insert --hex-blob test --skip-comments t1 DROP TABLE t1; -# -# Test for --insert-ignore -# +--echo # +--echo # Test for --insert-ignore +--echo # CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); @@ -200,10 +201,10 @@ INSERT INTO t1 VALUES (4),(5),(6); --exec $MYSQL_DUMP --skip-comments --insert-ignore --delayed-insert test t1 DROP TABLE t1; -# -# Bug #10286: mysqldump -c crashes on table that has many fields with long -# names -# +--echo # +--echo # Bug #10286: mysqldump -c crashes on table that has many fields with +--echo # long names +--echo # create table t1 ( F_c4ca4238a0b923820dcc509a6f75849b int, F_c81e728d9d4c2f636f067f89cc14862c int, @@ -539,19 +540,18 @@ insert into t1 (F_8d3bba7425e7c98c50f52ca1b52d3735) values (1); --exec $MYSQL_DUMP --skip-comments -c test drop table t1; -# -# Test for --add-drop-database -# +--echo # +--echo # Test for --add-drop-database +--echo # CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); --exec $MYSQL_DUMP --add-drop-database --skip-comments --databases test DROP TABLE t1; - -# -# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) -# +--echo # +--echo # Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +--echo # create database db1; use db1; @@ -572,9 +572,9 @@ drop table t2; drop view v2; drop database db1; -# -# Bug 10713 mysqldump includes database in create view and referenced tables -# +--echo # +--echo # Bug #10713 mysqldump includes database in create view and referenced tables +--echo # # create table and views in db2 create database db2; @@ -606,16 +606,15 @@ select * from t2 order by a; drop table t1, t2; drop database db1; -# -# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence -# +--echo # +--echo # Bug #15328 Segmentation fault occured if my.cnf is invalid for escape sequence +--echo # --exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump - -# -# Bug #9558 mysqldump --no-data db t1 t2 format still dumps data -# +--echo # +--echo # Bug #9558 mysqldump --no-data db t1 t2 format still dumps data +--echo # CREATE DATABASE mysqldump_test_db; USE mysqldump_test_db; @@ -630,11 +629,11 @@ INSERT INTO t2 VALUES (1), (2); DROP TABLE t1, t2; DROP DATABASE mysqldump_test_db; -# -# Testing with tables and databases that don't exists -# or contains illegal characters -# (Bug #9358 mysqldump crashes if tablename starts with \) -# +--echo # +--echo # Testing with tables and databases that don't exists +--echo # or contains illegal characters +--echo # (Bug #9358 mysqldump crashes if tablename starts with \) +--echo # create database mysqldump_test_db; use mysqldump_test_db; create table t1(a varchar(30) primary key, b int not null); @@ -694,9 +693,9 @@ drop database mysqldump_test_db; use test; -# -# Bug #9657 mysqldump xml ( -x ) does not format NULL fields correctly -# +--echo # +--echo # Bug #9657 mysqldump xml ( -x ) does not format NULL fields correctly +--echo # create table t1 (a int(10)); create table t2 (pk int primary key auto_increment, @@ -706,9 +705,9 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir --exec $MYSQL_DUMP --skip-comments --xml --no-create-info test drop table t1, t2; -# -# BUG #12123 -# +--echo # +--echo # Bug #12123 +--echo # create table t1 (a text character set utf8, b text character set latin1); insert t1 values (0x4F736E616272C3BC636B, 0x4BF66C6E); select * from t1; @@ -719,9 +718,9 @@ select * from t1; drop table t1; -# -# BUG #19025 mysqldump doesn't correctly dump "auto_increment = [int]" -# +--echo # +--echo # Bug #19025 mysqldump doesn't correctly dump "auto_increment = [int]" +--echo # create table `t1` ( t1_name varchar(255) default null, t1_id int(10) unsigned not null auto_increment, @@ -748,20 +747,23 @@ show create table `t1`; drop table `t1`; ---echo End of 4.1 tests +--echo # +--echo # End of 4.1 tests +--echo # + +--echo # +--echo # Dump of view +--echo # -# -# dump of view -# create table t1(a int); create view v1 as select * from t1; --exec $MYSQL_DUMP --skip-comments test drop view v1; drop table t1; -# -# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) -# +--echo # +--echo # Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +--echo # create database mysqldump_test_db; use mysqldump_test_db; @@ -783,18 +785,18 @@ drop view v2; drop database mysqldump_test_db; use test; -# -# Bug #9756 -# +--echo # +--echo # Bug #9756 +--echo # CREATE TABLE t1 (a char(10)); INSERT INTO t1 VALUES ('\''); --exec $MYSQL_DUMP --skip-comments test t1 DROP TABLE t1; -# -# Bug #10927 mysqldump: Can't reload dump with view that consist of other view -# +--echo # +--echo # Bug #10927 mysqldump: Can't reload dump with view that consist of other view +--echo # create table t1(a int, b int, c varchar(30)); @@ -813,9 +815,10 @@ select v3.a from v3, v1 where v1.a=v3.a and v3.b=3 limit 1; drop view v1, v2, v3; drop table t1; -# -# Test for dumping triggers -# + +--echo # +--echo # Test for dumping triggers +--echo # CREATE TABLE t1 (a int, b bigint default NULL); CREATE TABLE t2 (a int); @@ -863,9 +866,9 @@ show tables; show triggers; DROP TABLE t1, t2; -# -# Bugs #9136, #12917: problems with --defaults-extra-file option -# +--echo # +--echo # Bugs #9136, #12917: problems with --defaults-extra-file option +--echo # --system echo '[mysqltest1]' > $MYSQLTEST_VARDIR/tmp/tmp.cnf --system echo 'port=1234' >> $MYSQLTEST_VARDIR/tmp/tmp.cnf @@ -873,9 +876,9 @@ DROP TABLE t1, t2; --exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQLTEST_VARDIR/tmp/tmp.cnf mysqltest1 mysqltest1 --system rm $MYSQLTEST_VARDIR/tmp/tmp.cnf -# -# Test of fix to BUG 12597 -# +--echo # +--echo # Bug #12597 +--echo # DROP TABLE IF EXISTS `test1`; CREATE TABLE `test1` ( @@ -911,9 +914,9 @@ DROP TRIGGER testref; DROP TABLE test1; DROP TABLE test2; -# -# BUG#9056 - mysqldump does not dump routines -# +--echo # +--echo # Bug #9056 - mysqldump does not dump routines +--echo # --disable_warnings DROP TABLE IF EXISTS t1; @@ -960,9 +963,9 @@ DROP PROCEDURE bug9056_proc2; DROP PROCEDURE `a'b`; drop table t1; -# -# BUG# 13052 - mysqldump timestamp reloads broken -# +--echo # +--echo # Bug #13052 - mysqldump timestamp reloads broken +--echo # --disable_warnings drop table if exists t1; --enable_warnings @@ -982,9 +985,9 @@ drop table t1; set global time_zone=default; set time_zone=default; -# -# Test of fix to BUG 13146 - ansi quotes break loading of triggers -# +--echo # +--echo # Bug #13146 - ansi quotes break loading of triggers +--echo # --disable_warnings DROP TABLE IF EXISTS `t1 test`; DROP TABLE IF EXISTS `t2 test`; @@ -1015,9 +1018,9 @@ DROP TRIGGER `test trig`; DROP TABLE `t1 test`; DROP TABLE `t2 test`; -# -# BUG# 12838 mysqldump -x with views exits with error -# +--echo # +--echo # Bug #12838 mysqldump -x with views exits with error +--echo # --disable_warnings drop table if exists t1; @@ -1039,10 +1042,10 @@ drop view v0; drop view v1; drop table t1; -# -# BUG#14554 - mysqldump does not separate words "ROW" and "BEGIN" -# for tables with trigger created in the IGNORE_SPACE sql mode. -# +--echo # +--echo # Bug #14554 - mysqldump does not separate words "ROW" and "BEGIN" +--echo # for tables with trigger created in the IGNORE_SPACE sql mode. +--echo # SET @old_sql_mode = @@SQL_MODE; SET SQL_MODE = IGNORE_SPACE; @@ -1063,18 +1066,18 @@ SET SQL_MODE = @old_sql_mode; DROP TRIGGER tr1; DROP TABLE t1; -# -# Bug #13318: Bad result with empty field and --hex-blob -# +--echo # +--echo # Bug #13318: Bad result with empty field and --hex-blob +--echo # create table t1 (a binary(1), b blob); insert into t1 values ('',''); --exec $MYSQL_DUMP --skip-comments --skip-extended-insert --hex-blob test t1 --exec $MYSQL_DUMP --skip-comments --hex-blob test t1 drop table t1; -# -# Bug #18536: wrong table order -# +--echo # +--echo # Bug #18536: wrong table order +--echo # create table t1(a int); create table t2(a int); @@ -1085,9 +1088,9 @@ drop table t1, t2, t3; --echo End of 4.1 tests -# -# Bug 14871 Invalid view dump output -# +--echo # +--echo # Bug #14871 Invalid view dump output +--echo # create table t1 (a int); insert into t1 values (289), (298), (234), (456), (789); @@ -1114,9 +1117,9 @@ select * from v3 order by a; drop table t1; drop view v1, v2, v3, v4, v5; -# -# Bug #16878 dump of trigger -# +--echo # +--echo # Bug #16878 dump of trigger +--echo # create table t1 (a int, created datetime); create table t2 (b int, created datetime); @@ -1145,10 +1148,9 @@ drop trigger tr2; drop table t1, t2; -# -# Bug#18462 mysqldump does not dump view structures correctly -# -# +--echo # +--echo # Bug #18462 mysqldump does not dump view structures correctly +--echo # create table t (qty int, price int); insert into t values(3, 50); insert into t values(5, 51); @@ -1165,11 +1167,10 @@ drop view v2; drop table t; -# -# Bug#14857 Reading dump files with single statement stored routines fails. -# fixed by patch for bug#16878 -# -# +--echo # +--echo # Bug #14857 Reading dump files with single statement stored routines fails. +--echo # fixed by patch for Bug #16878 +--echo # DELIMITER |; /*!50003 CREATE FUNCTION `f`() RETURNS bigint(20) return 42 */| @@ -1181,10 +1182,10 @@ show create procedure p; drop function f; drop procedure p; -# -# Bug #17371 Unable to dump a schema with invalid views -# -# +--echo # +--echo # Bug #17371 Unable to dump a schema with invalid views +--echo # + create table t1 ( id serial ); create view v1 as select * from t1; drop table t1; @@ -1195,10 +1196,11 @@ drop table t1; --echo } mysqldump drop view v1; -# BUG#17201 Spurious 'DROP DATABASE' in output, -# also confusion between tables and views. -# Example code from Markus Popp - +--echo # +--echo # Bug #17201 Spurious 'DROP DATABASE' in output, +--echo # also confusion between tables and views. +--echo # Example code from Markus Popp +--echo # create database mysqldump_test_db; use mysqldump_test_db; create table t1 (id int); @@ -1212,8 +1214,9 @@ drop view v1; drop table t1; drop database mysqldump_test_db; -# Bug21014 Segmentation fault of mysqldump on view - +--echo # +--echo # Bug21014 Segmentation fault of mysqldump on view +--echo # create database mysqldump_tables; use mysqldump_tables; create table basetable ( id serial, tag varchar(64) ); @@ -1229,8 +1232,9 @@ drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; -# Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps - +--echo # +--echo # Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps +--echo # create database mysqldump_dba; use mysqldump_dba; create table t1 (f1 int, f2 int); @@ -1267,9 +1271,9 @@ drop view v1; drop table t1; drop database mysqldump_dbb; -# -# Bug#21215 mysqldump creating incomplete backups without warning -# +--echo # +--echo # Bug #21215 mysqldump creating incomplete backups without warning +--echo # use test; # Create user without sufficient privs to perform the requested operation @@ -1310,17 +1314,10 @@ grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; drop table t1; drop user mysqltest_1@localhost; ---exec $MYSQL_DUMP --skip-comments --databases mysqldump_tables mysqldump_views; +--echo # +--echo # Bug #13926: --order-by-primary fails if PKEY contains quote character +--echo # -drop view nasishnasifu; -drop database mysqldump_views; -drop table mysqldump_tables.basetable; -drop database mysqldump_tables; -USE test; - -# -# BUG#13926: --order-by-primary fails if PKEY contains quote character -# --disable_warnings DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( @@ -1335,5 +1332,8 @@ insert into t1 values (0815, 4711, 2006); --exec $MYSQL_DUMP --skip-comments --order-by-primary test t1 DROP TABLE `t1`; --enable_warnings ---echo End of 5.0 tests + +--echo # +--echo # End of 5.0 tests +--echo # From 01bec9b52f7b1f42a68051985458fda22c44cd5e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 03:15:06 +0200 Subject: [PATCH 30/37] Merge main->rpl --- mysql-test/r/variables.result | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 5526ca8634f..f759e78adbf 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -840,6 +840,12 @@ log_queries_not_using_indexes OFF select * from information_schema.session_variables where variable_name like 'log_queries_not_using_indexes'; VARIABLE_NAME VARIABLE_VALUE LOG_QUERIES_NOT_USING_INDEXES OFF +select @@""; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '""' at line 1 +select @@&; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '&' at line 1 +select @@@; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@' at line 1 End of 5.0 tests set global binlog_cache_size =@my_binlog_cache_size; set global connect_timeout =@my_connect_timeout; From 6e10407c2b34aad5324a13d5f9243c944614d2a5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 15:15:24 +0200 Subject: [PATCH 31/37] WL#3504 "plugin actions for engines' and plugins' unit tests" for push in 5.1 (I will inform Trudy). Storage engines and plugins can now have unit tests to test their components; such test must be an executable C/C++ program which name ends with '-t' and which is obeys the mytap protocol, it must be stored in the storage engine's or plugin's source directory (storage/ or plugin/) or any subdirectories of this. The top-level Makefile target "test-unit" will run all unit tests: it will scan the engines' and plugins' directories, recursively, and execute all executable files which name ends with '-t'." Makefile.am: "unittest" directory must be built before "storage" and "plugin" because the unit tests in these directories may need libmytap.a which is in unittest/mytap. config/ac-macros/plugins.m4: When enabling engine "X", we add "../storage/X" to the unit tests directories which unittest/unit.pl should traverse looking for tests to execute. Same for plugins. unittest/Makefile.am: Those variables contain all enabled engines and plugins. --- Makefile.am | 4 ++-- config/ac-macros/plugins.m4 | 12 ++++++++++-- unittest/Makefile.am | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 771a9570950..a0d19e8271d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,11 +24,11 @@ EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \ SUBDIRS = . include @docs_dirs@ @zlib_dir@ \ @readline_topdir@ sql-common \ @thread_dirs@ pstack \ - @sql_union_dirs@ storage plugin \ + @sql_union_dirs@ unittest storage plugin \ @sql_server@ scripts @man_dirs@ tests \ netware @libmysqld_dirs@ \ mysql-test support-files @tools_dirs@ \ - unittest win + win DIST_SUBDIRS = $(SUBDIRS) BUILD diff --git a/config/ac-macros/plugins.m4 b/config/ac-macros/plugins.m4 index cfc5f8dbcbe..87f057e696a 100644 --- a/config/ac-macros/plugins.m4 +++ b/config/ac-macros/plugins.m4 @@ -280,6 +280,8 @@ AC_DEFUN([MYSQL_CONFIGURE_PLUGINS],[ _MYSQL_EMIT_PLUGIN_ACTIONS(m4_bpatsubst(__mysql_plugin_list__, :, [,])) AC_SUBST([mysql_se_dirs]) AC_SUBST([mysql_pg_dirs]) + AC_SUBST([mysql_se_unittest_dirs]) + AC_SUBST([mysql_pg_unittest_dirs]) ]) ]) ]) @@ -410,9 +412,15 @@ dnl Although this is "pretty", it breaks libmysqld build [AC_CONFIG_FILES($6/Makefile)] ) ifelse(m4_substr($6, 0, 8), [storage/], - [mysql_se_dirs="$mysql_se_dirs ]m4_substr($6, 8)", + [ + [mysql_se_dirs="$mysql_se_dirs ]m4_substr($6, 8)" + mysql_se_unittest_dirs="$mysql_se_unittest_dirs ../$6" + ], m4_substr($6, 0, 7), [plugin/], - [mysql_pg_dirs="$mysql_pg_dirs ]m4_substr($6, 7)", + [ + [mysql_pg_dirs="$mysql_pg_dirs ]m4_substr($6, 7)" + mysql_pg_unittest_dirs="$mysql_pg_unittest_dirs ../$6" + ], [AC_FATAL([don't know how to handle plugin dir ]$6)]) fi ]) diff --git a/unittest/Makefile.am b/unittest/Makefile.am index f2f7fc0bf7d..7f1dd525d3b 100644 --- a/unittest/Makefile.am +++ b/unittest/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS = mytap . mysys examples EXTRA_DIST = unit.pl CLEANFILES = unit -unittests = mytap mysys +unittests = mytap mysys @mysql_se_unittest_dirs@ @mysql_pg_unittest_dirs@ test: perl unit.pl run $(unittests) From 9c88f37bf5e246cdc3a2d32c0a42405cc219f2f3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 17:25:13 +0300 Subject: [PATCH 32/37] Bug#22067 rpl_rbr_to_sbr and some other fail if NDB is default storage A query SET @@GLOBAL.binlog_format = ... returns an error when NDB is the default storage. This fails some tests invoking the set binlog_format explicitly. because the var turns to be read-only. In the following are files and method to fix if needed. t/ ndb_binlog_basic2.test # here the failure is benign rpl_rbr_to_sbr.test # does not check any ndb features => . # => not_ndb_default is enough rpl_row_basic_8partition.test # set binlog_format can be replaced rpl_switch_stm_row_mixed.test # does not check any ndb features => . # => not_ndb_default is enough two more invoking invoke extra/rpl_truncate_helper.test rpl_truncate_2myisam # to be fixed with not_ndb_default rpl_truncate_3innodb # same as above . # because there is a dedicated to ndb . . # rpl_truncate_7ndb* suit. Adapting/testing a new implement --source include/safe_set_to_maybe_ro_var.inc to avoid abort due to the error using binlog_format as application. BitKeeper/etc/ignore: Added mysql-test/t/rpl_truncate_4ndb.test to the ignore list mysql-test/r/rpl_row_basic_8partition.result: new results mysql-test/t/rpl_rbr_to_sbr.test: # does not check any ndb features => not_ndb_default is enough mysql-test/t/rpl_row_basic_8partition.test: set binlog_format can be read-only because of e.g default storage ndb. adapting/testing a new implement --source include/safe_set_to_maybe_ro_var.inc to avoid abort due to the error. Note, that it this particular test we could simply remove SET binlog_format because there is have_binlog_format_row require, as the test is about RBR. Futhermore utilizing safe_set_to_maybe_ro_var is redundat as well as long as we keep non_ndb_default guard. The latter is introduced because of ndb partitioning per-key limitation #19259: rpl_ndb_dd_partitions fails on solaris. The page is updated to refer to this test's. mysql-test/t/rpl_switch_stm_row_mixed.test: excluding ndb option, no ndb features mysql-test/t/rpl_truncate_2myisam.test: ndb checks truncate separately mysql-test/t/rpl_truncate_3innodb.test: ndb checks truncate separately mysql-test/include/safe_set_to_maybe_ro_var.inc: pseudo-macro to make read-only global/session vars "settable" in sense that SET var= val won't produce any error nor aborts testing. --- .bzrignore | 1 + .../include/safe_set_to_maybe_ro_var.inc | 23 +++++++++++++++++++ mysql-test/r/rpl_row_basic_8partition.result | 5 +++- mysql-test/t/rpl_rbr_to_sbr.test | 1 + mysql-test/t/rpl_row_basic_8partition.test | 7 +++++- mysql-test/t/rpl_switch_stm_row_mixed.test | 1 + mysql-test/t/rpl_truncate_2myisam.test | 2 +- mysql-test/t/rpl_truncate_3innodb.test | 1 + 8 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 mysql-test/include/safe_set_to_maybe_ro_var.inc diff --git a/.bzrignore b/.bzrignore index 1cf0cf7b889..fcacbd7c726 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1791,3 +1791,4 @@ vio/viotest-sslconnect.cpp vio/viotest.cpp zlib/*.ds? zlib/*.vcproj +mysql-test/t/rpl_truncate_4ndb.test diff --git a/mysql-test/include/safe_set_to_maybe_ro_var.inc b/mysql-test/include/safe_set_to_maybe_ro_var.inc new file mode 100644 index 00000000000..add7f2091b3 --- /dev/null +++ b/mysql-test/include/safe_set_to_maybe_ro_var.inc @@ -0,0 +1,23 @@ +# to mask out the error - never abort neither log in result file - in setting +# to read-only variable. +# It is assumed that the new value is equal to one the var was set to. +# Such situation happens particularily with binlog_format that becomes read-only +# with ndb default storage. +# +# when generate results always watch the file to find what is expected, +# the SET query may fail + +# script accepts $maybe_ro_var the var name and $val4var the value + +### USAGE: +### let $maybe_ro_var= ... +### let $val4var= ... +### include/safe_set_to_maybe_ro_var.inc + +--disable_result_log +--disable_abort_on_error +eval SET $maybe_ro_var = $val4var; +--enable_abort_on_error +--enable_result_log + +eval SELECT $maybe_ro_var; diff --git a/mysql-test/r/rpl_row_basic_8partition.result b/mysql-test/r/rpl_row_basic_8partition.result index a6728303a4c..dedd5d044e0 100644 --- a/mysql-test/r/rpl_row_basic_8partition.result +++ b/mysql-test/r/rpl_row_basic_8partition.result @@ -5,7 +5,10 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; DROP TABLE IF EXISTS t1; -SET BINLOG_FORMAT=ROW; +SET @@BINLOG_FORMAT = ROW; +SELECT @@BINLOG_FORMAT; +@@BINLOG_FORMAT +ROW **** Partition RANGE testing **** CREATE TABLE t1 (id MEDIUMINT NOT NULL, b1 BIT(8), vc VARCHAR(255), bc CHAR(255), d DECIMAL(10,4) DEFAULT 0, diff --git a/mysql-test/t/rpl_rbr_to_sbr.test b/mysql-test/t/rpl_rbr_to_sbr.test index 83a9b08c344..0c5368197b3 100644 --- a/mysql-test/t/rpl_rbr_to_sbr.test +++ b/mysql-test/t/rpl_rbr_to_sbr.test @@ -1,5 +1,6 @@ -- source include/have_row_based.inc -- source include/have_binlog_format_mixed_or_statement.inc +-- source include/not_ndb_default.inc -- source include/master-slave.inc # Test that the slave temporarily switches to ROW when seeing binrow diff --git a/mysql-test/t/rpl_row_basic_8partition.test b/mysql-test/t/rpl_row_basic_8partition.test index 640a420c10e..f262ef05c58 100644 --- a/mysql-test/t/rpl_row_basic_8partition.test +++ b/mysql-test/t/rpl_row_basic_8partition.test @@ -8,12 +8,17 @@ ############################################################ --source include/have_row_based.inc +--source include/have_binlog_format_row.inc --source include/have_partition.inc +--source include/not_ndb_default.inc --source include/master-slave.inc connection master; --disable_warnings DROP TABLE IF EXISTS t1; -SET BINLOG_FORMAT=ROW; + +let $maybe_ro_var = @@BINLOG_FORMAT; +let $val4var = ROW; +--source include/safe_set_to_maybe_ro_var.inc --echo **** Partition RANGE testing **** diff --git a/mysql-test/t/rpl_switch_stm_row_mixed.test b/mysql-test/t/rpl_switch_stm_row_mixed.test index 4066794d519..d345b62b8eb 100644 --- a/mysql-test/t/rpl_switch_stm_row_mixed.test +++ b/mysql-test/t/rpl_switch_stm_row_mixed.test @@ -1,4 +1,5 @@ -- source include/have_row_based.inc +-- source include/not_ndb_default.inc -- source include/master-slave.inc connection master; diff --git a/mysql-test/t/rpl_truncate_2myisam.test b/mysql-test/t/rpl_truncate_2myisam.test index 1a2cb1d0fb3..a0f0ea04f44 100644 --- a/mysql-test/t/rpl_truncate_2myisam.test +++ b/mysql-test/t/rpl_truncate_2myisam.test @@ -1,4 +1,4 @@ - +--source include/not_ndb_default.inc let $engine=MyISAM; --source extra/rpl_tests/rpl_truncate.test diff --git a/mysql-test/t/rpl_truncate_3innodb.test b/mysql-test/t/rpl_truncate_3innodb.test index 7f3145feb1b..a31fd62a29a 100644 --- a/mysql-test/t/rpl_truncate_3innodb.test +++ b/mysql-test/t/rpl_truncate_3innodb.test @@ -1,5 +1,6 @@ --source include/have_innodb.inc +--source include/not_ndb_default.inc let $engine=InnoDB; --source extra/rpl_tests/rpl_truncate.test From 0d7fccab2130ce9b6089d8f6cc7ee7700d9fdd5a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 17:00:35 +0200 Subject: [PATCH 33/37] bug#19259 rpl_ndb_dd_partitions fails because of limitation re-activating the bug to fix related to the limitation tests. mysql-test/t/disabled.def: re-disabling --- mysql-test/t/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index e9f2a5d80ec..1602237343b 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -55,3 +55,4 @@ func_group : BUG#21924 2006-08-30 reggie func_in : BUG#21925 2006-08-30 reggie ndb_binlog_discover : bug#21806 2006-08-24 ndb_autodiscover3 : bug#21806 +rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails because of limitation From 0cdbe2c3d5cead38e342945579ee457d12492399 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 15 Sep 2006 18:24:12 +0200 Subject: [PATCH 34/37] modifying disabled file so it is a copy of main tree --- mysql-test/t/disabled.def | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 1602237343b..6d58f1a22f9 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -22,27 +22,17 @@ ndb_load : BUG#17233 2006-05-04 tomas failed load data from infi partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table ps : BUG#21524 2006-08-08 pgalbraith 'ps' test fails in --ps-protocol test AMD64 bit ps_7ndb : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open -rpl_deadlock_innodb : BUG#16920 2006-04-12 kent fails in show slave status (randomly) -rpl_ndb_2innodb : BUG#19004 2006-03-22 tomas ndb: partition by range and update hangs -rpl_ndb_2myisam : BUG#19004 2006-03-22 tomas ndb: partition by range and update hangs -rpl_ndb_auto_inc : BUG#17086 2006-02-16 jmiller CR: auto_increment_increment and auto_increment_offset produce duplicate key er -rpl_ndb_commit_afterflush : LOCK TABLES cases hang in ndb injector thread -rpl_ndb_ddl : result file needs update + test needs to checked -rpl_ndb_innodb2ndb : BUG#18094 2006-03-16 mats Slave caches invalid table definition after atlters causes select failure -rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ -rpl_ndb_myisam2ndb : BUG#18094 2006-03-16 mats Slave caches invalid table definition after atlters causes select failure -rpl_ndb_relay_space : BUG#16993 2006-02-16 jmiller RBR: ALTER TABLE ZEROFILL AUTO_INCREMENT is not replicated correctly -rpl_switch_stm_row_mixed : BUG#18590 2006-03-28 brian -rpl_row_basic_7ndb : BUG#17400 2006-04-09 brian Cluster Replication: delete & update of rows in table without pk fails on slave. +rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated +rpl_ndb_2myisam : BUG#19227 Seems to pass currently +#rpl_ndb_commit_afterflush : BUG#19328 2006-05-04 tomas Slave timeout with COM_REGISTER_SLAVE error causing stop +rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD +rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked +rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement +#rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ +rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly -#rpl_row_func003 : BUG#19074 2006-13-04 andrei test failed -#rpl_row_inexist_tbl : BUG#18948 2006-03-09 mats Disabled since patch makes this test wait forever rpl_sp : BUG#16456 2006-02-16 jmiller -rpl_sp_effects : BUG#19862 2006-08-22 mats Bug appear to be fixed -rpl_until : BUG#15886 2006-02-16 jmiller Unstable test case -sp-goto : BUG#18949 2006-02-16 jmiller GOTO is currently is disabled - will be fixed in the future -mysqldump : BUG#18078 2006-03-10 lars -udf : BUG#18564 2006-03-27 ian (Permission by Brian) +rpl_sp_effects : BUG#19862 2006-06-15 mkindahl # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events @@ -55,4 +45,3 @@ func_group : BUG#21924 2006-08-30 reggie func_in : BUG#21925 2006-08-30 reggie ndb_binlog_discover : bug#21806 2006-08-24 ndb_autodiscover3 : bug#21806 -rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails because of limitation From 7d557fbcdc534663b2df1cab45d86eaf16819e8b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 16 Sep 2006 13:20:06 +0200 Subject: [PATCH 35/37] Test case fixes mysql-test/r/rpl_row_tabledefs_2myisam.result: Change error code of new error mysql-test/r/rpl_switch_stm_row_mixed.result: Change of result file mysql-test/t/mysqldump.test: incorrect merge --- mysql-test/r/rpl_row_tabledefs_2myisam.result | 8 ++++---- mysql-test/r/rpl_switch_stm_row_mixed.result | 2 +- mysql-test/t/mysqldump.test | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/rpl_row_tabledefs_2myisam.result b/mysql-test/r/rpl_row_tabledefs_2myisam.result index 37559b0412a..1c602695649 100644 --- a/mysql-test/r/rpl_row_tabledefs_2myisam.result +++ b/mysql-test/r/rpl_row_tabledefs_2myisam.result @@ -151,7 +151,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Table width mismatch - received 2 columns, test.t2 has 1 columns Skip_Counter 0 Exec_Master_Log_Pos # @@ -189,7 +189,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 0 type mismatch - received type 3, test.t4 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -227,7 +227,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 1 type mismatch - received type 3, test.t5 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # @@ -265,7 +265,7 @@ Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table -Last_Errno 1514 +Last_Errno 1522 Last_Error Column 2 type mismatch - received type 3, test.t6 has type 4 Skip_Counter 0 Exec_Master_Log_Pos # diff --git a/mysql-test/r/rpl_switch_stm_row_mixed.result b/mysql-test/r/rpl_switch_stm_row_mixed.result index 72c142f2c2a..047bfe53704 100644 --- a/mysql-test/r/rpl_switch_stm_row_mixed.result +++ b/mysql-test/r/rpl_switch_stm_row_mixed.result @@ -750,7 +750,7 @@ master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t2` ( master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t2) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F master-bin.000001 # Query 1 # use `mysqltest1`; CREATE TABLE `t3` ( - `1` varbinary(108) NOT NULL DEFAULT '' + `1` varbinary(36) NOT NULL DEFAULT '' ) master-bin.000001 # Table_map 1 # table_id: # (mysqltest1.t3) master-bin.000001 # Write_rows 1 # table_id: # flags: STMT_END_F diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 8941a0f7e0c..25b11c1bed3 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -835,7 +835,6 @@ use test; --echo # Dump of view --echo # ->>>>>>> create table t1(a int); create view v1 as select * from t1; --exec $MYSQL_DUMP --skip-comments test From 2aca61db47dd032f70980ee8df9a8674ae8e12e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Sep 2006 10:08:10 +0200 Subject: [PATCH 36/37] Adding tests lost in the merge. --- mysql-test/t/mysqldump.test | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 25b11c1bed3..fff166800a3 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -718,6 +718,12 @@ select * from t1; drop table t1; +--echo # +--echo # BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence +--echo # + +--exec $MYSQL_MY_PRINT_DEFAULTS --config-file=$MYSQL_TEST_DIR/std_data/bug15328.cnf mysqldump + --echo # --echo # Bug #19025 mysqldump doesn't correctly dump "auto_increment = [int]" --echo # @@ -1540,6 +1546,25 @@ drop database third; set time_zone = 'SYSTEM'; use test; +##### +# +# BUG#17201 Spurious 'DROP DATABASE' in output, +# also confusion between tables and views. +# Example code from Markus Popp + +create database mysqldump_test_db; +use mysqldump_test_db; +create table t1 (id int); +create view v1 as select * from t1; +insert into t1 values (1232131); +insert into t1 values (4711); +insert into t1 values (3231); +insert into t1 values (0815); +--exec $MYSQL_DUMP --skip-comments --add-drop-database --databases mysqldump_test_db +drop view v1; +drop table t1; +drop database mysqldump_test_db; + --echo # --echo # End of 5.1 tests --echo # From c323a2cbe2cee7a43afcb5d2ea34c39eedaf7f08 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 18 Sep 2006 21:09:48 +0200 Subject: [PATCH 37/37] Fixing and checking result for mysqldump test. mysql-test/r/mysqldump.result: Result change --- mysql-test/r/mysqldump.result | 260 ++++++++++++++-------------------- 1 file changed, 107 insertions(+), 153 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 9edc087f78d..ec0840fbd57 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1492,7 +1492,7 @@ create view v2 as select * from t2 where a like 'a%' with check option; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t2`; CREATE TABLE `t2` ( - `a` varchar(30) default NULL, + `a` varchar(30) DEFAULT NULL, KEY `a` (`a`(5)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -1765,6 +1765,9 @@ select * from t1; a b Osnabrück Köln drop table t1; +# +# BUG#15328 Segmentation fault occured if my.cnf is invalid for escape sequence +# --fields-optionally-enclosed-by=" # # Bug #19025 mysqldump doesn't correctly dump "auto_increment = [int]" @@ -1806,6 +1809,9 @@ t1 CREATE TABLE `t1` ( KEY `t1_name` (`t1_name`) ) ENGINE=MyISAM AUTO_INCREMENT=1003 DEFAULT CHARSET=latin1 drop table `t1`; +# +# Bug #18536: wrong table order +# create table t1(a int); create table t2(a int); create table t3(a int); @@ -1843,6 +1849,9 @@ CREATE TABLE `t2` ( /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop table t1, t2, t3; +# +# Bug #21288: mysqldump segmentation fault when using --where +# create table t1 (a int); mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 when retrieving data from server @@ -1873,6 +1882,9 @@ CREATE TABLE `t1` ( /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; drop table t1; +# +# Bug #10213 mysqldump crashes when dumping VIEWs(on MacOS X) +# create database db1; use db1; CREATE TABLE t2 ( @@ -1932,6 +1944,9 @@ drop table t2; drop view v2; drop database db1; use test; +# +# Bug 10713 mysqldump includes database in create view and referenced tables +# create database db2; use db2; create table t1 (a int); @@ -2836,74 +2851,6 @@ DELIMITER ; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -DROP TRIGGER tr1; -DROP TABLE t1; -create table t1 (a binary(1), b blob); -insert into t1 values ('',''); - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( - `a` binary(1) DEFAULT NULL, - `b` blob -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -LOCK TABLES `t1` WRITE; -/*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT INTO `t1` VALUES (0x00,''); -/*!40000 ALTER TABLE `t1` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( - `a` binary(1) DEFAULT NULL, - `b` blob -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -LOCK TABLES `t1` WRITE; -/*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT INTO `t1` VALUES (0x00,''); -/*!40000 ALTER TABLE `t1` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - DROP TRIGGER tr1; DROP TABLE t1; # @@ -2924,7 +2871,7 @@ insert into t1 values ('',''); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( - `a` binary(1) default NULL, + `a` binary(1) DEFAULT NULL, `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -2956,7 +2903,7 @@ UNLOCK TABLES; /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( - `a` binary(1) default NULL, + `a` binary(1) DEFAULT NULL, `b` blob ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -2995,15 +2942,15 @@ create table t3(a int); /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; DROP TABLE IF EXISTS `t3`; CREATE TABLE `t3` ( - `a` int(11) default NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( - `a` int(11) default NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; DROP TABLE IF EXISTS `t2`; CREATE TABLE `t2` ( - `a` int(11) default NULL + `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; @@ -3155,7 +3102,7 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_test_db` /*!40100 DEFAULT CH USE `mysqldump_test_db`; DROP TABLE IF EXISTS `t1`; CREATE TABLE `t1` ( - `id` int(11) default NULL + `id` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; LOCK TABLES `t1` WRITE; @@ -3225,7 +3172,7 @@ drop database mysqldump_views; drop table mysqldump_tables.basetable; drop database mysqldump_tables; # -# Bug20221 Dumping of multiple databases containing view(s) yields maleformed dumps +# Bug #20221 Dumping of multiple databases containing view(s) yields maleformed dumps # create database mysqldump_dba; use mysqldump_dba; @@ -3271,85 +3218,12 @@ grant RELOAD on *.* to mysqltest_1@localhost; mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; -CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=537; -CREATE TABLE `t1` ( - `a` int(11) default NULL, - `b` varchar(34) default NULL -) ENGINE=MyISAM DEFAULT CHARSET=latin1; drop table t1; drop user mysqltest_1@localhost; # -# Bug #13926: --order-by-primary fails if PKEY contains quote character +# Bug #21527 mysqldump incorrectly tries to LOCK TABLES on the +# information_schema database. # -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( -`a b` INT, -`c"d` INT, -`e``f` INT, -PRIMARY KEY (`a b`, `c"d`, `e``f`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; -insert into t1 values (0815, 4711, 2006); -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS "t1"; -CREATE TABLE "t1" ( - "a b" int(11) NOT NULL default '0', - "c""d" int(11) NOT NULL default '0', - "e`f" int(11) NOT NULL default '0', - PRIMARY KEY ("a b","c""d","e`f") -); - -LOCK TABLES "t1" WRITE; -/*!40000 ALTER TABLE "t1" DISABLE KEYS */; -INSERT INTO "t1" VALUES (815,4711,2006); -/*!40000 ALTER TABLE "t1" ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( - `a b` int(11) NOT NULL default '0', - `c"d` int(11) NOT NULL default '0', - `e``f` int(11) NOT NULL default '0', - PRIMARY KEY (`a b`,`c"d`,`e``f`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1; - -LOCK TABLES `t1` WRITE; -/*!40000 ALTER TABLE `t1` DISABLE KEYS */; -INSERT INTO `t1` VALUES (815,4711,2006); -/*!40000 ALTER TABLE `t1` ENABLE KEYS */; -UNLOCK TABLES; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - -DROP TABLE `t1`; create database mysqldump_myDB; use mysqldump_myDB; create user myDB_User; @@ -3365,7 +3239,6 @@ revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; drop user myDB_User; drop database mysqldump_myDB; use test; -End of 5.0 tests drop table if exists t1; CREATE TABLE t1(a int, b int); INSERT INTO t1 VALUES (1,1); @@ -3404,6 +3277,84 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; +# +# Bug #13926: --order-by-primary fails if PKEY contains quote character +# +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( +`a b` INT, +`c"d` INT, +`e``f` INT, +PRIMARY KEY (`a b`, `c"d`, `e``f`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +insert into t1 values (0815, 4711, 2006); +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS "t1"; +CREATE TABLE "t1" ( + "a b" int(11) NOT NULL DEFAULT '0', + "c""d" int(11) NOT NULL DEFAULT '0', + "e`f" int(11) NOT NULL DEFAULT '0', + PRIMARY KEY ("a b","c""d","e`f") +); + +LOCK TABLES "t1" WRITE; +/*!40000 ALTER TABLE "t1" DISABLE KEYS */; +INSERT INTO "t1" VALUES (815,4711,2006); +/*!40000 ALTER TABLE "t1" ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a b` int(11) NOT NULL DEFAULT '0', + `c"d` int(11) NOT NULL DEFAULT '0', + `e``f` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`a b`,`c"d`,`e``f`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES (815,4711,2006); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +DROP TABLE `t1`; +# +# End of 5.0 tests +# +# +# Added for use-thread option +# create table t1 (a text , b text); create table t2 (a text , b text); insert t1 values ("Duck, Duck", "goose"); @@ -3579,6 +3530,9 @@ mysql-import: Error: 1146, Table 'test.words' doesn't exist, when using table: w drop table t1; drop table t2; drop table words2; +# +# Bug #16853: mysqldump doesn't show events +# create database first; use first; set time_zone = 'UTC'; @@ -3677,5 +3631,5 @@ drop view v1; drop table t1; drop database mysqldump_test_db; # -# End of 5.0 tests +# End of 5.1 tests #